From 6cdab759cf6924c873e378665860c29442cdb29c Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Fri, 17 Jan 2020 16:43:47 -0500 Subject: [PATCH 01/11] 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 eb2228595..1be513f82 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 9c9a4ab21..7d2839846 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 d4e45617e..bdb8473e9 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 02/11] 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 76a2215e9..88094b689 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 465433ec0..25c46221e 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 fb7e8cdb1..f5ce3d111 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 e07153566..4e5ba8174 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 854a05444..b5cb33e2b 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 d5e20164a..380d11b11 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 6833c94a2..c6fdbe249 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 03/11] 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 000000000..36e3b701a --- /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 04/11] 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 36e3b701a..c852368cc 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 05/11] 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 bdb8473e9..613890358 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 c852368cc..3ed0cad2e 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 06/11] 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 c1d0e8ee1..000000000 --- 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 07/11] 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 3ed0cad2e..a669a810e 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 08/11] 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 f7780d3e3..ad6e090d8 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 000000000..a9aa16fb3 --- /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 000000000..61c7b1688 --- /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 000000000..65afebada --- /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 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 Date: Thu, 30 Jan 2020 21:58:35 -0500 Subject: [PATCH 09/11] 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 fb7e8cdb1..6a600a804 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 a42239db5..53bb29875 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 c2eab2ccc..a8366f524 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 10/11] 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 a8366f524..08497875b 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 11/11] 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 08c995ed9..adbdce0ae 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 46070ba11..b8a32ae4b 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).