@aptos-labs/ts-sdk 3.1.0 → 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/chunk-6MMUUJHX.js.map +1 -1
- package/dist/common/cli/index.js.map +1 -1
- package/dist/common/index.js +13 -13
- package/dist/common/index.js.map +1 -1
- package/dist/esm/account/AbstractKeylessAccount.mjs +1 -1
- package/dist/esm/account/AbstractedAccount.mjs +1 -1
- package/dist/esm/account/Account.mjs +1 -1
- package/dist/esm/account/AccountUtils.mjs +1 -1
- package/dist/esm/account/DerivableAbstractedAccount.mjs +1 -1
- package/dist/esm/account/Ed25519Account.mjs +1 -1
- package/dist/esm/account/EphemeralKeyPair.mjs +1 -1
- package/dist/esm/account/FederatedKeylessAccount.mjs +1 -1
- package/dist/esm/account/KeylessAccount.mjs +1 -1
- package/dist/esm/account/MultiEd25519Account.mjs +1 -1
- package/dist/esm/account/MultiKeyAccount.mjs +1 -1
- package/dist/esm/account/SingleKeyAccount.mjs +1 -1
- package/dist/esm/account/index.mjs +1 -1
- package/dist/esm/account/utils.mjs +1 -1
- package/dist/esm/api/account/abstraction.mjs +1 -1
- package/dist/esm/api/account.mjs +1 -1
- package/dist/esm/api/ans.mjs +1 -1
- package/dist/esm/api/aptos.mjs +1 -1
- package/dist/esm/api/coin.mjs +1 -1
- package/dist/esm/api/digitalAsset.mjs +1 -1
- package/dist/esm/api/event.mjs +1 -1
- package/dist/esm/api/faucet.mjs +1 -1
- package/dist/esm/api/fungibleAsset.mjs +1 -1
- package/dist/esm/api/general.mjs +1 -1
- package/dist/esm/api/index.mjs +1 -1
- package/dist/esm/api/keyless.mjs +1 -1
- package/dist/esm/api/object.mjs +1 -1
- package/dist/esm/api/staking.mjs +1 -1
- package/dist/esm/api/table.mjs +1 -1
- package/dist/esm/api/transaction.mjs +1 -1
- package/dist/esm/api/transactionSubmission/build.mjs +1 -1
- package/dist/esm/api/transactionSubmission/helpers.d.mts +22 -9
- package/dist/esm/api/transactionSubmission/helpers.mjs +1 -1
- package/dist/esm/api/transactionSubmission/management.mjs +1 -1
- package/dist/esm/api/transactionSubmission/sign.mjs +1 -1
- package/dist/esm/api/transactionSubmission/simulate.mjs +1 -1
- package/dist/esm/api/transactionSubmission/submit.mjs +1 -1
- package/dist/esm/api/utils.mjs +1 -1
- package/dist/esm/bcs/deserializer.mjs +1 -1
- package/dist/esm/bcs/index.mjs +1 -1
- package/dist/esm/bcs/serializable/entryFunctionBytes.mjs +1 -1
- package/dist/esm/bcs/serializable/fixedBytes.mjs +1 -1
- package/dist/esm/bcs/serializable/movePrimitives.mjs +1 -1
- package/dist/esm/bcs/serializable/moveStructs.mjs +1 -1
- package/dist/esm/bcs/serializer.mjs +1 -1
- package/dist/esm/chunk-4R4AI5RT.mjs +2 -0
- package/dist/esm/{chunk-HUWKPKPQ.mjs.map → chunk-4R4AI5RT.mjs.map} +1 -1
- package/dist/esm/{chunk-2BOHKN33.mjs → chunk-6MWXV62C.mjs} +2 -2
- package/dist/esm/{chunk-FGFLPH5K.mjs → chunk-6PKBXYG3.mjs} +2 -2
- package/dist/esm/{chunk-6WDVDEQZ.mjs → chunk-6Y6ZO7TS.mjs} +2 -2
- package/dist/esm/{chunk-SLWIGOQL.mjs → chunk-AQQEQB35.mjs} +2 -2
- package/dist/esm/{chunk-HNBVYE3N.mjs → chunk-BUUV6B4P.mjs} +2 -2
- package/dist/esm/{chunk-WSR5EBJM.mjs → chunk-BYINW7I2.mjs} +2 -2
- package/dist/esm/{chunk-ORMOQWWH.mjs → chunk-C6JRJNK3.mjs} +2 -2
- package/dist/esm/{chunk-Z5URUE4U.mjs → chunk-DW6WLD2B.mjs} +2 -2
- package/dist/esm/{chunk-U3GMNXO4.mjs → chunk-E6IUB35J.mjs} +2 -2
- package/dist/esm/{chunk-CO67Y6YE.mjs → chunk-EPMBZCYJ.mjs} +2 -2
- package/dist/esm/{chunk-RQX6JOEN.mjs → chunk-FBCXUC7J.mjs} +2 -2
- package/dist/esm/{chunk-CFQFFP6N.mjs → chunk-FWGLACJS.mjs} +2 -2
- package/dist/esm/{chunk-TYYVB2A6.mjs → chunk-GRB6YSIT.mjs} +2 -2
- package/dist/esm/{chunk-RGKRCZ36.mjs → chunk-GYVSI3TS.mjs} +2 -2
- package/dist/esm/chunk-HPQMAP7O.mjs +2 -0
- package/dist/esm/{chunk-ACNHLCQQ.mjs → chunk-I4NMWLUZ.mjs} +5 -5
- package/dist/esm/chunk-I4NMWLUZ.mjs.map +1 -0
- package/dist/esm/{chunk-TOBQ5UE6.mjs → chunk-IXYGZ57N.mjs} +2 -2
- package/dist/esm/{chunk-MML57K5H.mjs → chunk-NII5Q32W.mjs} +2 -2
- package/dist/esm/{chunk-EBMEXURY.mjs → chunk-NJN3EAOM.mjs} +2 -2
- package/dist/esm/{chunk-XKUIMGKU.mjs → chunk-OYH2T6V5.mjs} +2 -2
- package/dist/esm/chunk-OYUW6ZN2.mjs +2 -0
- package/dist/esm/{chunk-5URUYE6H.mjs → chunk-PQS3II2E.mjs} +2 -2
- package/dist/esm/{chunk-N6YTF76Q.mjs → chunk-PRUQZNAP.mjs} +2 -2
- package/dist/esm/{chunk-UQWF24SS.mjs → chunk-QGFWOGAV.mjs} +2 -2
- package/dist/esm/{chunk-4COLMDT3.mjs → chunk-QQEK2GJC.mjs} +2 -2
- package/dist/esm/chunk-QREVMGQZ.mjs +2 -0
- package/dist/esm/chunk-QREVMGQZ.mjs.map +1 -0
- package/dist/esm/{chunk-MNDTFHDB.mjs → chunk-RFQFTIOA.mjs} +2 -2
- package/dist/esm/{chunk-XZ75T7Q7.mjs → chunk-THUSLDD6.mjs} +2 -2
- package/dist/esm/{chunk-FLZPUYXQ.mjs → chunk-UCBUUH5M.mjs} +2 -2
- package/dist/esm/{chunk-MT2RJ7H3.mjs → chunk-WLUXOUZH.mjs} +2 -2
- package/dist/esm/{chunk-FYYEPFML.mjs → chunk-XIQFX5FV.mjs} +2 -2
- package/dist/esm/{chunk-7DQDJ2SA.mjs → chunk-YFFDF22R.mjs} +2 -2
- package/dist/esm/{chunk-WCMW2L3P.mjs → chunk-Z6KQX6VX.mjs} +2 -2
- package/dist/esm/{chunk-B563XRSZ.mjs → chunk-ZMT2M6YT.mjs} +2 -2
- package/dist/esm/cli/index.mjs +1 -1
- package/dist/esm/cli/localNode.mjs +1 -1
- package/dist/esm/client/core.mjs +1 -1
- package/dist/esm/client/get.mjs +1 -1
- package/dist/esm/client/index.mjs +1 -1
- package/dist/esm/client/post.mjs +1 -1
- package/dist/esm/core/account/index.mjs +1 -1
- package/dist/esm/core/account/utils/address.mjs +1 -1
- package/dist/esm/core/account/utils/index.mjs +1 -1
- package/dist/esm/core/accountAddress.mjs +1 -1
- package/dist/esm/core/authenticationKey.mjs +1 -1
- package/dist/esm/core/crypto/abstraction.mjs +1 -1
- package/dist/esm/core/crypto/deserializationUtils.mjs +1 -1
- package/dist/esm/core/crypto/ed25519.mjs +1 -1
- package/dist/esm/core/crypto/ephemeral.mjs +1 -1
- package/dist/esm/core/crypto/federatedKeyless.mjs +1 -1
- package/dist/esm/core/crypto/index.mjs +1 -1
- package/dist/esm/core/crypto/keyless.mjs +1 -1
- package/dist/esm/core/crypto/multiEd25519.mjs +1 -1
- package/dist/esm/core/crypto/multiKey.mjs +1 -1
- package/dist/esm/core/crypto/proof.mjs +1 -1
- package/dist/esm/core/crypto/publicKey.mjs +1 -1
- package/dist/esm/core/crypto/secp256k1.mjs +1 -1
- package/dist/esm/core/crypto/signature.mjs +1 -1
- package/dist/esm/core/crypto/singleKey.mjs +1 -1
- package/dist/esm/core/index.mjs +1 -1
- package/dist/esm/errors/index.mjs +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/internal/abstraction.mjs +1 -1
- package/dist/esm/internal/account.mjs +1 -1
- package/dist/esm/internal/ans.mjs +1 -1
- package/dist/esm/internal/coin.mjs +1 -1
- package/dist/esm/internal/digitalAsset.mjs +1 -1
- package/dist/esm/internal/event.mjs +1 -1
- package/dist/esm/internal/faucet.mjs +1 -1
- package/dist/esm/internal/fungibleAsset.mjs +1 -1
- package/dist/esm/internal/general.mjs +1 -1
- package/dist/esm/internal/keyless.mjs +1 -1
- package/dist/esm/internal/object.mjs +1 -1
- package/dist/esm/internal/staking.mjs +1 -1
- package/dist/esm/internal/table.mjs +1 -1
- package/dist/esm/internal/transaction.mjs +1 -1
- package/dist/esm/internal/transactionSubmission.mjs +1 -1
- package/dist/esm/internal/utils/index.mjs +1 -1
- package/dist/esm/internal/utils/utils.mjs +1 -1
- package/dist/esm/internal/view.mjs +1 -1
- package/dist/esm/transactions/authenticator/account.mjs +1 -1
- package/dist/esm/transactions/authenticator/index.mjs +1 -1
- package/dist/esm/transactions/authenticator/transaction.mjs +1 -1
- package/dist/esm/transactions/index.mjs +1 -1
- package/dist/esm/transactions/instances/chainId.mjs +1 -1
- package/dist/esm/transactions/instances/identifier.mjs +1 -1
- package/dist/esm/transactions/instances/index.mjs +1 -1
- package/dist/esm/transactions/instances/moduleId.mjs +1 -1
- package/dist/esm/transactions/instances/multiAgentTransaction.mjs +1 -1
- package/dist/esm/transactions/instances/rawTransaction.mjs +1 -1
- package/dist/esm/transactions/instances/rotationProofChallenge.mjs +1 -1
- package/dist/esm/transactions/instances/signedTransaction.mjs +1 -1
- package/dist/esm/transactions/instances/simpleTransaction.mjs +1 -1
- package/dist/esm/transactions/instances/transactionPayload.mjs +1 -1
- package/dist/esm/transactions/management/accountSequenceNumber.mjs +1 -1
- package/dist/esm/transactions/management/index.mjs +1 -1
- package/dist/esm/transactions/management/transactionWorker.mjs +1 -1
- package/dist/esm/transactions/transactionBuilder/helpers.mjs +1 -1
- package/dist/esm/transactions/transactionBuilder/index.mjs +1 -1
- package/dist/esm/transactions/transactionBuilder/remoteAbi.mjs +1 -1
- package/dist/esm/transactions/transactionBuilder/signingMessage.mjs +1 -1
- package/dist/esm/transactions/transactionBuilder/transactionBuilder.mjs +1 -1
- package/dist/esm/transactions/typeTag/index.mjs +1 -1
- package/dist/esm/transactions/typeTag/parser.mjs +1 -1
- package/dist/esm/utils/helpers.mjs +1 -1
- package/dist/esm/utils/index.mjs +1 -1
- package/dist/esm/utils/normalizeBundle.mjs +1 -1
- package/dist/esm/version.d.mts +1 -1
- package/dist/esm/version.mjs +1 -1
- package/package.json +1 -1
- package/src/api/transactionSubmission/helpers.ts +26 -20
- package/src/api/transactionSubmission/submit.ts +3 -3
- package/src/transactions/transactionBuilder/remoteAbi.ts +10 -1
- package/src/version.ts +1 -1
- package/dist/esm/chunk-ACNHLCQQ.mjs.map +0 -1
- package/dist/esm/chunk-CW35YAMN.mjs +0 -2
- package/dist/esm/chunk-HUWKPKPQ.mjs +0 -2
- package/dist/esm/chunk-W4BSN6SK.mjs +0 -2
- package/dist/esm/chunk-W4BSN6SK.mjs.map +0 -1
- package/dist/esm/chunk-XJJVJOX5.mjs +0 -2
- package/src/internal/move/jwks/build/jwk/BuildInfo.yaml +0 -56
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/account.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/aggregator.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/aggregator_factory.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/aggregator_v2.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/aptos_account.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/aptos_coin.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/aptos_governance.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/block.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/chain_id.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/chain_status.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/code.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/coin.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/config_buffer.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/consensus_config.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/create_signer.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/delegation_pool.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/dispatchable_fungible_asset.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/dkg.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/event.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/execution_config.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/function_info.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/fungible_asset.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/gas_schedule.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/genesis.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/governance_proposal.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/guid.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/jwk_consensus_config.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/jwks.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/keyless_account.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/managed_coin.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/multisig_account.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/object.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/object_code_deployment.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/optional_aggregator.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/primary_fungible_store.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/randomness.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/randomness_api_v0_config.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/randomness_config.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/randomness_config_seqnum.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/reconfiguration.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/reconfiguration_state.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/reconfiguration_with_dkg.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/resource_account.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/stake.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/staking_config.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/staking_contract.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/staking_proxy.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/state_storage.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/storage_gas.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/system_addresses.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/timestamp.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/transaction_context.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/transaction_fee.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/transaction_validation.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/util.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/validator_consensus_info.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/version.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/vesting.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosFramework/voting.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/any.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/aptos_hash.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/big_vector.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/bls12381.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/bls12381_algebra.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/bn254_algebra.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/capability.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/comparator.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/copyable_any.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/crypto_algebra.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/debug.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/ed25519.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/fixed_point64.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/from_bcs.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/math128.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/math64.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/math_fixed.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/math_fixed64.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/multi_ed25519.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/pool_u64.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/pool_u64_unbound.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/ristretto255.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/ristretto255_bulletproofs.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/ristretto255_elgamal.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/ristretto255_pedersen.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/secp256k1.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/simple_map.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/smart_table.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/smart_vector.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/string_utils.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/table.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/table_with_length.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/AptosStdlib/type_info.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/acl.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/bcs.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/bit_vector.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/error.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/features.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/fixed_point32.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/hash.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/option.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/signer.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/string.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_modules/dependencies/MoveStdlib/vector.mv +0 -0
- package/src/internal/move/jwks/build/jwk/bytecode_scripts/main.mv +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/account.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/aggregator.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/aggregator_factory.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/aggregator_v2.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/aptos_account.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/aptos_coin.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/aptos_governance.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/block.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/chain_id.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/chain_status.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/code.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/coin.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/config_buffer.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/consensus_config.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/create_signer.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/delegation_pool.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/dispatchable_fungible_asset.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/dkg.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/event.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/execution_config.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/function_info.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/fungible_asset.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/gas_schedule.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/genesis.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/governance_proposal.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/guid.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/jwk_consensus_config.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/jwks.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/keyless_account.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/managed_coin.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/multisig_account.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/object.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/object_code_deployment.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/optional_aggregator.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/primary_fungible_store.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/randomness.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/randomness_api_v0_config.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/randomness_config.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/randomness_config_seqnum.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/reconfiguration.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/reconfiguration_state.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/reconfiguration_with_dkg.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/resource_account.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/stake.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/staking_config.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/staking_contract.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/staking_proxy.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/state_storage.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/storage_gas.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/system_addresses.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/timestamp.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/transaction_context.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/transaction_fee.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/transaction_validation.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/util.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/validator_consensus_info.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/version.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/vesting.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosFramework/voting.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/any.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/aptos_hash.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/big_vector.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/bls12381.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/bls12381_algebra.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/bn254_algebra.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/capability.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/comparator.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/copyable_any.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/crypto_algebra.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/debug.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/ed25519.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/fixed_point64.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/from_bcs.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/math128.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/math64.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/math_fixed.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/math_fixed64.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/multi_ed25519.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/pool_u64.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/pool_u64_unbound.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/ristretto255.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/ristretto255_bulletproofs.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/ristretto255_elgamal.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/ristretto255_pedersen.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/secp256k1.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/simple_map.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/smart_table.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/smart_vector.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/string_utils.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/table.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/table_with_length.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/AptosStdlib/type_info.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/acl.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/bcs.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/bit_vector.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/error.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/features.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/fixed_point32.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/hash.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/option.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/signer.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/string.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/dependencies/MoveStdlib/vector.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/source_maps/main.mvsm +0 -0
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/account.move +0 -1533
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/aggregator.move +0 -48
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/aggregator_factory.move +0 -66
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/aggregator_v2.move +0 -280
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/aptos_account.move +0 -443
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/aptos_coin.move +0 -204
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/aptos_governance.move +0 -1387
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/block.move +0 -394
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/chain_id.move +0 -41
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/chain_status.move +0 -48
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/code.move +0 -367
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/coin.move +0 -2214
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/config_buffer.move +0 -101
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/consensus_config.move +0 -77
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/create_signer.move +0 -21
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/delegation_pool.move +0 -5568
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/dispatchable_fungible_asset.move +0 -228
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/dkg.move +0 -121
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/event.move +0 -92
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/execution_config.move +0 -66
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/function_info.move +0 -100
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/fungible_asset.move +0 -1566
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/gas_schedule.move +0 -176
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/genesis.move +0 -550
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/governance_proposal.move +0 -23
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/guid.move +0 -68
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/jwk_consensus_config.move +0 -148
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/jwks.move +0 -817
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/keyless_account.move +0 -312
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/managed_coin.move +0 -205
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/multisig_account.move +0 -2477
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/object.move +0 -1073
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/object_code_deployment.move +0 -147
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/optional_aggregator.move +0 -295
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/primary_fungible_store.move +0 -405
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/randomness.move +0 -574
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/randomness_api_v0_config.move +0 -57
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/randomness_config.move +0 -153
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/randomness_config_seqnum.move +0 -49
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/reconfiguration.move +0 -237
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/reconfiguration_state.move +0 -132
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/reconfiguration_with_dkg.move +0 -69
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/resource_account.move +0 -267
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/stake.move +0 -3286
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/staking_config.move +0 -686
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/staking_contract.move +0 -1618
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/staking_proxy.move +0 -228
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/state_storage.move +0 -90
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/storage_gas.move +0 -622
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/system_addresses.move +0 -82
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/timestamp.move +0 -88
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/transaction_context.move +0 -262
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/transaction_fee.move +0 -457
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/transaction_validation.move +0 -501
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/util.move +0 -16
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/validator_consensus_info.move +0 -42
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/version.move +0 -115
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/vesting.move +0 -2183
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosFramework/voting.move +0 -1279
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/any.move +0 -57
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/aptos_hash.move +0 -253
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/big_vector.move +0 -469
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/bls12381.move +0 -985
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/bls12381_algebra.move +0 -802
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/bn254_algebra.move +0 -855
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/capability.move +0 -193
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/comparator.move +0 -173
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/copyable_any.move +0 -45
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/crypto_algebra.move +0 -351
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/debug.move +0 -278
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/ed25519.move +0 -262
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/fixed_point64.move +0 -447
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/from_bcs.move +0 -91
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/math128.move +0 -381
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/math64.move +0 -336
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/math_fixed.move +0 -139
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/math_fixed64.move +0 -142
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/multi_ed25519.move +0 -482
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/pool_u64.move +0 -571
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/pool_u64_unbound.move +0 -270
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/ristretto255.move +0 -1310
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/ristretto255_bulletproofs.move +0 -253
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/ristretto255_elgamal.move +0 -234
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/ristretto255_pedersen.move +0 -158
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/secp256k1.move +0 -114
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/simple_map.move +0 -319
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/smart_table.move +0 -769
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/smart_vector.move +0 -766
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/string_utils.move +0 -148
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/table.move +0 -152
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/table_with_length.move +0 -141
- package/src/internal/move/jwks/build/jwk/sources/dependencies/AptosStdlib/type_info.move +0 -351
- package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/acl.move +0 -46
- package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/bcs.move +0 -27
- package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/bit_vector.move +0 -239
- package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/error.move +0 -88
- package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/features.move +0 -780
- package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/fixed_point32.move +0 -295
- package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/hash.move +0 -8
- package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/option.move +0 -356
- package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/signer.move +0 -21
- package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/string.move +0 -93
- package/src/internal/move/jwks/build/jwk/sources/dependencies/MoveStdlib/vector.move +0 -669
- package/src/internal/move/jwks/build/jwk/sources/main.move +0 -20
- /package/dist/esm/{chunk-2BOHKN33.mjs.map → chunk-6MWXV62C.mjs.map} +0 -0
- /package/dist/esm/{chunk-FGFLPH5K.mjs.map → chunk-6PKBXYG3.mjs.map} +0 -0
- /package/dist/esm/{chunk-6WDVDEQZ.mjs.map → chunk-6Y6ZO7TS.mjs.map} +0 -0
- /package/dist/esm/{chunk-SLWIGOQL.mjs.map → chunk-AQQEQB35.mjs.map} +0 -0
- /package/dist/esm/{chunk-HNBVYE3N.mjs.map → chunk-BUUV6B4P.mjs.map} +0 -0
- /package/dist/esm/{chunk-WSR5EBJM.mjs.map → chunk-BYINW7I2.mjs.map} +0 -0
- /package/dist/esm/{chunk-ORMOQWWH.mjs.map → chunk-C6JRJNK3.mjs.map} +0 -0
- /package/dist/esm/{chunk-Z5URUE4U.mjs.map → chunk-DW6WLD2B.mjs.map} +0 -0
- /package/dist/esm/{chunk-U3GMNXO4.mjs.map → chunk-E6IUB35J.mjs.map} +0 -0
- /package/dist/esm/{chunk-CO67Y6YE.mjs.map → chunk-EPMBZCYJ.mjs.map} +0 -0
- /package/dist/esm/{chunk-RQX6JOEN.mjs.map → chunk-FBCXUC7J.mjs.map} +0 -0
- /package/dist/esm/{chunk-CFQFFP6N.mjs.map → chunk-FWGLACJS.mjs.map} +0 -0
- /package/dist/esm/{chunk-TYYVB2A6.mjs.map → chunk-GRB6YSIT.mjs.map} +0 -0
- /package/dist/esm/{chunk-RGKRCZ36.mjs.map → chunk-GYVSI3TS.mjs.map} +0 -0
- /package/dist/esm/{chunk-CW35YAMN.mjs.map → chunk-HPQMAP7O.mjs.map} +0 -0
- /package/dist/esm/{chunk-TOBQ5UE6.mjs.map → chunk-IXYGZ57N.mjs.map} +0 -0
- /package/dist/esm/{chunk-MML57K5H.mjs.map → chunk-NII5Q32W.mjs.map} +0 -0
- /package/dist/esm/{chunk-EBMEXURY.mjs.map → chunk-NJN3EAOM.mjs.map} +0 -0
- /package/dist/esm/{chunk-XKUIMGKU.mjs.map → chunk-OYH2T6V5.mjs.map} +0 -0
- /package/dist/esm/{chunk-XJJVJOX5.mjs.map → chunk-OYUW6ZN2.mjs.map} +0 -0
- /package/dist/esm/{chunk-5URUYE6H.mjs.map → chunk-PQS3II2E.mjs.map} +0 -0
- /package/dist/esm/{chunk-N6YTF76Q.mjs.map → chunk-PRUQZNAP.mjs.map} +0 -0
- /package/dist/esm/{chunk-UQWF24SS.mjs.map → chunk-QGFWOGAV.mjs.map} +0 -0
- /package/dist/esm/{chunk-4COLMDT3.mjs.map → chunk-QQEK2GJC.mjs.map} +0 -0
- /package/dist/esm/{chunk-MNDTFHDB.mjs.map → chunk-RFQFTIOA.mjs.map} +0 -0
- /package/dist/esm/{chunk-XZ75T7Q7.mjs.map → chunk-THUSLDD6.mjs.map} +0 -0
- /package/dist/esm/{chunk-FLZPUYXQ.mjs.map → chunk-UCBUUH5M.mjs.map} +0 -0
- /package/dist/esm/{chunk-MT2RJ7H3.mjs.map → chunk-WLUXOUZH.mjs.map} +0 -0
- /package/dist/esm/{chunk-FYYEPFML.mjs.map → chunk-XIQFX5FV.mjs.map} +0 -0
- /package/dist/esm/{chunk-7DQDJ2SA.mjs.map → chunk-YFFDF22R.mjs.map} +0 -0
- /package/dist/esm/{chunk-WCMW2L3P.mjs.map → chunk-Z6KQX6VX.mjs.map} +0 -0
- /package/dist/esm/{chunk-B563XRSZ.mjs.map → chunk-ZMT2M6YT.mjs.map} +0 -0
|
@@ -1,3286 +0,0 @@
|
|
|
1
|
-
///
|
|
2
|
-
/// Validator lifecycle:
|
|
3
|
-
/// 1. Prepare a validator node set up and call stake::initialize_validator
|
|
4
|
-
/// 2. Once ready to deposit stake (or have funds assigned by a staking service in exchange for ownership capability),
|
|
5
|
-
/// call stake::add_stake (or *_with_cap versions if called from the staking service)
|
|
6
|
-
/// 3. Call stake::join_validator_set (or _with_cap version) to join the active validator set. Changes are effective in
|
|
7
|
-
/// the next epoch.
|
|
8
|
-
/// 4. Validate and gain rewards. The stake will automatically be locked up for a fixed duration (set by governance) and
|
|
9
|
-
/// automatically renewed at expiration.
|
|
10
|
-
/// 5. At any point, if the validator operator wants to update the consensus key or network/fullnode addresses, they can
|
|
11
|
-
/// call stake::rotate_consensus_key and stake::update_network_and_fullnode_addresses. Similar to changes to stake, the
|
|
12
|
-
/// changes to consensus key/network/fullnode addresses are only effective in the next epoch.
|
|
13
|
-
/// 6. Validator can request to unlock their stake at any time. However, their stake will only become withdrawable when
|
|
14
|
-
/// their current lockup expires. This can be at most as long as the fixed lockup duration.
|
|
15
|
-
/// 7. After exiting, the validator can either explicitly leave the validator set by calling stake::leave_validator_set
|
|
16
|
-
/// or if their stake drops below the min required, they would get removed at the end of the epoch.
|
|
17
|
-
/// 8. Validator can always rejoin the validator set by going through steps 2-3 again.
|
|
18
|
-
/// 9. An owner can always switch operators by calling stake::set_operator.
|
|
19
|
-
/// 10. An owner can always switch designated voter by calling stake::set_designated_voter.
|
|
20
|
-
module aptos_framework::stake {
|
|
21
|
-
use std::error;
|
|
22
|
-
use std::features;
|
|
23
|
-
use std::option::{Self, Option};
|
|
24
|
-
use std::signer;
|
|
25
|
-
use std::vector;
|
|
26
|
-
use aptos_std::bls12381;
|
|
27
|
-
use aptos_std::math64::min;
|
|
28
|
-
use aptos_std::table::{Self, Table};
|
|
29
|
-
use aptos_framework::aptos_coin::AptosCoin;
|
|
30
|
-
use aptos_framework::account;
|
|
31
|
-
use aptos_framework::coin::{Self, Coin, MintCapability};
|
|
32
|
-
use aptos_framework::event::{Self, EventHandle};
|
|
33
|
-
use aptos_framework::timestamp;
|
|
34
|
-
use aptos_framework::system_addresses;
|
|
35
|
-
use aptos_framework::staking_config::{Self, StakingConfig, StakingRewardsConfig};
|
|
36
|
-
use aptos_framework::chain_status;
|
|
37
|
-
|
|
38
|
-
friend aptos_framework::block;
|
|
39
|
-
friend aptos_framework::genesis;
|
|
40
|
-
friend aptos_framework::reconfiguration;
|
|
41
|
-
friend aptos_framework::reconfiguration_with_dkg;
|
|
42
|
-
friend aptos_framework::transaction_fee;
|
|
43
|
-
|
|
44
|
-
/// Validator Config not published.
|
|
45
|
-
const EVALIDATOR_CONFIG: u64 = 1;
|
|
46
|
-
/// Not enough stake to join validator set.
|
|
47
|
-
const ESTAKE_TOO_LOW: u64 = 2;
|
|
48
|
-
/// Too much stake to join validator set.
|
|
49
|
-
const ESTAKE_TOO_HIGH: u64 = 3;
|
|
50
|
-
/// Account is already a validator or pending validator.
|
|
51
|
-
const EALREADY_ACTIVE_VALIDATOR: u64 = 4;
|
|
52
|
-
/// Account is not a validator.
|
|
53
|
-
const ENOT_VALIDATOR: u64 = 5;
|
|
54
|
-
/// Can't remove last validator.
|
|
55
|
-
const ELAST_VALIDATOR: u64 = 6;
|
|
56
|
-
/// Total stake exceeds maximum allowed.
|
|
57
|
-
const ESTAKE_EXCEEDS_MAX: u64 = 7;
|
|
58
|
-
/// Account is already registered as a validator candidate.
|
|
59
|
-
const EALREADY_REGISTERED: u64 = 8;
|
|
60
|
-
/// Account does not have the right operator capability.
|
|
61
|
-
const ENOT_OPERATOR: u64 = 9;
|
|
62
|
-
/// Validators cannot join or leave post genesis on this test network.
|
|
63
|
-
const ENO_POST_GENESIS_VALIDATOR_SET_CHANGE_ALLOWED: u64 = 10;
|
|
64
|
-
/// Invalid consensus public key
|
|
65
|
-
const EINVALID_PUBLIC_KEY: u64 = 11;
|
|
66
|
-
/// Validator set exceeds the limit
|
|
67
|
-
const EVALIDATOR_SET_TOO_LARGE: u64 = 12;
|
|
68
|
-
/// Voting power increase has exceeded the limit for this current epoch.
|
|
69
|
-
const EVOTING_POWER_INCREASE_EXCEEDS_LIMIT: u64 = 13;
|
|
70
|
-
/// Stake pool does not exist at the provided pool address.
|
|
71
|
-
const ESTAKE_POOL_DOES_NOT_EXIST: u64 = 14;
|
|
72
|
-
/// Owner capability does not exist at the provided account.
|
|
73
|
-
const EOWNER_CAP_NOT_FOUND: u64 = 15;
|
|
74
|
-
/// An account cannot own more than one owner capability.
|
|
75
|
-
const EOWNER_CAP_ALREADY_EXISTS: u64 = 16;
|
|
76
|
-
/// Validator is not defined in the ACL of entities allowed to be validators
|
|
77
|
-
const EINELIGIBLE_VALIDATOR: u64 = 17;
|
|
78
|
-
/// Cannot update stake pool's lockup to earlier than current lockup.
|
|
79
|
-
const EINVALID_LOCKUP: u64 = 18;
|
|
80
|
-
/// Table to store collected transaction fees for each validator already exists.
|
|
81
|
-
const EFEES_TABLE_ALREADY_EXISTS: u64 = 19;
|
|
82
|
-
/// Validator set change temporarily disabled because of in-progress reconfiguration.
|
|
83
|
-
const ERECONFIGURATION_IN_PROGRESS: u64 = 20;
|
|
84
|
-
|
|
85
|
-
/// Validator status enum. We can switch to proper enum later once Move supports it.
|
|
86
|
-
const VALIDATOR_STATUS_PENDING_ACTIVE: u64 = 1;
|
|
87
|
-
const VALIDATOR_STATUS_ACTIVE: u64 = 2;
|
|
88
|
-
const VALIDATOR_STATUS_PENDING_INACTIVE: u64 = 3;
|
|
89
|
-
const VALIDATOR_STATUS_INACTIVE: u64 = 4;
|
|
90
|
-
|
|
91
|
-
/// Limit the maximum size to u16::max, it's the current limit of the bitvec
|
|
92
|
-
/// https://github.com/aptos-labs/aptos-core/blob/main/crates/aptos-bitvec/src/lib.rs#L20
|
|
93
|
-
const MAX_VALIDATOR_SET_SIZE: u64 = 65536;
|
|
94
|
-
|
|
95
|
-
/// Limit the maximum value of `rewards_rate` in order to avoid any arithmetic overflow.
|
|
96
|
-
const MAX_REWARDS_RATE: u64 = 1000000;
|
|
97
|
-
|
|
98
|
-
const MAX_U64: u128 = 18446744073709551615;
|
|
99
|
-
|
|
100
|
-
/// Capability that represents ownership and can be used to control the validator and the associated stake pool.
|
|
101
|
-
/// Having this be separate from the signer for the account that the validator resources are hosted at allows
|
|
102
|
-
/// modules to have control over a validator.
|
|
103
|
-
struct OwnerCapability has key, store {
|
|
104
|
-
pool_address: address,
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/// Each validator has a separate StakePool resource and can provide a stake.
|
|
108
|
-
/// Changes in stake for an active validator:
|
|
109
|
-
/// 1. If a validator calls add_stake, the newly added stake is moved to pending_active.
|
|
110
|
-
/// 2. If validator calls unlock, their stake is moved to pending_inactive.
|
|
111
|
-
/// 2. When the next epoch starts, any pending_inactive stake is moved to inactive and can be withdrawn.
|
|
112
|
-
/// Any pending_active stake is moved to active and adds to the validator's voting power.
|
|
113
|
-
///
|
|
114
|
-
/// Changes in stake for an inactive validator:
|
|
115
|
-
/// 1. If a validator calls add_stake, the newly added stake is moved directly to active.
|
|
116
|
-
/// 2. If validator calls unlock, their stake is moved directly to inactive.
|
|
117
|
-
/// 3. When the next epoch starts, the validator can be activated if their active stake is more than the minimum.
|
|
118
|
-
struct StakePool has key {
|
|
119
|
-
// active stake
|
|
120
|
-
active: Coin<AptosCoin>,
|
|
121
|
-
// inactive stake, can be withdrawn
|
|
122
|
-
inactive: Coin<AptosCoin>,
|
|
123
|
-
// pending activation for next epoch
|
|
124
|
-
pending_active: Coin<AptosCoin>,
|
|
125
|
-
// pending deactivation for next epoch
|
|
126
|
-
pending_inactive: Coin<AptosCoin>,
|
|
127
|
-
locked_until_secs: u64,
|
|
128
|
-
// Track the current operator of the validator node.
|
|
129
|
-
// This allows the operator to be different from the original account and allow for separation of
|
|
130
|
-
// the validator operations and ownership.
|
|
131
|
-
// Only the account holding OwnerCapability of the staking pool can update this.
|
|
132
|
-
operator_address: address,
|
|
133
|
-
|
|
134
|
-
// Track the current vote delegator of the staking pool.
|
|
135
|
-
// Only the account holding OwnerCapability of the staking pool can update this.
|
|
136
|
-
delegated_voter: address,
|
|
137
|
-
|
|
138
|
-
// The events emitted for the entire StakePool's lifecycle.
|
|
139
|
-
initialize_validator_events: EventHandle<RegisterValidatorCandidateEvent>,
|
|
140
|
-
set_operator_events: EventHandle<SetOperatorEvent>,
|
|
141
|
-
add_stake_events: EventHandle<AddStakeEvent>,
|
|
142
|
-
reactivate_stake_events: EventHandle<ReactivateStakeEvent>,
|
|
143
|
-
rotate_consensus_key_events: EventHandle<RotateConsensusKeyEvent>,
|
|
144
|
-
update_network_and_fullnode_addresses_events: EventHandle<UpdateNetworkAndFullnodeAddressesEvent>,
|
|
145
|
-
increase_lockup_events: EventHandle<IncreaseLockupEvent>,
|
|
146
|
-
join_validator_set_events: EventHandle<JoinValidatorSetEvent>,
|
|
147
|
-
distribute_rewards_events: EventHandle<DistributeRewardsEvent>,
|
|
148
|
-
unlock_stake_events: EventHandle<UnlockStakeEvent>,
|
|
149
|
-
withdraw_stake_events: EventHandle<WithdrawStakeEvent>,
|
|
150
|
-
leave_validator_set_events: EventHandle<LeaveValidatorSetEvent>,
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/// Validator info stored in validator address.
|
|
154
|
-
struct ValidatorConfig has key, copy, store, drop {
|
|
155
|
-
consensus_pubkey: vector<u8>,
|
|
156
|
-
network_addresses: vector<u8>,
|
|
157
|
-
// to make it compatible with previous definition, remove later
|
|
158
|
-
fullnode_addresses: vector<u8>,
|
|
159
|
-
// Index in the active set if the validator corresponding to this stake pool is active.
|
|
160
|
-
validator_index: u64,
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/// Consensus information per validator, stored in ValidatorSet.
|
|
164
|
-
struct ValidatorInfo has copy, store, drop {
|
|
165
|
-
addr: address,
|
|
166
|
-
voting_power: u64,
|
|
167
|
-
config: ValidatorConfig,
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/// Full ValidatorSet, stored in @aptos_framework.
|
|
171
|
-
/// 1. join_validator_set adds to pending_active queue.
|
|
172
|
-
/// 2. leave_valdiator_set moves from active to pending_inactive queue.
|
|
173
|
-
/// 3. on_new_epoch processes two pending queues and refresh ValidatorInfo from the owner's address.
|
|
174
|
-
struct ValidatorSet has copy, key, drop, store {
|
|
175
|
-
consensus_scheme: u8,
|
|
176
|
-
// Active validators for the current epoch.
|
|
177
|
-
active_validators: vector<ValidatorInfo>,
|
|
178
|
-
// Pending validators to leave in next epoch (still active).
|
|
179
|
-
pending_inactive: vector<ValidatorInfo>,
|
|
180
|
-
// Pending validators to join in next epoch.
|
|
181
|
-
pending_active: vector<ValidatorInfo>,
|
|
182
|
-
// Current total voting power.
|
|
183
|
-
total_voting_power: u128,
|
|
184
|
-
// Total voting power waiting to join in the next epoch.
|
|
185
|
-
total_joining_power: u128,
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/// AptosCoin capabilities, set during genesis and stored in @CoreResource account.
|
|
189
|
-
/// This allows the Stake module to mint rewards to stakers.
|
|
190
|
-
struct AptosCoinCapabilities has key {
|
|
191
|
-
mint_cap: MintCapability<AptosCoin>,
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
struct IndividualValidatorPerformance has store, drop {
|
|
195
|
-
successful_proposals: u64,
|
|
196
|
-
failed_proposals: u64,
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
struct ValidatorPerformance has key {
|
|
200
|
-
validators: vector<IndividualValidatorPerformance>,
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
struct RegisterValidatorCandidateEvent has drop, store {
|
|
204
|
-
pool_address: address,
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
#[event]
|
|
208
|
-
struct RegisterValidatorCandidate has drop, store {
|
|
209
|
-
pool_address: address,
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
struct SetOperatorEvent has drop, store {
|
|
213
|
-
pool_address: address,
|
|
214
|
-
old_operator: address,
|
|
215
|
-
new_operator: address,
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
#[event]
|
|
219
|
-
struct SetOperator has drop, store {
|
|
220
|
-
pool_address: address,
|
|
221
|
-
old_operator: address,
|
|
222
|
-
new_operator: address,
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
struct AddStakeEvent has drop, store {
|
|
226
|
-
pool_address: address,
|
|
227
|
-
amount_added: u64,
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
#[event]
|
|
231
|
-
struct AddStake has drop, store {
|
|
232
|
-
pool_address: address,
|
|
233
|
-
amount_added: u64,
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
struct ReactivateStakeEvent has drop, store {
|
|
237
|
-
pool_address: address,
|
|
238
|
-
amount: u64,
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
#[event]
|
|
242
|
-
struct ReactivateStake has drop, store {
|
|
243
|
-
pool_address: address,
|
|
244
|
-
amount: u64,
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
struct RotateConsensusKeyEvent has drop, store {
|
|
248
|
-
pool_address: address,
|
|
249
|
-
old_consensus_pubkey: vector<u8>,
|
|
250
|
-
new_consensus_pubkey: vector<u8>,
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
#[event]
|
|
254
|
-
struct RotateConsensusKey has drop, store {
|
|
255
|
-
pool_address: address,
|
|
256
|
-
old_consensus_pubkey: vector<u8>,
|
|
257
|
-
new_consensus_pubkey: vector<u8>,
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
struct UpdateNetworkAndFullnodeAddressesEvent has drop, store {
|
|
261
|
-
pool_address: address,
|
|
262
|
-
old_network_addresses: vector<u8>,
|
|
263
|
-
new_network_addresses: vector<u8>,
|
|
264
|
-
old_fullnode_addresses: vector<u8>,
|
|
265
|
-
new_fullnode_addresses: vector<u8>,
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
#[event]
|
|
269
|
-
struct UpdateNetworkAndFullnodeAddresses has drop, store {
|
|
270
|
-
pool_address: address,
|
|
271
|
-
old_network_addresses: vector<u8>,
|
|
272
|
-
new_network_addresses: vector<u8>,
|
|
273
|
-
old_fullnode_addresses: vector<u8>,
|
|
274
|
-
new_fullnode_addresses: vector<u8>,
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
struct IncreaseLockupEvent has drop, store {
|
|
278
|
-
pool_address: address,
|
|
279
|
-
old_locked_until_secs: u64,
|
|
280
|
-
new_locked_until_secs: u64,
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
#[event]
|
|
284
|
-
struct IncreaseLockup has drop, store {
|
|
285
|
-
pool_address: address,
|
|
286
|
-
old_locked_until_secs: u64,
|
|
287
|
-
new_locked_until_secs: u64,
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
struct JoinValidatorSetEvent has drop, store {
|
|
291
|
-
pool_address: address,
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
#[event]
|
|
295
|
-
struct JoinValidatorSet has drop, store {
|
|
296
|
-
pool_address: address,
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
struct DistributeRewardsEvent has drop, store {
|
|
300
|
-
pool_address: address,
|
|
301
|
-
rewards_amount: u64,
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
#[event]
|
|
305
|
-
struct DistributeRewards has drop, store {
|
|
306
|
-
pool_address: address,
|
|
307
|
-
rewards_amount: u64,
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
struct UnlockStakeEvent has drop, store {
|
|
311
|
-
pool_address: address,
|
|
312
|
-
amount_unlocked: u64,
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
#[event]
|
|
316
|
-
struct UnlockStake has drop, store {
|
|
317
|
-
pool_address: address,
|
|
318
|
-
amount_unlocked: u64,
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
struct WithdrawStakeEvent has drop, store {
|
|
322
|
-
pool_address: address,
|
|
323
|
-
amount_withdrawn: u64,
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
#[event]
|
|
327
|
-
struct WithdrawStake has drop, store {
|
|
328
|
-
pool_address: address,
|
|
329
|
-
amount_withdrawn: u64,
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
struct LeaveValidatorSetEvent has drop, store {
|
|
333
|
-
pool_address: address,
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
#[event]
|
|
337
|
-
struct LeaveValidatorSet has drop, store {
|
|
338
|
-
pool_address: address,
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
/// Stores transaction fees assigned to validators. All fees are distributed to validators
|
|
342
|
-
/// at the end of the epoch.
|
|
343
|
-
struct ValidatorFees has key {
|
|
344
|
-
fees_table: Table<address, Coin<AptosCoin>>,
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
/// Initializes the resource storing information about collected transaction fees per validator.
|
|
348
|
-
/// Used by `transaction_fee.move` to initialize fee collection and distribution.
|
|
349
|
-
public(friend) fun initialize_validator_fees(aptos_framework: &signer) {
|
|
350
|
-
system_addresses::assert_aptos_framework(aptos_framework);
|
|
351
|
-
assert!(
|
|
352
|
-
!exists<ValidatorFees>(@aptos_framework),
|
|
353
|
-
error::already_exists(EFEES_TABLE_ALREADY_EXISTS)
|
|
354
|
-
);
|
|
355
|
-
move_to(aptos_framework, ValidatorFees { fees_table: table::new() });
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/// Stores the transaction fee collected to the specified validator address.
|
|
359
|
-
public(friend) fun add_transaction_fee(validator_addr: address, fee: Coin<AptosCoin>) acquires ValidatorFees {
|
|
360
|
-
let fees_table = &mut borrow_global_mut<ValidatorFees>(@aptos_framework).fees_table;
|
|
361
|
-
if (table::contains(fees_table, validator_addr)) {
|
|
362
|
-
let collected_fee = table::borrow_mut(fees_table, validator_addr);
|
|
363
|
-
coin::merge(collected_fee, fee);
|
|
364
|
-
} else {
|
|
365
|
-
table::add(fees_table, validator_addr, fee);
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
#[view]
|
|
370
|
-
/// Return the lockup expiration of the stake pool at `pool_address`.
|
|
371
|
-
/// This will throw an error if there's no stake pool at `pool_address`.
|
|
372
|
-
public fun get_lockup_secs(pool_address: address): u64 acquires StakePool {
|
|
373
|
-
assert_stake_pool_exists(pool_address);
|
|
374
|
-
borrow_global<StakePool>(pool_address).locked_until_secs
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
#[view]
|
|
378
|
-
/// Return the remaining lockup of the stake pool at `pool_address`.
|
|
379
|
-
/// This will throw an error if there's no stake pool at `pool_address`.
|
|
380
|
-
public fun get_remaining_lockup_secs(pool_address: address): u64 acquires StakePool {
|
|
381
|
-
assert_stake_pool_exists(pool_address);
|
|
382
|
-
let lockup_time = borrow_global<StakePool>(pool_address).locked_until_secs;
|
|
383
|
-
if (lockup_time <= timestamp::now_seconds()) {
|
|
384
|
-
0
|
|
385
|
-
} else {
|
|
386
|
-
lockup_time - timestamp::now_seconds()
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
#[view]
|
|
391
|
-
/// Return the different stake amounts for `pool_address` (whether the validator is active or not).
|
|
392
|
-
/// The returned amounts are for (active, inactive, pending_active, pending_inactive) stake respectively.
|
|
393
|
-
public fun get_stake(pool_address: address): (u64, u64, u64, u64) acquires StakePool {
|
|
394
|
-
assert_stake_pool_exists(pool_address);
|
|
395
|
-
let stake_pool = borrow_global<StakePool>(pool_address);
|
|
396
|
-
(
|
|
397
|
-
coin::value(&stake_pool.active),
|
|
398
|
-
coin::value(&stake_pool.inactive),
|
|
399
|
-
coin::value(&stake_pool.pending_active),
|
|
400
|
-
coin::value(&stake_pool.pending_inactive),
|
|
401
|
-
)
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
#[view]
|
|
405
|
-
/// Returns the validator's state.
|
|
406
|
-
public fun get_validator_state(pool_address: address): u64 acquires ValidatorSet {
|
|
407
|
-
let validator_set = borrow_global<ValidatorSet>(@aptos_framework);
|
|
408
|
-
if (option::is_some(&find_validator(&validator_set.pending_active, pool_address))) {
|
|
409
|
-
VALIDATOR_STATUS_PENDING_ACTIVE
|
|
410
|
-
} else if (option::is_some(&find_validator(&validator_set.active_validators, pool_address))) {
|
|
411
|
-
VALIDATOR_STATUS_ACTIVE
|
|
412
|
-
} else if (option::is_some(&find_validator(&validator_set.pending_inactive, pool_address))) {
|
|
413
|
-
VALIDATOR_STATUS_PENDING_INACTIVE
|
|
414
|
-
} else {
|
|
415
|
-
VALIDATOR_STATUS_INACTIVE
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
#[view]
|
|
420
|
-
/// Return the voting power of the validator in the current epoch.
|
|
421
|
-
/// This is the same as the validator's total active and pending_inactive stake.
|
|
422
|
-
public fun get_current_epoch_voting_power(pool_address: address): u64 acquires StakePool, ValidatorSet {
|
|
423
|
-
assert_stake_pool_exists(pool_address);
|
|
424
|
-
let validator_state = get_validator_state(pool_address);
|
|
425
|
-
// Both active and pending inactive validators can still vote in the current epoch.
|
|
426
|
-
if (validator_state == VALIDATOR_STATUS_ACTIVE || validator_state == VALIDATOR_STATUS_PENDING_INACTIVE) {
|
|
427
|
-
let active_stake = coin::value(&borrow_global<StakePool>(pool_address).active);
|
|
428
|
-
let pending_inactive_stake = coin::value(&borrow_global<StakePool>(pool_address).pending_inactive);
|
|
429
|
-
active_stake + pending_inactive_stake
|
|
430
|
-
} else {
|
|
431
|
-
0
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
#[view]
|
|
436
|
-
/// Return the delegated voter of the validator at `pool_address`.
|
|
437
|
-
public fun get_delegated_voter(pool_address: address): address acquires StakePool {
|
|
438
|
-
assert_stake_pool_exists(pool_address);
|
|
439
|
-
borrow_global<StakePool>(pool_address).delegated_voter
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
#[view]
|
|
443
|
-
/// Return the operator of the validator at `pool_address`.
|
|
444
|
-
public fun get_operator(pool_address: address): address acquires StakePool {
|
|
445
|
-
assert_stake_pool_exists(pool_address);
|
|
446
|
-
borrow_global<StakePool>(pool_address).operator_address
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
/// Return the pool address in `owner_cap`.
|
|
450
|
-
public fun get_owned_pool_address(owner_cap: &OwnerCapability): address {
|
|
451
|
-
owner_cap.pool_address
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
#[view]
|
|
455
|
-
/// Return the validator index for `pool_address`.
|
|
456
|
-
public fun get_validator_index(pool_address: address): u64 acquires ValidatorConfig {
|
|
457
|
-
assert_stake_pool_exists(pool_address);
|
|
458
|
-
borrow_global<ValidatorConfig>(pool_address).validator_index
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
#[view]
|
|
462
|
-
/// Return the number of successful and failed proposals for the proposal at the given validator index.
|
|
463
|
-
public fun get_current_epoch_proposal_counts(validator_index: u64): (u64, u64) acquires ValidatorPerformance {
|
|
464
|
-
let validator_performances = &borrow_global<ValidatorPerformance>(@aptos_framework).validators;
|
|
465
|
-
let validator_performance = vector::borrow(validator_performances, validator_index);
|
|
466
|
-
(validator_performance.successful_proposals, validator_performance.failed_proposals)
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
#[view]
|
|
470
|
-
/// Return the validator's config.
|
|
471
|
-
public fun get_validator_config(
|
|
472
|
-
pool_address: address
|
|
473
|
-
): (vector<u8>, vector<u8>, vector<u8>) acquires ValidatorConfig {
|
|
474
|
-
assert_stake_pool_exists(pool_address);
|
|
475
|
-
let validator_config = borrow_global<ValidatorConfig>(pool_address);
|
|
476
|
-
(validator_config.consensus_pubkey, validator_config.network_addresses, validator_config.fullnode_addresses)
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
#[view]
|
|
480
|
-
public fun stake_pool_exists(addr: address): bool {
|
|
481
|
-
exists<StakePool>(addr)
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
/// Initialize validator set to the core resource account.
|
|
485
|
-
public(friend) fun initialize(aptos_framework: &signer) {
|
|
486
|
-
system_addresses::assert_aptos_framework(aptos_framework);
|
|
487
|
-
|
|
488
|
-
move_to(aptos_framework, ValidatorSet {
|
|
489
|
-
consensus_scheme: 0,
|
|
490
|
-
active_validators: vector::empty(),
|
|
491
|
-
pending_active: vector::empty(),
|
|
492
|
-
pending_inactive: vector::empty(),
|
|
493
|
-
total_voting_power: 0,
|
|
494
|
-
total_joining_power: 0,
|
|
495
|
-
});
|
|
496
|
-
|
|
497
|
-
move_to(aptos_framework, ValidatorPerformance {
|
|
498
|
-
validators: vector::empty(),
|
|
499
|
-
});
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
/// This is only called during Genesis, which is where MintCapability<AptosCoin> can be created.
|
|
503
|
-
/// Beyond genesis, no one can create AptosCoin mint/burn capabilities.
|
|
504
|
-
public(friend) fun store_aptos_coin_mint_cap(aptos_framework: &signer, mint_cap: MintCapability<AptosCoin>) {
|
|
505
|
-
system_addresses::assert_aptos_framework(aptos_framework);
|
|
506
|
-
move_to(aptos_framework, AptosCoinCapabilities { mint_cap })
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
/// Allow on chain governance to remove validators from the validator set.
|
|
510
|
-
public fun remove_validators(
|
|
511
|
-
aptos_framework: &signer,
|
|
512
|
-
validators: &vector<address>,
|
|
513
|
-
) acquires ValidatorSet {
|
|
514
|
-
assert_reconfig_not_in_progress();
|
|
515
|
-
system_addresses::assert_aptos_framework(aptos_framework);
|
|
516
|
-
let validator_set = borrow_global_mut<ValidatorSet>(@aptos_framework);
|
|
517
|
-
let active_validators = &mut validator_set.active_validators;
|
|
518
|
-
let pending_inactive = &mut validator_set.pending_inactive;
|
|
519
|
-
spec {
|
|
520
|
-
update ghost_active_num = len(active_validators);
|
|
521
|
-
update ghost_pending_inactive_num = len(pending_inactive);
|
|
522
|
-
};
|
|
523
|
-
let len_validators = vector::length(validators);
|
|
524
|
-
let i = 0;
|
|
525
|
-
// Remove each validator from the validator set.
|
|
526
|
-
while ({
|
|
527
|
-
spec {
|
|
528
|
-
invariant i <= len_validators;
|
|
529
|
-
invariant spec_validators_are_initialized(active_validators);
|
|
530
|
-
invariant spec_validator_indices_are_valid(active_validators);
|
|
531
|
-
invariant spec_validators_are_initialized(pending_inactive);
|
|
532
|
-
invariant spec_validator_indices_are_valid(pending_inactive);
|
|
533
|
-
invariant ghost_active_num + ghost_pending_inactive_num == len(active_validators) + len(pending_inactive);
|
|
534
|
-
};
|
|
535
|
-
i < len_validators
|
|
536
|
-
}) {
|
|
537
|
-
let validator = *vector::borrow(validators, i);
|
|
538
|
-
let validator_index = find_validator(active_validators, validator);
|
|
539
|
-
if (option::is_some(&validator_index)) {
|
|
540
|
-
let validator_info = vector::swap_remove(active_validators, *option::borrow(&validator_index));
|
|
541
|
-
vector::push_back(pending_inactive, validator_info);
|
|
542
|
-
spec {
|
|
543
|
-
update ghost_active_num = ghost_active_num - 1;
|
|
544
|
-
update ghost_pending_inactive_num = ghost_pending_inactive_num + 1;
|
|
545
|
-
};
|
|
546
|
-
};
|
|
547
|
-
i = i + 1;
|
|
548
|
-
};
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
/// Initialize the validator account and give ownership to the signing account
|
|
552
|
-
/// except it leaves the ValidatorConfig to be set by another entity.
|
|
553
|
-
/// Note: this triggers setting the operator and owner, set it to the account's address
|
|
554
|
-
/// to set later.
|
|
555
|
-
public entry fun initialize_stake_owner(
|
|
556
|
-
owner: &signer,
|
|
557
|
-
initial_stake_amount: u64,
|
|
558
|
-
operator: address,
|
|
559
|
-
voter: address,
|
|
560
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, ValidatorSet {
|
|
561
|
-
initialize_owner(owner);
|
|
562
|
-
move_to(owner, ValidatorConfig {
|
|
563
|
-
consensus_pubkey: vector::empty(),
|
|
564
|
-
network_addresses: vector::empty(),
|
|
565
|
-
fullnode_addresses: vector::empty(),
|
|
566
|
-
validator_index: 0,
|
|
567
|
-
});
|
|
568
|
-
|
|
569
|
-
if (initial_stake_amount > 0) {
|
|
570
|
-
add_stake(owner, initial_stake_amount);
|
|
571
|
-
};
|
|
572
|
-
|
|
573
|
-
let account_address = signer::address_of(owner);
|
|
574
|
-
if (account_address != operator) {
|
|
575
|
-
set_operator(owner, operator)
|
|
576
|
-
};
|
|
577
|
-
if (account_address != voter) {
|
|
578
|
-
set_delegated_voter(owner, voter)
|
|
579
|
-
};
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
/// Initialize the validator account and give ownership to the signing account.
|
|
583
|
-
public entry fun initialize_validator(
|
|
584
|
-
account: &signer,
|
|
585
|
-
consensus_pubkey: vector<u8>,
|
|
586
|
-
proof_of_possession: vector<u8>,
|
|
587
|
-
network_addresses: vector<u8>,
|
|
588
|
-
fullnode_addresses: vector<u8>,
|
|
589
|
-
) acquires AllowedValidators {
|
|
590
|
-
// Checks the public key has a valid proof-of-possession to prevent rogue-key attacks.
|
|
591
|
-
let pubkey_from_pop = &mut bls12381::public_key_from_bytes_with_pop(
|
|
592
|
-
consensus_pubkey,
|
|
593
|
-
&proof_of_possession_from_bytes(proof_of_possession)
|
|
594
|
-
);
|
|
595
|
-
assert!(option::is_some(pubkey_from_pop), error::invalid_argument(EINVALID_PUBLIC_KEY));
|
|
596
|
-
|
|
597
|
-
initialize_owner(account);
|
|
598
|
-
move_to(account, ValidatorConfig {
|
|
599
|
-
consensus_pubkey,
|
|
600
|
-
network_addresses,
|
|
601
|
-
fullnode_addresses,
|
|
602
|
-
validator_index: 0,
|
|
603
|
-
});
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
fun initialize_owner(owner: &signer) acquires AllowedValidators {
|
|
607
|
-
let owner_address = signer::address_of(owner);
|
|
608
|
-
assert!(is_allowed(owner_address), error::not_found(EINELIGIBLE_VALIDATOR));
|
|
609
|
-
assert!(!stake_pool_exists(owner_address), error::already_exists(EALREADY_REGISTERED));
|
|
610
|
-
|
|
611
|
-
move_to(owner, StakePool {
|
|
612
|
-
active: coin::zero<AptosCoin>(),
|
|
613
|
-
pending_active: coin::zero<AptosCoin>(),
|
|
614
|
-
pending_inactive: coin::zero<AptosCoin>(),
|
|
615
|
-
inactive: coin::zero<AptosCoin>(),
|
|
616
|
-
locked_until_secs: 0,
|
|
617
|
-
operator_address: owner_address,
|
|
618
|
-
delegated_voter: owner_address,
|
|
619
|
-
// Events.
|
|
620
|
-
initialize_validator_events: account::new_event_handle<RegisterValidatorCandidateEvent>(owner),
|
|
621
|
-
set_operator_events: account::new_event_handle<SetOperatorEvent>(owner),
|
|
622
|
-
add_stake_events: account::new_event_handle<AddStakeEvent>(owner),
|
|
623
|
-
reactivate_stake_events: account::new_event_handle<ReactivateStakeEvent>(owner),
|
|
624
|
-
rotate_consensus_key_events: account::new_event_handle<RotateConsensusKeyEvent>(owner),
|
|
625
|
-
update_network_and_fullnode_addresses_events: account::new_event_handle<UpdateNetworkAndFullnodeAddressesEvent>(
|
|
626
|
-
owner
|
|
627
|
-
),
|
|
628
|
-
increase_lockup_events: account::new_event_handle<IncreaseLockupEvent>(owner),
|
|
629
|
-
join_validator_set_events: account::new_event_handle<JoinValidatorSetEvent>(owner),
|
|
630
|
-
distribute_rewards_events: account::new_event_handle<DistributeRewardsEvent>(owner),
|
|
631
|
-
unlock_stake_events: account::new_event_handle<UnlockStakeEvent>(owner),
|
|
632
|
-
withdraw_stake_events: account::new_event_handle<WithdrawStakeEvent>(owner),
|
|
633
|
-
leave_validator_set_events: account::new_event_handle<LeaveValidatorSetEvent>(owner),
|
|
634
|
-
});
|
|
635
|
-
|
|
636
|
-
move_to(owner, OwnerCapability { pool_address: owner_address });
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
/// Extract and return owner capability from the signing account.
|
|
640
|
-
public fun extract_owner_cap(owner: &signer): OwnerCapability acquires OwnerCapability {
|
|
641
|
-
let owner_address = signer::address_of(owner);
|
|
642
|
-
assert_owner_cap_exists(owner_address);
|
|
643
|
-
move_from<OwnerCapability>(owner_address)
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
/// Deposit `owner_cap` into `account`. This requires `account` to not already have ownership of another
|
|
647
|
-
/// staking pool.
|
|
648
|
-
public fun deposit_owner_cap(owner: &signer, owner_cap: OwnerCapability) {
|
|
649
|
-
assert!(!exists<OwnerCapability>(signer::address_of(owner)), error::not_found(EOWNER_CAP_ALREADY_EXISTS));
|
|
650
|
-
move_to(owner, owner_cap);
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
/// Destroy `owner_cap`.
|
|
654
|
-
public fun destroy_owner_cap(owner_cap: OwnerCapability) {
|
|
655
|
-
let OwnerCapability { pool_address: _ } = owner_cap;
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
/// Allows an owner to change the operator of the stake pool.
|
|
659
|
-
public entry fun set_operator(owner: &signer, new_operator: address) acquires OwnerCapability, StakePool {
|
|
660
|
-
let owner_address = signer::address_of(owner);
|
|
661
|
-
assert_owner_cap_exists(owner_address);
|
|
662
|
-
let ownership_cap = borrow_global<OwnerCapability>(owner_address);
|
|
663
|
-
set_operator_with_cap(ownership_cap, new_operator);
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
/// Allows an account with ownership capability to change the operator of the stake pool.
|
|
667
|
-
public fun set_operator_with_cap(owner_cap: &OwnerCapability, new_operator: address) acquires StakePool {
|
|
668
|
-
let pool_address = owner_cap.pool_address;
|
|
669
|
-
assert_stake_pool_exists(pool_address);
|
|
670
|
-
let stake_pool = borrow_global_mut<StakePool>(pool_address);
|
|
671
|
-
let old_operator = stake_pool.operator_address;
|
|
672
|
-
stake_pool.operator_address = new_operator;
|
|
673
|
-
|
|
674
|
-
if (std::features::module_event_migration_enabled()) {
|
|
675
|
-
event::emit(
|
|
676
|
-
SetOperator {
|
|
677
|
-
pool_address,
|
|
678
|
-
old_operator,
|
|
679
|
-
new_operator,
|
|
680
|
-
},
|
|
681
|
-
);
|
|
682
|
-
};
|
|
683
|
-
|
|
684
|
-
event::emit_event(
|
|
685
|
-
&mut stake_pool.set_operator_events,
|
|
686
|
-
SetOperatorEvent {
|
|
687
|
-
pool_address,
|
|
688
|
-
old_operator,
|
|
689
|
-
new_operator,
|
|
690
|
-
},
|
|
691
|
-
);
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
/// Allows an owner to change the delegated voter of the stake pool.
|
|
695
|
-
public entry fun set_delegated_voter(owner: &signer, new_voter: address) acquires OwnerCapability, StakePool {
|
|
696
|
-
let owner_address = signer::address_of(owner);
|
|
697
|
-
assert_owner_cap_exists(owner_address);
|
|
698
|
-
let ownership_cap = borrow_global<OwnerCapability>(owner_address);
|
|
699
|
-
set_delegated_voter_with_cap(ownership_cap, new_voter);
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
/// Allows an owner to change the delegated voter of the stake pool.
|
|
703
|
-
public fun set_delegated_voter_with_cap(owner_cap: &OwnerCapability, new_voter: address) acquires StakePool {
|
|
704
|
-
let pool_address = owner_cap.pool_address;
|
|
705
|
-
assert_stake_pool_exists(pool_address);
|
|
706
|
-
let stake_pool = borrow_global_mut<StakePool>(pool_address);
|
|
707
|
-
stake_pool.delegated_voter = new_voter;
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
/// Add `amount` of coins from the `account` owning the StakePool.
|
|
711
|
-
public entry fun add_stake(owner: &signer, amount: u64) acquires OwnerCapability, StakePool, ValidatorSet {
|
|
712
|
-
let owner_address = signer::address_of(owner);
|
|
713
|
-
assert_owner_cap_exists(owner_address);
|
|
714
|
-
let ownership_cap = borrow_global<OwnerCapability>(owner_address);
|
|
715
|
-
add_stake_with_cap(ownership_cap, coin::withdraw<AptosCoin>(owner, amount));
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
/// Add `coins` into `pool_address`. this requires the corresponding `owner_cap` to be passed in.
|
|
719
|
-
public fun add_stake_with_cap(owner_cap: &OwnerCapability, coins: Coin<AptosCoin>) acquires StakePool, ValidatorSet {
|
|
720
|
-
assert_reconfig_not_in_progress();
|
|
721
|
-
let pool_address = owner_cap.pool_address;
|
|
722
|
-
assert_stake_pool_exists(pool_address);
|
|
723
|
-
|
|
724
|
-
let amount = coin::value(&coins);
|
|
725
|
-
if (amount == 0) {
|
|
726
|
-
coin::destroy_zero(coins);
|
|
727
|
-
return
|
|
728
|
-
};
|
|
729
|
-
|
|
730
|
-
// Only track and validate voting power increase for active and pending_active validator.
|
|
731
|
-
// Pending_inactive validator will be removed from the validator set in the next epoch.
|
|
732
|
-
// Inactive validator's total stake will be tracked when they join the validator set.
|
|
733
|
-
let validator_set = borrow_global_mut<ValidatorSet>(@aptos_framework);
|
|
734
|
-
// Search directly rather using get_validator_state to save on unnecessary loops.
|
|
735
|
-
if (option::is_some(&find_validator(&validator_set.active_validators, pool_address)) ||
|
|
736
|
-
option::is_some(&find_validator(&validator_set.pending_active, pool_address))) {
|
|
737
|
-
update_voting_power_increase(amount);
|
|
738
|
-
};
|
|
739
|
-
|
|
740
|
-
// Add to pending_active if it's a current validator because the stake is not counted until the next epoch.
|
|
741
|
-
// Otherwise, the delegation can be added to active directly as the validator is also activated in the epoch.
|
|
742
|
-
let stake_pool = borrow_global_mut<StakePool>(pool_address);
|
|
743
|
-
if (is_current_epoch_validator(pool_address)) {
|
|
744
|
-
coin::merge<AptosCoin>(&mut stake_pool.pending_active, coins);
|
|
745
|
-
} else {
|
|
746
|
-
coin::merge<AptosCoin>(&mut stake_pool.active, coins);
|
|
747
|
-
};
|
|
748
|
-
|
|
749
|
-
let (_, maximum_stake) = staking_config::get_required_stake(&staking_config::get());
|
|
750
|
-
let voting_power = get_next_epoch_voting_power(stake_pool);
|
|
751
|
-
assert!(voting_power <= maximum_stake, error::invalid_argument(ESTAKE_EXCEEDS_MAX));
|
|
752
|
-
|
|
753
|
-
if (std::features::module_event_migration_enabled()) {
|
|
754
|
-
event::emit(
|
|
755
|
-
AddStake {
|
|
756
|
-
pool_address,
|
|
757
|
-
amount_added: amount,
|
|
758
|
-
},
|
|
759
|
-
);
|
|
760
|
-
};
|
|
761
|
-
event::emit_event(
|
|
762
|
-
&mut stake_pool.add_stake_events,
|
|
763
|
-
AddStakeEvent {
|
|
764
|
-
pool_address,
|
|
765
|
-
amount_added: amount,
|
|
766
|
-
},
|
|
767
|
-
);
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
/// Move `amount` of coins from pending_inactive to active.
|
|
771
|
-
public entry fun reactivate_stake(owner: &signer, amount: u64) acquires OwnerCapability, StakePool {
|
|
772
|
-
assert_reconfig_not_in_progress();
|
|
773
|
-
let owner_address = signer::address_of(owner);
|
|
774
|
-
assert_owner_cap_exists(owner_address);
|
|
775
|
-
let ownership_cap = borrow_global<OwnerCapability>(owner_address);
|
|
776
|
-
reactivate_stake_with_cap(ownership_cap, amount);
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
public fun reactivate_stake_with_cap(owner_cap: &OwnerCapability, amount: u64) acquires StakePool {
|
|
780
|
-
assert_reconfig_not_in_progress();
|
|
781
|
-
let pool_address = owner_cap.pool_address;
|
|
782
|
-
assert_stake_pool_exists(pool_address);
|
|
783
|
-
|
|
784
|
-
// Cap the amount to reactivate by the amount in pending_inactive.
|
|
785
|
-
let stake_pool = borrow_global_mut<StakePool>(pool_address);
|
|
786
|
-
let total_pending_inactive = coin::value(&stake_pool.pending_inactive);
|
|
787
|
-
amount = min(amount, total_pending_inactive);
|
|
788
|
-
|
|
789
|
-
// Since this does not count as a voting power change (pending inactive still counts as voting power in the
|
|
790
|
-
// current epoch), stake can be immediately moved from pending inactive to active.
|
|
791
|
-
// We also don't need to check voting power increase as there's none.
|
|
792
|
-
let reactivated_coins = coin::extract(&mut stake_pool.pending_inactive, amount);
|
|
793
|
-
coin::merge(&mut stake_pool.active, reactivated_coins);
|
|
794
|
-
|
|
795
|
-
if (std::features::module_event_migration_enabled()) {
|
|
796
|
-
event::emit(
|
|
797
|
-
ReactivateStake {
|
|
798
|
-
pool_address,
|
|
799
|
-
amount,
|
|
800
|
-
},
|
|
801
|
-
);
|
|
802
|
-
};
|
|
803
|
-
event::emit_event(
|
|
804
|
-
&mut stake_pool.reactivate_stake_events,
|
|
805
|
-
ReactivateStakeEvent {
|
|
806
|
-
pool_address,
|
|
807
|
-
amount,
|
|
808
|
-
},
|
|
809
|
-
);
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
/// Rotate the consensus key of the validator, it'll take effect in next epoch.
|
|
813
|
-
public entry fun rotate_consensus_key(
|
|
814
|
-
operator: &signer,
|
|
815
|
-
pool_address: address,
|
|
816
|
-
new_consensus_pubkey: vector<u8>,
|
|
817
|
-
proof_of_possession: vector<u8>,
|
|
818
|
-
) acquires StakePool, ValidatorConfig {
|
|
819
|
-
assert_reconfig_not_in_progress();
|
|
820
|
-
assert_stake_pool_exists(pool_address);
|
|
821
|
-
|
|
822
|
-
let stake_pool = borrow_global_mut<StakePool>(pool_address);
|
|
823
|
-
assert!(signer::address_of(operator) == stake_pool.operator_address, error::unauthenticated(ENOT_OPERATOR));
|
|
824
|
-
|
|
825
|
-
assert!(exists<ValidatorConfig>(pool_address), error::not_found(EVALIDATOR_CONFIG));
|
|
826
|
-
let validator_info = borrow_global_mut<ValidatorConfig>(pool_address);
|
|
827
|
-
let old_consensus_pubkey = validator_info.consensus_pubkey;
|
|
828
|
-
// Checks the public key has a valid proof-of-possession to prevent rogue-key attacks.
|
|
829
|
-
let pubkey_from_pop = &mut bls12381::public_key_from_bytes_with_pop(
|
|
830
|
-
new_consensus_pubkey,
|
|
831
|
-
&proof_of_possession_from_bytes(proof_of_possession)
|
|
832
|
-
);
|
|
833
|
-
assert!(option::is_some(pubkey_from_pop), error::invalid_argument(EINVALID_PUBLIC_KEY));
|
|
834
|
-
validator_info.consensus_pubkey = new_consensus_pubkey;
|
|
835
|
-
|
|
836
|
-
if (std::features::module_event_migration_enabled()) {
|
|
837
|
-
event::emit(
|
|
838
|
-
RotateConsensusKey {
|
|
839
|
-
pool_address,
|
|
840
|
-
old_consensus_pubkey,
|
|
841
|
-
new_consensus_pubkey,
|
|
842
|
-
},
|
|
843
|
-
);
|
|
844
|
-
};
|
|
845
|
-
event::emit_event(
|
|
846
|
-
&mut stake_pool.rotate_consensus_key_events,
|
|
847
|
-
RotateConsensusKeyEvent {
|
|
848
|
-
pool_address,
|
|
849
|
-
old_consensus_pubkey,
|
|
850
|
-
new_consensus_pubkey,
|
|
851
|
-
},
|
|
852
|
-
);
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
/// Update the network and full node addresses of the validator. This only takes effect in the next epoch.
|
|
856
|
-
public entry fun update_network_and_fullnode_addresses(
|
|
857
|
-
operator: &signer,
|
|
858
|
-
pool_address: address,
|
|
859
|
-
new_network_addresses: vector<u8>,
|
|
860
|
-
new_fullnode_addresses: vector<u8>,
|
|
861
|
-
) acquires StakePool, ValidatorConfig {
|
|
862
|
-
assert_reconfig_not_in_progress();
|
|
863
|
-
assert_stake_pool_exists(pool_address);
|
|
864
|
-
let stake_pool = borrow_global_mut<StakePool>(pool_address);
|
|
865
|
-
assert!(signer::address_of(operator) == stake_pool.operator_address, error::unauthenticated(ENOT_OPERATOR));
|
|
866
|
-
assert!(exists<ValidatorConfig>(pool_address), error::not_found(EVALIDATOR_CONFIG));
|
|
867
|
-
let validator_info = borrow_global_mut<ValidatorConfig>(pool_address);
|
|
868
|
-
let old_network_addresses = validator_info.network_addresses;
|
|
869
|
-
validator_info.network_addresses = new_network_addresses;
|
|
870
|
-
let old_fullnode_addresses = validator_info.fullnode_addresses;
|
|
871
|
-
validator_info.fullnode_addresses = new_fullnode_addresses;
|
|
872
|
-
|
|
873
|
-
if (std::features::module_event_migration_enabled()) {
|
|
874
|
-
event::emit(
|
|
875
|
-
UpdateNetworkAndFullnodeAddresses {
|
|
876
|
-
pool_address,
|
|
877
|
-
old_network_addresses,
|
|
878
|
-
new_network_addresses,
|
|
879
|
-
old_fullnode_addresses,
|
|
880
|
-
new_fullnode_addresses,
|
|
881
|
-
},
|
|
882
|
-
);
|
|
883
|
-
};
|
|
884
|
-
event::emit_event(
|
|
885
|
-
&mut stake_pool.update_network_and_fullnode_addresses_events,
|
|
886
|
-
UpdateNetworkAndFullnodeAddressesEvent {
|
|
887
|
-
pool_address,
|
|
888
|
-
old_network_addresses,
|
|
889
|
-
new_network_addresses,
|
|
890
|
-
old_fullnode_addresses,
|
|
891
|
-
new_fullnode_addresses,
|
|
892
|
-
},
|
|
893
|
-
);
|
|
894
|
-
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
/// Similar to increase_lockup_with_cap but will use ownership capability from the signing account.
|
|
898
|
-
public entry fun increase_lockup(owner: &signer) acquires OwnerCapability, StakePool {
|
|
899
|
-
let owner_address = signer::address_of(owner);
|
|
900
|
-
assert_owner_cap_exists(owner_address);
|
|
901
|
-
let ownership_cap = borrow_global<OwnerCapability>(owner_address);
|
|
902
|
-
increase_lockup_with_cap(ownership_cap);
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
/// Unlock from active delegation, it's moved to pending_inactive if locked_until_secs < current_time or
|
|
906
|
-
/// directly inactive if it's not from an active validator.
|
|
907
|
-
public fun increase_lockup_with_cap(owner_cap: &OwnerCapability) acquires StakePool {
|
|
908
|
-
let pool_address = owner_cap.pool_address;
|
|
909
|
-
assert_stake_pool_exists(pool_address);
|
|
910
|
-
let config = staking_config::get();
|
|
911
|
-
|
|
912
|
-
let stake_pool = borrow_global_mut<StakePool>(pool_address);
|
|
913
|
-
let old_locked_until_secs = stake_pool.locked_until_secs;
|
|
914
|
-
let new_locked_until_secs = timestamp::now_seconds() + staking_config::get_recurring_lockup_duration(&config);
|
|
915
|
-
assert!(old_locked_until_secs < new_locked_until_secs, error::invalid_argument(EINVALID_LOCKUP));
|
|
916
|
-
stake_pool.locked_until_secs = new_locked_until_secs;
|
|
917
|
-
|
|
918
|
-
if (std::features::module_event_migration_enabled()) {
|
|
919
|
-
event::emit(
|
|
920
|
-
IncreaseLockup {
|
|
921
|
-
pool_address,
|
|
922
|
-
old_locked_until_secs,
|
|
923
|
-
new_locked_until_secs,
|
|
924
|
-
},
|
|
925
|
-
);
|
|
926
|
-
};
|
|
927
|
-
event::emit_event(
|
|
928
|
-
&mut stake_pool.increase_lockup_events,
|
|
929
|
-
IncreaseLockupEvent {
|
|
930
|
-
pool_address,
|
|
931
|
-
old_locked_until_secs,
|
|
932
|
-
new_locked_until_secs,
|
|
933
|
-
},
|
|
934
|
-
);
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
/// This can only called by the operator of the validator/staking pool.
|
|
938
|
-
public entry fun join_validator_set(
|
|
939
|
-
operator: &signer,
|
|
940
|
-
pool_address: address
|
|
941
|
-
) acquires StakePool, ValidatorConfig, ValidatorSet {
|
|
942
|
-
assert!(
|
|
943
|
-
staking_config::get_allow_validator_set_change(&staking_config::get()),
|
|
944
|
-
error::invalid_argument(ENO_POST_GENESIS_VALIDATOR_SET_CHANGE_ALLOWED),
|
|
945
|
-
);
|
|
946
|
-
|
|
947
|
-
join_validator_set_internal(operator, pool_address);
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
/// Request to have `pool_address` join the validator set. Can only be called after calling `initialize_validator`.
|
|
951
|
-
/// If the validator has the required stake (more than minimum and less than maximum allowed), they will be
|
|
952
|
-
/// added to the pending_active queue. All validators in this queue will be added to the active set when the next
|
|
953
|
-
/// epoch starts (eligibility will be rechecked).
|
|
954
|
-
///
|
|
955
|
-
/// This internal version can only be called by the Genesis module during Genesis.
|
|
956
|
-
public(friend) fun join_validator_set_internal(
|
|
957
|
-
operator: &signer,
|
|
958
|
-
pool_address: address
|
|
959
|
-
) acquires StakePool, ValidatorConfig, ValidatorSet {
|
|
960
|
-
assert_reconfig_not_in_progress();
|
|
961
|
-
assert_stake_pool_exists(pool_address);
|
|
962
|
-
let stake_pool = borrow_global_mut<StakePool>(pool_address);
|
|
963
|
-
assert!(signer::address_of(operator) == stake_pool.operator_address, error::unauthenticated(ENOT_OPERATOR));
|
|
964
|
-
assert!(
|
|
965
|
-
get_validator_state(pool_address) == VALIDATOR_STATUS_INACTIVE,
|
|
966
|
-
error::invalid_state(EALREADY_ACTIVE_VALIDATOR),
|
|
967
|
-
);
|
|
968
|
-
|
|
969
|
-
let config = staking_config::get();
|
|
970
|
-
let (minimum_stake, maximum_stake) = staking_config::get_required_stake(&config);
|
|
971
|
-
let voting_power = get_next_epoch_voting_power(stake_pool);
|
|
972
|
-
assert!(voting_power >= minimum_stake, error::invalid_argument(ESTAKE_TOO_LOW));
|
|
973
|
-
assert!(voting_power <= maximum_stake, error::invalid_argument(ESTAKE_TOO_HIGH));
|
|
974
|
-
|
|
975
|
-
// Track and validate voting power increase.
|
|
976
|
-
update_voting_power_increase(voting_power);
|
|
977
|
-
|
|
978
|
-
// Add validator to pending_active, to be activated in the next epoch.
|
|
979
|
-
let validator_config = borrow_global_mut<ValidatorConfig>(pool_address);
|
|
980
|
-
assert!(!vector::is_empty(&validator_config.consensus_pubkey), error::invalid_argument(EINVALID_PUBLIC_KEY));
|
|
981
|
-
|
|
982
|
-
// Validate the current validator set size has not exceeded the limit.
|
|
983
|
-
let validator_set = borrow_global_mut<ValidatorSet>(@aptos_framework);
|
|
984
|
-
vector::push_back(
|
|
985
|
-
&mut validator_set.pending_active,
|
|
986
|
-
generate_validator_info(pool_address, stake_pool, *validator_config)
|
|
987
|
-
);
|
|
988
|
-
let validator_set_size = vector::length(&validator_set.active_validators) + vector::length(
|
|
989
|
-
&validator_set.pending_active
|
|
990
|
-
);
|
|
991
|
-
assert!(validator_set_size <= MAX_VALIDATOR_SET_SIZE, error::invalid_argument(EVALIDATOR_SET_TOO_LARGE));
|
|
992
|
-
|
|
993
|
-
if (std::features::module_event_migration_enabled()) {
|
|
994
|
-
event::emit(JoinValidatorSet { pool_address });
|
|
995
|
-
};
|
|
996
|
-
event::emit_event(
|
|
997
|
-
&mut stake_pool.join_validator_set_events,
|
|
998
|
-
JoinValidatorSetEvent { pool_address },
|
|
999
|
-
);
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
|
-
/// Similar to unlock_with_cap but will use ownership capability from the signing account.
|
|
1003
|
-
public entry fun unlock(owner: &signer, amount: u64) acquires OwnerCapability, StakePool {
|
|
1004
|
-
assert_reconfig_not_in_progress();
|
|
1005
|
-
let owner_address = signer::address_of(owner);
|
|
1006
|
-
assert_owner_cap_exists(owner_address);
|
|
1007
|
-
let ownership_cap = borrow_global<OwnerCapability>(owner_address);
|
|
1008
|
-
unlock_with_cap(amount, ownership_cap);
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
/// Unlock `amount` from the active stake. Only possible if the lockup has expired.
|
|
1012
|
-
public fun unlock_with_cap(amount: u64, owner_cap: &OwnerCapability) acquires StakePool {
|
|
1013
|
-
assert_reconfig_not_in_progress();
|
|
1014
|
-
// Short-circuit if amount to unlock is 0 so we don't emit events.
|
|
1015
|
-
if (amount == 0) {
|
|
1016
|
-
return
|
|
1017
|
-
};
|
|
1018
|
-
|
|
1019
|
-
// Unlocked coins are moved to pending_inactive. When the current lockup cycle expires, they will be moved into
|
|
1020
|
-
// inactive in the earliest possible epoch transition.
|
|
1021
|
-
let pool_address = owner_cap.pool_address;
|
|
1022
|
-
assert_stake_pool_exists(pool_address);
|
|
1023
|
-
let stake_pool = borrow_global_mut<StakePool>(pool_address);
|
|
1024
|
-
// Cap amount to unlock by maximum active stake.
|
|
1025
|
-
let amount = min(amount, coin::value(&stake_pool.active));
|
|
1026
|
-
let unlocked_stake = coin::extract(&mut stake_pool.active, amount);
|
|
1027
|
-
coin::merge<AptosCoin>(&mut stake_pool.pending_inactive, unlocked_stake);
|
|
1028
|
-
|
|
1029
|
-
if (std::features::module_event_migration_enabled()) {
|
|
1030
|
-
event::emit(
|
|
1031
|
-
UnlockStake {
|
|
1032
|
-
pool_address,
|
|
1033
|
-
amount_unlocked: amount,
|
|
1034
|
-
},
|
|
1035
|
-
);
|
|
1036
|
-
};
|
|
1037
|
-
event::emit_event(
|
|
1038
|
-
&mut stake_pool.unlock_stake_events,
|
|
1039
|
-
UnlockStakeEvent {
|
|
1040
|
-
pool_address,
|
|
1041
|
-
amount_unlocked: amount,
|
|
1042
|
-
},
|
|
1043
|
-
);
|
|
1044
|
-
}
|
|
1045
|
-
|
|
1046
|
-
/// Withdraw from `account`'s inactive stake.
|
|
1047
|
-
public entry fun withdraw(
|
|
1048
|
-
owner: &signer,
|
|
1049
|
-
withdraw_amount: u64
|
|
1050
|
-
) acquires OwnerCapability, StakePool, ValidatorSet {
|
|
1051
|
-
let owner_address = signer::address_of(owner);
|
|
1052
|
-
assert_owner_cap_exists(owner_address);
|
|
1053
|
-
let ownership_cap = borrow_global<OwnerCapability>(owner_address);
|
|
1054
|
-
let coins = withdraw_with_cap(ownership_cap, withdraw_amount);
|
|
1055
|
-
coin::deposit<AptosCoin>(owner_address, coins);
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
/// Withdraw from `pool_address`'s inactive stake with the corresponding `owner_cap`.
|
|
1059
|
-
public fun withdraw_with_cap(
|
|
1060
|
-
owner_cap: &OwnerCapability,
|
|
1061
|
-
withdraw_amount: u64
|
|
1062
|
-
): Coin<AptosCoin> acquires StakePool, ValidatorSet {
|
|
1063
|
-
assert_reconfig_not_in_progress();
|
|
1064
|
-
let pool_address = owner_cap.pool_address;
|
|
1065
|
-
assert_stake_pool_exists(pool_address);
|
|
1066
|
-
let stake_pool = borrow_global_mut<StakePool>(pool_address);
|
|
1067
|
-
// There's an edge case where a validator unlocks their stake and leaves the validator set before
|
|
1068
|
-
// the stake is fully unlocked (the current lockup cycle has not expired yet).
|
|
1069
|
-
// This can leave their stake stuck in pending_inactive even after the current lockup cycle expires.
|
|
1070
|
-
if (get_validator_state(pool_address) == VALIDATOR_STATUS_INACTIVE &&
|
|
1071
|
-
timestamp::now_seconds() >= stake_pool.locked_until_secs) {
|
|
1072
|
-
let pending_inactive_stake = coin::extract_all(&mut stake_pool.pending_inactive);
|
|
1073
|
-
coin::merge(&mut stake_pool.inactive, pending_inactive_stake);
|
|
1074
|
-
};
|
|
1075
|
-
|
|
1076
|
-
// Cap withdraw amount by total inactive coins.
|
|
1077
|
-
withdraw_amount = min(withdraw_amount, coin::value(&stake_pool.inactive));
|
|
1078
|
-
if (withdraw_amount == 0) return coin::zero<AptosCoin>();
|
|
1079
|
-
|
|
1080
|
-
if (std::features::module_event_migration_enabled()) {
|
|
1081
|
-
event::emit(
|
|
1082
|
-
WithdrawStake {
|
|
1083
|
-
pool_address,
|
|
1084
|
-
amount_withdrawn: withdraw_amount,
|
|
1085
|
-
},
|
|
1086
|
-
);
|
|
1087
|
-
};
|
|
1088
|
-
event::emit_event(
|
|
1089
|
-
&mut stake_pool.withdraw_stake_events,
|
|
1090
|
-
WithdrawStakeEvent {
|
|
1091
|
-
pool_address,
|
|
1092
|
-
amount_withdrawn: withdraw_amount,
|
|
1093
|
-
},
|
|
1094
|
-
);
|
|
1095
|
-
|
|
1096
|
-
coin::extract(&mut stake_pool.inactive, withdraw_amount)
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
/// Request to have `pool_address` leave the validator set. The validator is only actually removed from the set when
|
|
1100
|
-
/// the next epoch starts.
|
|
1101
|
-
/// The last validator in the set cannot leave. This is an edge case that should never happen as long as the network
|
|
1102
|
-
/// is still operational.
|
|
1103
|
-
///
|
|
1104
|
-
/// Can only be called by the operator of the validator/staking pool.
|
|
1105
|
-
public entry fun leave_validator_set(
|
|
1106
|
-
operator: &signer,
|
|
1107
|
-
pool_address: address
|
|
1108
|
-
) acquires StakePool, ValidatorSet {
|
|
1109
|
-
assert_reconfig_not_in_progress();
|
|
1110
|
-
let config = staking_config::get();
|
|
1111
|
-
assert!(
|
|
1112
|
-
staking_config::get_allow_validator_set_change(&config),
|
|
1113
|
-
error::invalid_argument(ENO_POST_GENESIS_VALIDATOR_SET_CHANGE_ALLOWED),
|
|
1114
|
-
);
|
|
1115
|
-
|
|
1116
|
-
assert_stake_pool_exists(pool_address);
|
|
1117
|
-
let stake_pool = borrow_global_mut<StakePool>(pool_address);
|
|
1118
|
-
// Account has to be the operator.
|
|
1119
|
-
assert!(signer::address_of(operator) == stake_pool.operator_address, error::unauthenticated(ENOT_OPERATOR));
|
|
1120
|
-
|
|
1121
|
-
let validator_set = borrow_global_mut<ValidatorSet>(@aptos_framework);
|
|
1122
|
-
// If the validator is still pending_active, directly kick the validator out.
|
|
1123
|
-
let maybe_pending_active_index = find_validator(&validator_set.pending_active, pool_address);
|
|
1124
|
-
if (option::is_some(&maybe_pending_active_index)) {
|
|
1125
|
-
vector::swap_remove(
|
|
1126
|
-
&mut validator_set.pending_active, option::extract(&mut maybe_pending_active_index));
|
|
1127
|
-
|
|
1128
|
-
// Decrease the voting power increase as the pending validator's voting power was added when they requested
|
|
1129
|
-
// to join. Now that they changed their mind, their voting power should not affect the joining limit of this
|
|
1130
|
-
// epoch.
|
|
1131
|
-
let validator_stake = (get_next_epoch_voting_power(stake_pool) as u128);
|
|
1132
|
-
// total_joining_power should be larger than validator_stake but just in case there has been a small
|
|
1133
|
-
// rounding error somewhere that can lead to an underflow, we still want to allow this transaction to
|
|
1134
|
-
// succeed.
|
|
1135
|
-
if (validator_set.total_joining_power > validator_stake) {
|
|
1136
|
-
validator_set.total_joining_power = validator_set.total_joining_power - validator_stake;
|
|
1137
|
-
} else {
|
|
1138
|
-
validator_set.total_joining_power = 0;
|
|
1139
|
-
};
|
|
1140
|
-
} else {
|
|
1141
|
-
// Validate that the validator is already part of the validator set.
|
|
1142
|
-
let maybe_active_index = find_validator(&validator_set.active_validators, pool_address);
|
|
1143
|
-
assert!(option::is_some(&maybe_active_index), error::invalid_state(ENOT_VALIDATOR));
|
|
1144
|
-
let validator_info = vector::swap_remove(
|
|
1145
|
-
&mut validator_set.active_validators, option::extract(&mut maybe_active_index));
|
|
1146
|
-
assert!(vector::length(&validator_set.active_validators) > 0, error::invalid_state(ELAST_VALIDATOR));
|
|
1147
|
-
vector::push_back(&mut validator_set.pending_inactive, validator_info);
|
|
1148
|
-
|
|
1149
|
-
if (std::features::module_event_migration_enabled()) {
|
|
1150
|
-
event::emit(LeaveValidatorSet { pool_address });
|
|
1151
|
-
};
|
|
1152
|
-
event::emit_event(
|
|
1153
|
-
&mut stake_pool.leave_validator_set_events,
|
|
1154
|
-
LeaveValidatorSetEvent {
|
|
1155
|
-
pool_address,
|
|
1156
|
-
},
|
|
1157
|
-
);
|
|
1158
|
-
};
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
|
-
/// Returns true if the current validator can still vote in the current epoch.
|
|
1162
|
-
/// This includes validators that requested to leave but are still in the pending_inactive queue and will be removed
|
|
1163
|
-
/// when the epoch starts.
|
|
1164
|
-
public fun is_current_epoch_validator(pool_address: address): bool acquires ValidatorSet {
|
|
1165
|
-
assert_stake_pool_exists(pool_address);
|
|
1166
|
-
let validator_state = get_validator_state(pool_address);
|
|
1167
|
-
validator_state == VALIDATOR_STATUS_ACTIVE || validator_state == VALIDATOR_STATUS_PENDING_INACTIVE
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
|
-
/// Update the validator performance (proposal statistics). This is only called by block::prologue().
|
|
1171
|
-
/// This function cannot abort.
|
|
1172
|
-
public(friend) fun update_performance_statistics(
|
|
1173
|
-
proposer_index: Option<u64>,
|
|
1174
|
-
failed_proposer_indices: vector<u64>
|
|
1175
|
-
) acquires ValidatorPerformance {
|
|
1176
|
-
// Validator set cannot change until the end of the epoch, so the validator index in arguments should
|
|
1177
|
-
// match with those of the validators in ValidatorPerformance resource.
|
|
1178
|
-
let validator_perf = borrow_global_mut<ValidatorPerformance>(@aptos_framework);
|
|
1179
|
-
let validator_len = vector::length(&validator_perf.validators);
|
|
1180
|
-
|
|
1181
|
-
spec {
|
|
1182
|
-
update ghost_valid_perf = validator_perf;
|
|
1183
|
-
update ghost_proposer_idx = proposer_index;
|
|
1184
|
-
};
|
|
1185
|
-
// proposer_index is an option because it can be missing (for NilBlocks)
|
|
1186
|
-
if (option::is_some(&proposer_index)) {
|
|
1187
|
-
let cur_proposer_index = option::extract(&mut proposer_index);
|
|
1188
|
-
// Here, and in all other vector::borrow, skip any validator indices that are out of bounds,
|
|
1189
|
-
// this ensures that this function doesn't abort if there are out of bounds errors.
|
|
1190
|
-
if (cur_proposer_index < validator_len) {
|
|
1191
|
-
let validator = vector::borrow_mut(&mut validator_perf.validators, cur_proposer_index);
|
|
1192
|
-
spec {
|
|
1193
|
-
assume validator.successful_proposals + 1 <= MAX_U64;
|
|
1194
|
-
};
|
|
1195
|
-
validator.successful_proposals = validator.successful_proposals + 1;
|
|
1196
|
-
};
|
|
1197
|
-
};
|
|
1198
|
-
|
|
1199
|
-
let f = 0;
|
|
1200
|
-
let f_len = vector::length(&failed_proposer_indices);
|
|
1201
|
-
while ({
|
|
1202
|
-
spec {
|
|
1203
|
-
invariant len(validator_perf.validators) == validator_len;
|
|
1204
|
-
invariant (option::spec_is_some(ghost_proposer_idx) && option::spec_borrow(
|
|
1205
|
-
ghost_proposer_idx
|
|
1206
|
-
) < validator_len) ==>
|
|
1207
|
-
(validator_perf.validators[option::spec_borrow(ghost_proposer_idx)].successful_proposals ==
|
|
1208
|
-
ghost_valid_perf.validators[option::spec_borrow(ghost_proposer_idx)].successful_proposals + 1);
|
|
1209
|
-
};
|
|
1210
|
-
f < f_len
|
|
1211
|
-
}) {
|
|
1212
|
-
let validator_index = *vector::borrow(&failed_proposer_indices, f);
|
|
1213
|
-
if (validator_index < validator_len) {
|
|
1214
|
-
let validator = vector::borrow_mut(&mut validator_perf.validators, validator_index);
|
|
1215
|
-
spec {
|
|
1216
|
-
assume validator.failed_proposals + 1 <= MAX_U64;
|
|
1217
|
-
};
|
|
1218
|
-
validator.failed_proposals = validator.failed_proposals + 1;
|
|
1219
|
-
};
|
|
1220
|
-
f = f + 1;
|
|
1221
|
-
};
|
|
1222
|
-
}
|
|
1223
|
-
|
|
1224
|
-
/// Triggered during a reconfiguration. This function shouldn't abort.
|
|
1225
|
-
///
|
|
1226
|
-
/// 1. Distribute transaction fees and rewards to stake pools of active and pending inactive validators (requested
|
|
1227
|
-
/// to leave but not yet removed).
|
|
1228
|
-
/// 2. Officially move pending active stake to active and move pending inactive stake to inactive.
|
|
1229
|
-
/// The staking pool's voting power in this new epoch will be updated to the total active stake.
|
|
1230
|
-
/// 3. Add pending active validators to the active set if they satisfy requirements so they can vote and remove
|
|
1231
|
-
/// pending inactive validators so they no longer can vote.
|
|
1232
|
-
/// 4. The validator's voting power in the validator set is updated to be the corresponding staking pool's voting
|
|
1233
|
-
/// power.
|
|
1234
|
-
public(friend) fun on_new_epoch(
|
|
1235
|
-
) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
1236
|
-
let validator_set = borrow_global_mut<ValidatorSet>(@aptos_framework);
|
|
1237
|
-
let config = staking_config::get();
|
|
1238
|
-
let validator_perf = borrow_global_mut<ValidatorPerformance>(@aptos_framework);
|
|
1239
|
-
|
|
1240
|
-
// Process pending stake and distribute transaction fees and rewards for each currently active validator.
|
|
1241
|
-
vector::for_each_ref(&validator_set.active_validators, |validator| {
|
|
1242
|
-
let validator: &ValidatorInfo = validator;
|
|
1243
|
-
update_stake_pool(validator_perf, validator.addr, &config);
|
|
1244
|
-
});
|
|
1245
|
-
|
|
1246
|
-
// Process pending stake and distribute transaction fees and rewards for each currently pending_inactive validator
|
|
1247
|
-
// (requested to leave but not removed yet).
|
|
1248
|
-
vector::for_each_ref(&validator_set.pending_inactive, |validator| {
|
|
1249
|
-
let validator: &ValidatorInfo = validator;
|
|
1250
|
-
update_stake_pool(validator_perf, validator.addr, &config);
|
|
1251
|
-
});
|
|
1252
|
-
|
|
1253
|
-
// Activate currently pending_active validators.
|
|
1254
|
-
append(&mut validator_set.active_validators, &mut validator_set.pending_active);
|
|
1255
|
-
|
|
1256
|
-
// Officially deactivate all pending_inactive validators. They will now no longer receive rewards.
|
|
1257
|
-
validator_set.pending_inactive = vector::empty();
|
|
1258
|
-
|
|
1259
|
-
// Update active validator set so that network address/public key change takes effect.
|
|
1260
|
-
// Moreover, recalculate the total voting power, and deactivate the validator whose
|
|
1261
|
-
// voting power is less than the minimum required stake.
|
|
1262
|
-
let next_epoch_validators = vector::empty();
|
|
1263
|
-
let (minimum_stake, _) = staking_config::get_required_stake(&config);
|
|
1264
|
-
let vlen = vector::length(&validator_set.active_validators);
|
|
1265
|
-
let total_voting_power = 0;
|
|
1266
|
-
let i = 0;
|
|
1267
|
-
while ({
|
|
1268
|
-
spec {
|
|
1269
|
-
invariant spec_validators_are_initialized(next_epoch_validators);
|
|
1270
|
-
invariant i <= vlen;
|
|
1271
|
-
};
|
|
1272
|
-
i < vlen
|
|
1273
|
-
}) {
|
|
1274
|
-
let old_validator_info = vector::borrow_mut(&mut validator_set.active_validators, i);
|
|
1275
|
-
let pool_address = old_validator_info.addr;
|
|
1276
|
-
let validator_config = borrow_global_mut<ValidatorConfig>(pool_address);
|
|
1277
|
-
let stake_pool = borrow_global_mut<StakePool>(pool_address);
|
|
1278
|
-
let new_validator_info = generate_validator_info(pool_address, stake_pool, *validator_config);
|
|
1279
|
-
|
|
1280
|
-
// A validator needs at least the min stake required to join the validator set.
|
|
1281
|
-
if (new_validator_info.voting_power >= minimum_stake) {
|
|
1282
|
-
spec {
|
|
1283
|
-
assume total_voting_power + new_validator_info.voting_power <= MAX_U128;
|
|
1284
|
-
};
|
|
1285
|
-
total_voting_power = total_voting_power + (new_validator_info.voting_power as u128);
|
|
1286
|
-
vector::push_back(&mut next_epoch_validators, new_validator_info);
|
|
1287
|
-
};
|
|
1288
|
-
i = i + 1;
|
|
1289
|
-
};
|
|
1290
|
-
|
|
1291
|
-
validator_set.active_validators = next_epoch_validators;
|
|
1292
|
-
validator_set.total_voting_power = total_voting_power;
|
|
1293
|
-
validator_set.total_joining_power = 0;
|
|
1294
|
-
|
|
1295
|
-
// Update validator indices, reset performance scores, and renew lockups.
|
|
1296
|
-
validator_perf.validators = vector::empty();
|
|
1297
|
-
let recurring_lockup_duration_secs = staking_config::get_recurring_lockup_duration(&config);
|
|
1298
|
-
let vlen = vector::length(&validator_set.active_validators);
|
|
1299
|
-
let validator_index = 0;
|
|
1300
|
-
while ({
|
|
1301
|
-
spec {
|
|
1302
|
-
invariant spec_validators_are_initialized(validator_set.active_validators);
|
|
1303
|
-
invariant len(validator_set.pending_active) == 0;
|
|
1304
|
-
invariant len(validator_set.pending_inactive) == 0;
|
|
1305
|
-
invariant 0 <= validator_index && validator_index <= vlen;
|
|
1306
|
-
invariant vlen == len(validator_set.active_validators);
|
|
1307
|
-
invariant forall i in 0..validator_index:
|
|
1308
|
-
global<ValidatorConfig>(validator_set.active_validators[i].addr).validator_index < validator_index;
|
|
1309
|
-
invariant forall i in 0..validator_index:
|
|
1310
|
-
validator_set.active_validators[i].config.validator_index < validator_index;
|
|
1311
|
-
invariant len(validator_perf.validators) == validator_index;
|
|
1312
|
-
};
|
|
1313
|
-
validator_index < vlen
|
|
1314
|
-
}) {
|
|
1315
|
-
let validator_info = vector::borrow_mut(&mut validator_set.active_validators, validator_index);
|
|
1316
|
-
validator_info.config.validator_index = validator_index;
|
|
1317
|
-
let validator_config = borrow_global_mut<ValidatorConfig>(validator_info.addr);
|
|
1318
|
-
validator_config.validator_index = validator_index;
|
|
1319
|
-
|
|
1320
|
-
vector::push_back(&mut validator_perf.validators, IndividualValidatorPerformance {
|
|
1321
|
-
successful_proposals: 0,
|
|
1322
|
-
failed_proposals: 0,
|
|
1323
|
-
});
|
|
1324
|
-
|
|
1325
|
-
// Automatically renew a validator's lockup for validators that will still be in the validator set in the
|
|
1326
|
-
// next epoch.
|
|
1327
|
-
let stake_pool = borrow_global_mut<StakePool>(validator_info.addr);
|
|
1328
|
-
let now_secs = timestamp::now_seconds();
|
|
1329
|
-
let reconfig_start_secs = if (chain_status::is_operating()) {
|
|
1330
|
-
get_reconfig_start_time_secs()
|
|
1331
|
-
} else {
|
|
1332
|
-
now_secs
|
|
1333
|
-
};
|
|
1334
|
-
if (stake_pool.locked_until_secs <= reconfig_start_secs) {
|
|
1335
|
-
spec {
|
|
1336
|
-
assume now_secs + recurring_lockup_duration_secs <= MAX_U64;
|
|
1337
|
-
};
|
|
1338
|
-
stake_pool.locked_until_secs = now_secs + recurring_lockup_duration_secs;
|
|
1339
|
-
};
|
|
1340
|
-
|
|
1341
|
-
validator_index = validator_index + 1;
|
|
1342
|
-
};
|
|
1343
|
-
|
|
1344
|
-
if (features::periodical_reward_rate_decrease_enabled()) {
|
|
1345
|
-
// Update rewards rate after reward distribution.
|
|
1346
|
-
staking_config::calculate_and_save_latest_epoch_rewards_rate();
|
|
1347
|
-
};
|
|
1348
|
-
}
|
|
1349
|
-
|
|
1350
|
-
/// Return the `ValidatorConsensusInfo` of each current validator, sorted by current validator index.
|
|
1351
|
-
public fun cur_validator_consensus_infos(): vector<ValidatorConsensusInfo> acquires ValidatorSet {
|
|
1352
|
-
let validator_set = borrow_global<ValidatorSet>(@aptos_framework);
|
|
1353
|
-
validator_consensus_infos_from_validator_set(validator_set)
|
|
1354
|
-
}
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
public fun next_validator_consensus_infos(): vector<ValidatorConsensusInfo> acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig {
|
|
1358
|
-
// Init.
|
|
1359
|
-
let cur_validator_set = borrow_global<ValidatorSet>(@aptos_framework);
|
|
1360
|
-
let staking_config = staking_config::get();
|
|
1361
|
-
let validator_perf = borrow_global<ValidatorPerformance>(@aptos_framework);
|
|
1362
|
-
let (minimum_stake, _) = staking_config::get_required_stake(&staking_config);
|
|
1363
|
-
let (rewards_rate, rewards_rate_denominator) = staking_config::get_reward_rate(&staking_config);
|
|
1364
|
-
|
|
1365
|
-
// Compute new validator set.
|
|
1366
|
-
let new_active_validators = vector[];
|
|
1367
|
-
let num_new_actives = 0;
|
|
1368
|
-
let candidate_idx = 0;
|
|
1369
|
-
let new_total_power = 0;
|
|
1370
|
-
let num_cur_actives = vector::length(&cur_validator_set.active_validators);
|
|
1371
|
-
let num_cur_pending_actives = vector::length(&cur_validator_set.pending_active);
|
|
1372
|
-
spec {
|
|
1373
|
-
assume num_cur_actives + num_cur_pending_actives <= MAX_U64;
|
|
1374
|
-
};
|
|
1375
|
-
let num_candidates = num_cur_actives + num_cur_pending_actives;
|
|
1376
|
-
while ({
|
|
1377
|
-
spec {
|
|
1378
|
-
invariant candidate_idx <= num_candidates;
|
|
1379
|
-
invariant spec_validators_are_initialized(new_active_validators);
|
|
1380
|
-
invariant len(new_active_validators) == num_new_actives;
|
|
1381
|
-
invariant forall i in 0..len(new_active_validators):
|
|
1382
|
-
new_active_validators[i].config.validator_index == i;
|
|
1383
|
-
invariant num_new_actives <= candidate_idx;
|
|
1384
|
-
invariant spec_validators_are_initialized(new_active_validators);
|
|
1385
|
-
};
|
|
1386
|
-
candidate_idx < num_candidates
|
|
1387
|
-
}) {
|
|
1388
|
-
let candidate_in_current_validator_set = candidate_idx < num_cur_actives;
|
|
1389
|
-
let candidate = if (candidate_idx < num_cur_actives) {
|
|
1390
|
-
vector::borrow(&cur_validator_set.active_validators, candidate_idx)
|
|
1391
|
-
} else {
|
|
1392
|
-
vector::borrow(&cur_validator_set.pending_active, candidate_idx - num_cur_actives)
|
|
1393
|
-
};
|
|
1394
|
-
let stake_pool = borrow_global<StakePool>(candidate.addr);
|
|
1395
|
-
let cur_active = coin::value(&stake_pool.active);
|
|
1396
|
-
let cur_pending_active = coin::value(&stake_pool.pending_active);
|
|
1397
|
-
let cur_pending_inactive = coin::value(&stake_pool.pending_inactive);
|
|
1398
|
-
|
|
1399
|
-
let cur_reward = if (candidate_in_current_validator_set && cur_active > 0) {
|
|
1400
|
-
spec {
|
|
1401
|
-
assert candidate.config.validator_index < len(validator_perf.validators);
|
|
1402
|
-
};
|
|
1403
|
-
let cur_perf = vector::borrow(&validator_perf.validators, candidate.config.validator_index);
|
|
1404
|
-
spec {
|
|
1405
|
-
assume cur_perf.successful_proposals + cur_perf.failed_proposals <= MAX_U64;
|
|
1406
|
-
};
|
|
1407
|
-
calculate_rewards_amount(cur_active, cur_perf.successful_proposals, cur_perf.successful_proposals + cur_perf.failed_proposals, rewards_rate, rewards_rate_denominator)
|
|
1408
|
-
} else {
|
|
1409
|
-
0
|
|
1410
|
-
};
|
|
1411
|
-
|
|
1412
|
-
let cur_fee = 0;
|
|
1413
|
-
if (features::collect_and_distribute_gas_fees()) {
|
|
1414
|
-
let fees_table = &borrow_global<ValidatorFees>(@aptos_framework).fees_table;
|
|
1415
|
-
if (table::contains(fees_table, candidate.addr)) {
|
|
1416
|
-
let fee_coin = table::borrow(fees_table, candidate.addr);
|
|
1417
|
-
cur_fee = coin::value(fee_coin);
|
|
1418
|
-
}
|
|
1419
|
-
};
|
|
1420
|
-
|
|
1421
|
-
let lockup_expired = get_reconfig_start_time_secs() >= stake_pool.locked_until_secs;
|
|
1422
|
-
spec {
|
|
1423
|
-
assume cur_active + cur_pending_active + cur_reward + cur_fee <= MAX_U64;
|
|
1424
|
-
assume cur_active + cur_pending_inactive + cur_pending_active + cur_reward + cur_fee <= MAX_U64;
|
|
1425
|
-
};
|
|
1426
|
-
let new_voting_power =
|
|
1427
|
-
cur_active
|
|
1428
|
-
+ if (lockup_expired) { 0 } else { cur_pending_inactive }
|
|
1429
|
-
+ cur_pending_active
|
|
1430
|
-
+ cur_reward + cur_fee;
|
|
1431
|
-
|
|
1432
|
-
if (new_voting_power >= minimum_stake) {
|
|
1433
|
-
let config = *borrow_global<ValidatorConfig>(candidate.addr);
|
|
1434
|
-
config.validator_index = num_new_actives;
|
|
1435
|
-
let new_validator_info = ValidatorInfo {
|
|
1436
|
-
addr: candidate.addr,
|
|
1437
|
-
voting_power: new_voting_power,
|
|
1438
|
-
config,
|
|
1439
|
-
};
|
|
1440
|
-
|
|
1441
|
-
// Update ValidatorSet.
|
|
1442
|
-
spec {
|
|
1443
|
-
assume new_total_power + new_voting_power <= MAX_U128;
|
|
1444
|
-
};
|
|
1445
|
-
new_total_power = new_total_power + (new_voting_power as u128);
|
|
1446
|
-
vector::push_back(&mut new_active_validators, new_validator_info);
|
|
1447
|
-
num_new_actives = num_new_actives + 1;
|
|
1448
|
-
|
|
1449
|
-
};
|
|
1450
|
-
candidate_idx = candidate_idx + 1;
|
|
1451
|
-
};
|
|
1452
|
-
|
|
1453
|
-
let new_validator_set = ValidatorSet {
|
|
1454
|
-
consensus_scheme: cur_validator_set.consensus_scheme,
|
|
1455
|
-
active_validators: new_active_validators,
|
|
1456
|
-
pending_inactive: vector[],
|
|
1457
|
-
pending_active: vector[],
|
|
1458
|
-
total_voting_power: new_total_power,
|
|
1459
|
-
total_joining_power: 0,
|
|
1460
|
-
};
|
|
1461
|
-
|
|
1462
|
-
validator_consensus_infos_from_validator_set(&new_validator_set)
|
|
1463
|
-
}
|
|
1464
|
-
|
|
1465
|
-
fun validator_consensus_infos_from_validator_set(validator_set: &ValidatorSet): vector<ValidatorConsensusInfo> {
|
|
1466
|
-
let validator_consensus_infos = vector[];
|
|
1467
|
-
|
|
1468
|
-
let num_active = vector::length(&validator_set.active_validators);
|
|
1469
|
-
let num_pending_inactive = vector::length(&validator_set.pending_inactive);
|
|
1470
|
-
spec {
|
|
1471
|
-
assume num_active + num_pending_inactive <= MAX_U64;
|
|
1472
|
-
};
|
|
1473
|
-
let total = num_active + num_pending_inactive;
|
|
1474
|
-
|
|
1475
|
-
// Pre-fill the return value with dummy values.
|
|
1476
|
-
let idx = 0;
|
|
1477
|
-
while ({
|
|
1478
|
-
spec {
|
|
1479
|
-
invariant idx <= len(validator_set.active_validators) + len(validator_set.pending_inactive);
|
|
1480
|
-
invariant len(validator_consensus_infos) == idx;
|
|
1481
|
-
invariant len(validator_consensus_infos) <= len(validator_set.active_validators) + len(validator_set.pending_inactive);
|
|
1482
|
-
};
|
|
1483
|
-
idx < total
|
|
1484
|
-
}) {
|
|
1485
|
-
vector::push_back(&mut validator_consensus_infos, validator_consensus_info::default());
|
|
1486
|
-
idx = idx + 1;
|
|
1487
|
-
};
|
|
1488
|
-
spec {
|
|
1489
|
-
assert len(validator_consensus_infos) == len(validator_set.active_validators) + len(validator_set.pending_inactive);
|
|
1490
|
-
assert spec_validator_indices_are_valid_config(validator_set.active_validators,
|
|
1491
|
-
len(validator_set.active_validators) + len(validator_set.pending_inactive));
|
|
1492
|
-
};
|
|
1493
|
-
|
|
1494
|
-
vector::for_each_ref(&validator_set.active_validators, |obj| {
|
|
1495
|
-
let vi: &ValidatorInfo = obj;
|
|
1496
|
-
spec {
|
|
1497
|
-
assume len(validator_consensus_infos) == len(validator_set.active_validators) + len(validator_set.pending_inactive);
|
|
1498
|
-
assert vi.config.validator_index < len(validator_consensus_infos);
|
|
1499
|
-
};
|
|
1500
|
-
let vci = vector::borrow_mut(&mut validator_consensus_infos, vi.config.validator_index);
|
|
1501
|
-
*vci = validator_consensus_info::new(
|
|
1502
|
-
vi.addr,
|
|
1503
|
-
vi.config.consensus_pubkey,
|
|
1504
|
-
vi.voting_power
|
|
1505
|
-
);
|
|
1506
|
-
spec {
|
|
1507
|
-
assert len(validator_consensus_infos) == len(validator_set.active_validators) + len(validator_set.pending_inactive);
|
|
1508
|
-
};
|
|
1509
|
-
});
|
|
1510
|
-
|
|
1511
|
-
vector::for_each_ref(&validator_set.pending_inactive, |obj| {
|
|
1512
|
-
let vi: &ValidatorInfo = obj;
|
|
1513
|
-
spec {
|
|
1514
|
-
assume len(validator_consensus_infos) == len(validator_set.active_validators) + len(validator_set.pending_inactive);
|
|
1515
|
-
assert vi.config.validator_index < len(validator_consensus_infos);
|
|
1516
|
-
};
|
|
1517
|
-
let vci = vector::borrow_mut(&mut validator_consensus_infos, vi.config.validator_index);
|
|
1518
|
-
*vci = validator_consensus_info::new(
|
|
1519
|
-
vi.addr,
|
|
1520
|
-
vi.config.consensus_pubkey,
|
|
1521
|
-
vi.voting_power
|
|
1522
|
-
);
|
|
1523
|
-
spec {
|
|
1524
|
-
assert len(validator_consensus_infos) == len(validator_set.active_validators) + len(validator_set.pending_inactive);
|
|
1525
|
-
};
|
|
1526
|
-
});
|
|
1527
|
-
|
|
1528
|
-
validator_consensus_infos
|
|
1529
|
-
}
|
|
1530
|
-
|
|
1531
|
-
fun addresses_from_validator_infos(infos: &vector<ValidatorInfo>): vector<address> {
|
|
1532
|
-
vector::map_ref(infos, |obj| {
|
|
1533
|
-
let info: &ValidatorInfo = obj;
|
|
1534
|
-
info.addr
|
|
1535
|
-
})
|
|
1536
|
-
}
|
|
1537
|
-
|
|
1538
|
-
/// Calculate the stake amount of a stake pool for the next epoch.
|
|
1539
|
-
/// Update individual validator's stake pool if `commit == true`.
|
|
1540
|
-
///
|
|
1541
|
-
/// 1. distribute transaction fees to active/pending_inactive delegations
|
|
1542
|
-
/// 2. distribute rewards to active/pending_inactive delegations
|
|
1543
|
-
/// 3. process pending_active, pending_inactive correspondingly
|
|
1544
|
-
/// This function shouldn't abort.
|
|
1545
|
-
fun update_stake_pool(
|
|
1546
|
-
validator_perf: &ValidatorPerformance,
|
|
1547
|
-
pool_address: address,
|
|
1548
|
-
staking_config: &StakingConfig,
|
|
1549
|
-
) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorFees {
|
|
1550
|
-
let stake_pool = borrow_global_mut<StakePool>(pool_address);
|
|
1551
|
-
let validator_config = borrow_global<ValidatorConfig>(pool_address);
|
|
1552
|
-
let cur_validator_perf = vector::borrow(&validator_perf.validators, validator_config.validator_index);
|
|
1553
|
-
let num_successful_proposals = cur_validator_perf.successful_proposals;
|
|
1554
|
-
spec {
|
|
1555
|
-
// The following addition should not overflow because `num_total_proposals` cannot be larger than 86400,
|
|
1556
|
-
// the maximum number of proposals in a day (1 proposal per second).
|
|
1557
|
-
assume cur_validator_perf.successful_proposals + cur_validator_perf.failed_proposals <= MAX_U64;
|
|
1558
|
-
};
|
|
1559
|
-
let num_total_proposals = cur_validator_perf.successful_proposals + cur_validator_perf.failed_proposals;
|
|
1560
|
-
let (rewards_rate, rewards_rate_denominator) = staking_config::get_reward_rate(staking_config);
|
|
1561
|
-
let rewards_active = distribute_rewards(
|
|
1562
|
-
&mut stake_pool.active,
|
|
1563
|
-
num_successful_proposals,
|
|
1564
|
-
num_total_proposals,
|
|
1565
|
-
rewards_rate,
|
|
1566
|
-
rewards_rate_denominator
|
|
1567
|
-
);
|
|
1568
|
-
let rewards_pending_inactive = distribute_rewards(
|
|
1569
|
-
&mut stake_pool.pending_inactive,
|
|
1570
|
-
num_successful_proposals,
|
|
1571
|
-
num_total_proposals,
|
|
1572
|
-
rewards_rate,
|
|
1573
|
-
rewards_rate_denominator
|
|
1574
|
-
);
|
|
1575
|
-
spec {
|
|
1576
|
-
assume rewards_active + rewards_pending_inactive <= MAX_U64;
|
|
1577
|
-
};
|
|
1578
|
-
let rewards_amount = rewards_active + rewards_pending_inactive;
|
|
1579
|
-
// Pending active stake can now be active.
|
|
1580
|
-
coin::merge(&mut stake_pool.active, coin::extract_all(&mut stake_pool.pending_active));
|
|
1581
|
-
|
|
1582
|
-
// Additionally, distribute transaction fees.
|
|
1583
|
-
if (features::collect_and_distribute_gas_fees()) {
|
|
1584
|
-
let fees_table = &mut borrow_global_mut<ValidatorFees>(@aptos_framework).fees_table;
|
|
1585
|
-
if (table::contains(fees_table, pool_address)) {
|
|
1586
|
-
let coin = table::remove(fees_table, pool_address);
|
|
1587
|
-
coin::merge(&mut stake_pool.active, coin);
|
|
1588
|
-
};
|
|
1589
|
-
};
|
|
1590
|
-
|
|
1591
|
-
// Pending inactive stake is only fully unlocked and moved into inactive if the current lockup cycle has expired
|
|
1592
|
-
let current_lockup_expiration = stake_pool.locked_until_secs;
|
|
1593
|
-
if (get_reconfig_start_time_secs() >= current_lockup_expiration) {
|
|
1594
|
-
coin::merge(
|
|
1595
|
-
&mut stake_pool.inactive,
|
|
1596
|
-
coin::extract_all(&mut stake_pool.pending_inactive),
|
|
1597
|
-
);
|
|
1598
|
-
};
|
|
1599
|
-
|
|
1600
|
-
if (std::features::module_event_migration_enabled()) {
|
|
1601
|
-
event::emit(DistributeRewards { pool_address, rewards_amount });
|
|
1602
|
-
};
|
|
1603
|
-
event::emit_event(
|
|
1604
|
-
&mut stake_pool.distribute_rewards_events,
|
|
1605
|
-
DistributeRewardsEvent {
|
|
1606
|
-
pool_address,
|
|
1607
|
-
rewards_amount,
|
|
1608
|
-
},
|
|
1609
|
-
);
|
|
1610
|
-
}
|
|
1611
|
-
|
|
1612
|
-
/// Assuming we are in a middle of a reconfiguration (no matter it is immediate or async), get its start time.
|
|
1613
|
-
fun get_reconfig_start_time_secs(): u64 {
|
|
1614
|
-
if (reconfiguration_state::is_initialized()) {
|
|
1615
|
-
reconfiguration_state::start_time_secs()
|
|
1616
|
-
} else {
|
|
1617
|
-
timestamp::now_seconds()
|
|
1618
|
-
}
|
|
1619
|
-
}
|
|
1620
|
-
|
|
1621
|
-
/// Calculate the rewards amount.
|
|
1622
|
-
fun calculate_rewards_amount(
|
|
1623
|
-
stake_amount: u64,
|
|
1624
|
-
num_successful_proposals: u64,
|
|
1625
|
-
num_total_proposals: u64,
|
|
1626
|
-
rewards_rate: u64,
|
|
1627
|
-
rewards_rate_denominator: u64,
|
|
1628
|
-
): u64 {
|
|
1629
|
-
spec {
|
|
1630
|
-
// The following condition must hold because
|
|
1631
|
-
// (1) num_successful_proposals <= num_total_proposals, and
|
|
1632
|
-
// (2) `num_total_proposals` cannot be larger than 86400, the maximum number of proposals
|
|
1633
|
-
// in a day (1 proposal per second), and `num_total_proposals` is reset to 0 every epoch.
|
|
1634
|
-
assume num_successful_proposals * MAX_REWARDS_RATE <= MAX_U64;
|
|
1635
|
-
};
|
|
1636
|
-
// The rewards amount is equal to (stake amount * rewards rate * performance multiplier).
|
|
1637
|
-
// We do multiplication in u128 before division to avoid the overflow and minimize the rounding error.
|
|
1638
|
-
let rewards_numerator = (stake_amount as u128) * (rewards_rate as u128) * (num_successful_proposals as u128);
|
|
1639
|
-
let rewards_denominator = (rewards_rate_denominator as u128) * (num_total_proposals as u128);
|
|
1640
|
-
if (rewards_denominator > 0) {
|
|
1641
|
-
((rewards_numerator / rewards_denominator) as u64)
|
|
1642
|
-
} else {
|
|
1643
|
-
0
|
|
1644
|
-
}
|
|
1645
|
-
}
|
|
1646
|
-
|
|
1647
|
-
/// Mint rewards corresponding to current epoch's `stake` and `num_successful_votes`.
|
|
1648
|
-
fun distribute_rewards(
|
|
1649
|
-
stake: &mut Coin<AptosCoin>,
|
|
1650
|
-
num_successful_proposals: u64,
|
|
1651
|
-
num_total_proposals: u64,
|
|
1652
|
-
rewards_rate: u64,
|
|
1653
|
-
rewards_rate_denominator: u64,
|
|
1654
|
-
): u64 acquires AptosCoinCapabilities {
|
|
1655
|
-
let stake_amount = coin::value(stake);
|
|
1656
|
-
let rewards_amount = if (stake_amount > 0) {
|
|
1657
|
-
calculate_rewards_amount(
|
|
1658
|
-
stake_amount,
|
|
1659
|
-
num_successful_proposals,
|
|
1660
|
-
num_total_proposals,
|
|
1661
|
-
rewards_rate,
|
|
1662
|
-
rewards_rate_denominator
|
|
1663
|
-
)
|
|
1664
|
-
} else {
|
|
1665
|
-
0
|
|
1666
|
-
};
|
|
1667
|
-
if (rewards_amount > 0) {
|
|
1668
|
-
let mint_cap = &borrow_global<AptosCoinCapabilities>(@aptos_framework).mint_cap;
|
|
1669
|
-
let rewards = coin::mint(rewards_amount, mint_cap);
|
|
1670
|
-
coin::merge(stake, rewards);
|
|
1671
|
-
};
|
|
1672
|
-
rewards_amount
|
|
1673
|
-
}
|
|
1674
|
-
|
|
1675
|
-
fun append<T>(v1: &mut vector<T>, v2: &mut vector<T>) {
|
|
1676
|
-
while (!vector::is_empty(v2)) {
|
|
1677
|
-
vector::push_back(v1, vector::pop_back(v2));
|
|
1678
|
-
}
|
|
1679
|
-
}
|
|
1680
|
-
|
|
1681
|
-
fun find_validator(v: &vector<ValidatorInfo>, addr: address): Option<u64> {
|
|
1682
|
-
let i = 0;
|
|
1683
|
-
let len = vector::length(v);
|
|
1684
|
-
while ({
|
|
1685
|
-
spec {
|
|
1686
|
-
invariant !(exists j in 0..i: v[j].addr == addr);
|
|
1687
|
-
};
|
|
1688
|
-
i < len
|
|
1689
|
-
}) {
|
|
1690
|
-
if (vector::borrow(v, i).addr == addr) {
|
|
1691
|
-
return option::some(i)
|
|
1692
|
-
};
|
|
1693
|
-
i = i + 1;
|
|
1694
|
-
};
|
|
1695
|
-
option::none()
|
|
1696
|
-
}
|
|
1697
|
-
|
|
1698
|
-
fun generate_validator_info(addr: address, stake_pool: &StakePool, config: ValidatorConfig): ValidatorInfo {
|
|
1699
|
-
let voting_power = get_next_epoch_voting_power(stake_pool);
|
|
1700
|
-
ValidatorInfo {
|
|
1701
|
-
addr,
|
|
1702
|
-
voting_power,
|
|
1703
|
-
config,
|
|
1704
|
-
}
|
|
1705
|
-
}
|
|
1706
|
-
|
|
1707
|
-
/// Returns validator's next epoch voting power, including pending_active, active, and pending_inactive stake.
|
|
1708
|
-
fun get_next_epoch_voting_power(stake_pool: &StakePool): u64 {
|
|
1709
|
-
let value_pending_active = coin::value(&stake_pool.pending_active);
|
|
1710
|
-
let value_active = coin::value(&stake_pool.active);
|
|
1711
|
-
let value_pending_inactive = coin::value(&stake_pool.pending_inactive);
|
|
1712
|
-
spec {
|
|
1713
|
-
assume value_pending_active + value_active + value_pending_inactive <= MAX_U64;
|
|
1714
|
-
};
|
|
1715
|
-
value_pending_active + value_active + value_pending_inactive
|
|
1716
|
-
}
|
|
1717
|
-
|
|
1718
|
-
fun update_voting_power_increase(increase_amount: u64) acquires ValidatorSet {
|
|
1719
|
-
let validator_set = borrow_global_mut<ValidatorSet>(@aptos_framework);
|
|
1720
|
-
let voting_power_increase_limit =
|
|
1721
|
-
(staking_config::get_voting_power_increase_limit(&staking_config::get()) as u128);
|
|
1722
|
-
validator_set.total_joining_power = validator_set.total_joining_power + (increase_amount as u128);
|
|
1723
|
-
|
|
1724
|
-
// Only validator voting power increase if the current validator set's voting power > 0.
|
|
1725
|
-
if (validator_set.total_voting_power > 0) {
|
|
1726
|
-
assert!(
|
|
1727
|
-
validator_set.total_joining_power <= validator_set.total_voting_power * voting_power_increase_limit / 100,
|
|
1728
|
-
error::invalid_argument(EVOTING_POWER_INCREASE_EXCEEDS_LIMIT),
|
|
1729
|
-
);
|
|
1730
|
-
}
|
|
1731
|
-
}
|
|
1732
|
-
|
|
1733
|
-
fun assert_stake_pool_exists(pool_address: address) {
|
|
1734
|
-
assert!(stake_pool_exists(pool_address), error::invalid_argument(ESTAKE_POOL_DOES_NOT_EXIST));
|
|
1735
|
-
}
|
|
1736
|
-
|
|
1737
|
-
/// This provides an ACL for Testnet purposes. In testnet, everyone is a whale, a whale can be a validator.
|
|
1738
|
-
/// This allows a testnet to bring additional entities into the validator set without compromising the
|
|
1739
|
-
/// security of the testnet. This will NOT be enabled in Mainnet.
|
|
1740
|
-
struct AllowedValidators has key {
|
|
1741
|
-
accounts: vector<address>,
|
|
1742
|
-
}
|
|
1743
|
-
|
|
1744
|
-
public fun configure_allowed_validators(
|
|
1745
|
-
aptos_framework: &signer,
|
|
1746
|
-
accounts: vector<address>
|
|
1747
|
-
) acquires AllowedValidators {
|
|
1748
|
-
let aptos_framework_address = signer::address_of(aptos_framework);
|
|
1749
|
-
system_addresses::assert_aptos_framework(aptos_framework);
|
|
1750
|
-
if (!exists<AllowedValidators>(aptos_framework_address)) {
|
|
1751
|
-
move_to(aptos_framework, AllowedValidators { accounts });
|
|
1752
|
-
} else {
|
|
1753
|
-
let allowed = borrow_global_mut<AllowedValidators>(aptos_framework_address);
|
|
1754
|
-
allowed.accounts = accounts;
|
|
1755
|
-
}
|
|
1756
|
-
}
|
|
1757
|
-
|
|
1758
|
-
fun is_allowed(account: address): bool acquires AllowedValidators {
|
|
1759
|
-
if (!exists<AllowedValidators>(@aptos_framework)) {
|
|
1760
|
-
true
|
|
1761
|
-
} else {
|
|
1762
|
-
let allowed = borrow_global<AllowedValidators>(@aptos_framework);
|
|
1763
|
-
vector::contains(&allowed.accounts, &account)
|
|
1764
|
-
}
|
|
1765
|
-
}
|
|
1766
|
-
|
|
1767
|
-
fun assert_owner_cap_exists(owner: address) {
|
|
1768
|
-
assert!(exists<OwnerCapability>(owner), error::not_found(EOWNER_CAP_NOT_FOUND));
|
|
1769
|
-
}
|
|
1770
|
-
|
|
1771
|
-
fun assert_reconfig_not_in_progress() {
|
|
1772
|
-
assert!(!reconfiguration_state::is_in_progress(), error::invalid_state(ERECONFIGURATION_IN_PROGRESS));
|
|
1773
|
-
}
|
|
1774
|
-
|
|
1775
|
-
#[test_only]
|
|
1776
|
-
use aptos_framework::aptos_coin;
|
|
1777
|
-
use aptos_std::bls12381::proof_of_possession_from_bytes;
|
|
1778
|
-
use aptos_framework::reconfiguration_state;
|
|
1779
|
-
use aptos_framework::validator_consensus_info;
|
|
1780
|
-
use aptos_framework::validator_consensus_info::ValidatorConsensusInfo;
|
|
1781
|
-
#[test_only]
|
|
1782
|
-
use aptos_std::fixed_point64;
|
|
1783
|
-
|
|
1784
|
-
#[test_only]
|
|
1785
|
-
const EPOCH_DURATION: u64 = 60;
|
|
1786
|
-
|
|
1787
|
-
#[test_only]
|
|
1788
|
-
const LOCKUP_CYCLE_SECONDS: u64 = 3600;
|
|
1789
|
-
|
|
1790
|
-
#[test_only]
|
|
1791
|
-
public fun initialize_for_test(aptos_framework: &signer) {
|
|
1792
|
-
reconfiguration_state::initialize(aptos_framework);
|
|
1793
|
-
initialize_for_test_custom(aptos_framework, 100, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 100, 1000000);
|
|
1794
|
-
}
|
|
1795
|
-
|
|
1796
|
-
#[test_only]
|
|
1797
|
-
public fun join_validator_set_for_test(
|
|
1798
|
-
pk: &bls12381::PublicKey,
|
|
1799
|
-
pop: &bls12381::ProofOfPossession,
|
|
1800
|
-
operator: &signer,
|
|
1801
|
-
pool_address: address,
|
|
1802
|
-
should_end_epoch: bool,
|
|
1803
|
-
) acquires AptosCoinCapabilities, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
1804
|
-
let pk_bytes = bls12381::public_key_to_bytes(pk);
|
|
1805
|
-
let pop_bytes = bls12381::proof_of_possession_to_bytes(pop);
|
|
1806
|
-
rotate_consensus_key(operator, pool_address, pk_bytes, pop_bytes);
|
|
1807
|
-
join_validator_set(operator, pool_address);
|
|
1808
|
-
if (should_end_epoch) {
|
|
1809
|
-
end_epoch();
|
|
1810
|
-
}
|
|
1811
|
-
}
|
|
1812
|
-
|
|
1813
|
-
#[test_only]
|
|
1814
|
-
public fun fast_forward_to_unlock(pool_address: address)
|
|
1815
|
-
acquires AptosCoinCapabilities, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
1816
|
-
let expiration_time = get_lockup_secs(pool_address);
|
|
1817
|
-
timestamp::update_global_time_for_test_secs(expiration_time);
|
|
1818
|
-
end_epoch();
|
|
1819
|
-
}
|
|
1820
|
-
|
|
1821
|
-
// Convenient function for setting up all required stake initializations.
|
|
1822
|
-
#[test_only]
|
|
1823
|
-
public fun initialize_for_test_custom(
|
|
1824
|
-
aptos_framework: &signer,
|
|
1825
|
-
minimum_stake: u64,
|
|
1826
|
-
maximum_stake: u64,
|
|
1827
|
-
recurring_lockup_secs: u64,
|
|
1828
|
-
allow_validator_set_change: bool,
|
|
1829
|
-
rewards_rate_numerator: u64,
|
|
1830
|
-
rewards_rate_denominator: u64,
|
|
1831
|
-
voting_power_increase_limit: u64,
|
|
1832
|
-
) {
|
|
1833
|
-
timestamp::set_time_has_started_for_testing(aptos_framework);
|
|
1834
|
-
reconfiguration_state::initialize(aptos_framework);
|
|
1835
|
-
if (!exists<ValidatorSet>(@aptos_framework)) {
|
|
1836
|
-
initialize(aptos_framework);
|
|
1837
|
-
};
|
|
1838
|
-
staking_config::initialize_for_test(
|
|
1839
|
-
aptos_framework,
|
|
1840
|
-
minimum_stake,
|
|
1841
|
-
maximum_stake,
|
|
1842
|
-
recurring_lockup_secs,
|
|
1843
|
-
allow_validator_set_change,
|
|
1844
|
-
rewards_rate_numerator,
|
|
1845
|
-
rewards_rate_denominator,
|
|
1846
|
-
voting_power_increase_limit,
|
|
1847
|
-
);
|
|
1848
|
-
|
|
1849
|
-
if (!exists<AptosCoinCapabilities>(@aptos_framework)) {
|
|
1850
|
-
let (burn_cap, mint_cap) = aptos_coin::initialize_for_test(aptos_framework);
|
|
1851
|
-
store_aptos_coin_mint_cap(aptos_framework, mint_cap);
|
|
1852
|
-
coin::destroy_burn_cap<AptosCoin>(burn_cap);
|
|
1853
|
-
};
|
|
1854
|
-
}
|
|
1855
|
-
|
|
1856
|
-
// This function assumes the stake module already the capability to mint aptos coins.
|
|
1857
|
-
#[test_only]
|
|
1858
|
-
public fun mint_coins(amount: u64): Coin<AptosCoin> acquires AptosCoinCapabilities {
|
|
1859
|
-
let mint_cap = &borrow_global<AptosCoinCapabilities>(@aptos_framework).mint_cap;
|
|
1860
|
-
coin::mint(amount, mint_cap)
|
|
1861
|
-
}
|
|
1862
|
-
|
|
1863
|
-
#[test_only]
|
|
1864
|
-
public fun mint(account: &signer, amount: u64) acquires AptosCoinCapabilities {
|
|
1865
|
-
coin::register<AptosCoin>(account);
|
|
1866
|
-
coin::deposit(signer::address_of(account), mint_coins(amount));
|
|
1867
|
-
}
|
|
1868
|
-
|
|
1869
|
-
#[test_only]
|
|
1870
|
-
public fun mint_and_add_stake(
|
|
1871
|
-
account: &signer, amount: u64) acquires AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorSet {
|
|
1872
|
-
mint(account, amount);
|
|
1873
|
-
add_stake(account, amount);
|
|
1874
|
-
}
|
|
1875
|
-
|
|
1876
|
-
#[test_only]
|
|
1877
|
-
public fun initialize_test_validator(
|
|
1878
|
-
public_key: &bls12381::PublicKey,
|
|
1879
|
-
proof_of_possession: &bls12381::ProofOfPossession,
|
|
1880
|
-
validator: &signer,
|
|
1881
|
-
amount: u64,
|
|
1882
|
-
should_join_validator_set: bool,
|
|
1883
|
-
should_end_epoch: bool,
|
|
1884
|
-
) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
1885
|
-
let validator_address = signer::address_of(validator);
|
|
1886
|
-
if (!account::exists_at(signer::address_of(validator))) {
|
|
1887
|
-
account::create_account_for_test(validator_address);
|
|
1888
|
-
};
|
|
1889
|
-
|
|
1890
|
-
let pk_bytes = bls12381::public_key_to_bytes(public_key);
|
|
1891
|
-
let pop_bytes = bls12381::proof_of_possession_to_bytes(proof_of_possession);
|
|
1892
|
-
initialize_validator(validator, pk_bytes, pop_bytes, vector::empty(), vector::empty());
|
|
1893
|
-
|
|
1894
|
-
if (amount > 0) {
|
|
1895
|
-
mint_and_add_stake(validator, amount);
|
|
1896
|
-
};
|
|
1897
|
-
|
|
1898
|
-
if (should_join_validator_set) {
|
|
1899
|
-
join_validator_set(validator, validator_address);
|
|
1900
|
-
};
|
|
1901
|
-
if (should_end_epoch) {
|
|
1902
|
-
end_epoch();
|
|
1903
|
-
};
|
|
1904
|
-
}
|
|
1905
|
-
|
|
1906
|
-
#[test_only]
|
|
1907
|
-
public fun create_validator_set(
|
|
1908
|
-
aptos_framework: &signer,
|
|
1909
|
-
active_validator_addresses: vector<address>,
|
|
1910
|
-
public_keys: vector<bls12381::PublicKey>,
|
|
1911
|
-
) {
|
|
1912
|
-
let active_validators = vector::empty<ValidatorInfo>();
|
|
1913
|
-
let i = 0;
|
|
1914
|
-
while (i < vector::length(&active_validator_addresses)) {
|
|
1915
|
-
let validator_address = vector::borrow(&active_validator_addresses, i);
|
|
1916
|
-
let pk = vector::borrow(&public_keys, i);
|
|
1917
|
-
vector::push_back(&mut active_validators, ValidatorInfo {
|
|
1918
|
-
addr: *validator_address,
|
|
1919
|
-
voting_power: 0,
|
|
1920
|
-
config: ValidatorConfig {
|
|
1921
|
-
consensus_pubkey: bls12381::public_key_to_bytes(pk),
|
|
1922
|
-
network_addresses: b"",
|
|
1923
|
-
fullnode_addresses: b"",
|
|
1924
|
-
validator_index: 0,
|
|
1925
|
-
}
|
|
1926
|
-
});
|
|
1927
|
-
i = i + 1;
|
|
1928
|
-
};
|
|
1929
|
-
|
|
1930
|
-
move_to(aptos_framework, ValidatorSet {
|
|
1931
|
-
consensus_scheme: 0,
|
|
1932
|
-
// active validators for the current epoch
|
|
1933
|
-
active_validators,
|
|
1934
|
-
// pending validators to leave in next epoch (still active)
|
|
1935
|
-
pending_inactive: vector::empty<ValidatorInfo>(),
|
|
1936
|
-
// pending validators to join in next epoch
|
|
1937
|
-
pending_active: vector::empty<ValidatorInfo>(),
|
|
1938
|
-
total_voting_power: 0,
|
|
1939
|
-
total_joining_power: 0,
|
|
1940
|
-
});
|
|
1941
|
-
}
|
|
1942
|
-
|
|
1943
|
-
#[test_only]
|
|
1944
|
-
public fun create_stake_pool(
|
|
1945
|
-
account: &signer,
|
|
1946
|
-
active: Coin<AptosCoin>,
|
|
1947
|
-
pending_inactive: Coin<AptosCoin>,
|
|
1948
|
-
locked_until_secs: u64,
|
|
1949
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, ValidatorSet {
|
|
1950
|
-
let account_address = signer::address_of(account);
|
|
1951
|
-
initialize_stake_owner(account, 0, account_address, account_address);
|
|
1952
|
-
let stake_pool = borrow_global_mut<StakePool>(account_address);
|
|
1953
|
-
coin::merge(&mut stake_pool.active, active);
|
|
1954
|
-
coin::merge(&mut stake_pool.pending_inactive, pending_inactive);
|
|
1955
|
-
stake_pool.locked_until_secs = locked_until_secs;
|
|
1956
|
-
}
|
|
1957
|
-
|
|
1958
|
-
// Allows unit tests to set custom validator performances.
|
|
1959
|
-
#[test_only]
|
|
1960
|
-
public fun update_validator_performances_for_test(
|
|
1961
|
-
proposer_index: Option<u64>,
|
|
1962
|
-
failed_proposer_indices: vector<u64>,
|
|
1963
|
-
) acquires ValidatorPerformance {
|
|
1964
|
-
update_performance_statistics(proposer_index, failed_proposer_indices);
|
|
1965
|
-
}
|
|
1966
|
-
|
|
1967
|
-
#[test_only]
|
|
1968
|
-
public fun generate_identity(): (bls12381::SecretKey, bls12381::PublicKey, bls12381::ProofOfPossession) {
|
|
1969
|
-
let (sk, pkpop) = bls12381::generate_keys();
|
|
1970
|
-
let pop = bls12381::generate_proof_of_possession(&sk);
|
|
1971
|
-
let unvalidated_pk = bls12381::public_key_with_pop_to_normal(&pkpop);
|
|
1972
|
-
(sk, unvalidated_pk, pop)
|
|
1973
|
-
}
|
|
1974
|
-
|
|
1975
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
1976
|
-
#[expected_failure(abort_code = 0x10007, location = Self)]
|
|
1977
|
-
public entry fun test_inactive_validator_can_add_stake_if_exceeding_max_allowed(
|
|
1978
|
-
aptos_framework: &signer,
|
|
1979
|
-
validator: &signer,
|
|
1980
|
-
) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
1981
|
-
initialize_for_test(aptos_framework);
|
|
1982
|
-
let (_sk, pk, pop) = generate_identity();
|
|
1983
|
-
initialize_test_validator(&pk, &pop, validator, 100, false, false);
|
|
1984
|
-
|
|
1985
|
-
// Add more stake to exceed max. This should fail.
|
|
1986
|
-
mint_and_add_stake(validator, 9901);
|
|
1987
|
-
}
|
|
1988
|
-
|
|
1989
|
-
#[test(aptos_framework = @0x1, validator_1 = @0x123, validator_2 = @0x234)]
|
|
1990
|
-
#[expected_failure(abort_code = 0x10007, location = Self)]
|
|
1991
|
-
public entry fun test_pending_active_validator_cannot_add_stake_if_exceeding_max_allowed(
|
|
1992
|
-
aptos_framework: &signer,
|
|
1993
|
-
validator_1: &signer,
|
|
1994
|
-
validator_2: &signer,
|
|
1995
|
-
) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
1996
|
-
initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 100000);
|
|
1997
|
-
// Have one validator join the set to ensure the validator set is not empty when main validator joins.
|
|
1998
|
-
let (_sk_1, pk_1, pop_1) = generate_identity();
|
|
1999
|
-
initialize_test_validator(&pk_1, &pop_1, validator_1, 100, true, true);
|
|
2000
|
-
|
|
2001
|
-
// Validator 2 joins validator set but epoch has not ended so validator is in pending_active state.
|
|
2002
|
-
let (_sk_2, pk_2, pop_2) = generate_identity();
|
|
2003
|
-
initialize_test_validator(&pk_2, &pop_2, validator_2, 100, true, false);
|
|
2004
|
-
|
|
2005
|
-
// Add more stake to exceed max. This should fail.
|
|
2006
|
-
mint_and_add_stake(validator_2, 9901);
|
|
2007
|
-
}
|
|
2008
|
-
|
|
2009
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2010
|
-
#[expected_failure(abort_code = 0x10007, location = Self)]
|
|
2011
|
-
public entry fun test_active_validator_cannot_add_stake_if_exceeding_max_allowed(
|
|
2012
|
-
aptos_framework: &signer,
|
|
2013
|
-
validator: &signer,
|
|
2014
|
-
) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2015
|
-
initialize_for_test(aptos_framework);
|
|
2016
|
-
// Validator joins validator set and waits for epoch end so it's in the validator set.
|
|
2017
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2018
|
-
initialize_test_validator(&pk, &pop, validator, 100, true, true);
|
|
2019
|
-
|
|
2020
|
-
// Add more stake to exceed max. This should fail.
|
|
2021
|
-
mint_and_add_stake(validator, 9901);
|
|
2022
|
-
}
|
|
2023
|
-
|
|
2024
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2025
|
-
#[expected_failure(abort_code = 0x10007, location = Self)]
|
|
2026
|
-
public entry fun test_active_validator_with_pending_inactive_stake_cannot_add_stake_if_exceeding_max_allowed(
|
|
2027
|
-
aptos_framework: &signer,
|
|
2028
|
-
validator: &signer,
|
|
2029
|
-
) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2030
|
-
initialize_for_test(aptos_framework);
|
|
2031
|
-
// Validator joins validator set and waits for epoch end so it's in the validator set.
|
|
2032
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2033
|
-
initialize_test_validator(&pk, &pop, validator, 100, true, true);
|
|
2034
|
-
|
|
2035
|
-
// Request to unlock 50 coins, which go to pending_inactive. Validator has 50 remaining in active.
|
|
2036
|
-
unlock(validator, 50);
|
|
2037
|
-
assert_validator_state(signer::address_of(validator), 50, 0, 0, 50, 0);
|
|
2038
|
-
|
|
2039
|
-
// Add 9901 more. Total stake is 50 (active) + 50 (pending_inactive) + 9901 > 10000 so still exceeding max.
|
|
2040
|
-
mint_and_add_stake(validator, 9901);
|
|
2041
|
-
}
|
|
2042
|
-
|
|
2043
|
-
#[test(aptos_framework = @aptos_framework, validator_1 = @0x123, validator_2 = @0x234)]
|
|
2044
|
-
#[expected_failure(abort_code = 0x10007, location = Self)]
|
|
2045
|
-
public entry fun test_pending_inactive_cannot_add_stake_if_exceeding_max_allowed(
|
|
2046
|
-
aptos_framework: &signer,
|
|
2047
|
-
validator_1: &signer,
|
|
2048
|
-
validator_2: &signer,
|
|
2049
|
-
) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2050
|
-
initialize_for_test(aptos_framework);
|
|
2051
|
-
let (_sk_1, pk_1, pop_1) = generate_identity();
|
|
2052
|
-
let (_sk_2, pk_2, pop_2) = generate_identity();
|
|
2053
|
-
initialize_test_validator(&pk_1, &pop_1, validator_1, 100, true, false);
|
|
2054
|
-
initialize_test_validator(&pk_2, &pop_2, validator_2, 100, true, true);
|
|
2055
|
-
|
|
2056
|
-
// Leave validator set so validator is in pending_inactive state.
|
|
2057
|
-
leave_validator_set(validator_1, signer::address_of(validator_1));
|
|
2058
|
-
|
|
2059
|
-
// Add 9901 more. Total stake is 50 (active) + 50 (pending_inactive) + 9901 > 10000 so still exceeding max.
|
|
2060
|
-
mint_and_add_stake(validator_1, 9901);
|
|
2061
|
-
}
|
|
2062
|
-
|
|
2063
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2064
|
-
public entry fun test_end_to_end(
|
|
2065
|
-
aptos_framework: &signer,
|
|
2066
|
-
validator: &signer,
|
|
2067
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2068
|
-
initialize_for_test(aptos_framework);
|
|
2069
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2070
|
-
initialize_test_validator(&pk, &pop, validator, 100, true, true);
|
|
2071
|
-
|
|
2072
|
-
// Validator has a lockup now that they've joined the validator set.
|
|
2073
|
-
let validator_address = signer::address_of(validator);
|
|
2074
|
-
assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS, 1);
|
|
2075
|
-
|
|
2076
|
-
// Validator adds more stake while already being active.
|
|
2077
|
-
// The added stake should go to pending_active to wait for activation when next epoch starts.
|
|
2078
|
-
mint(validator, 900);
|
|
2079
|
-
add_stake(validator, 100);
|
|
2080
|
-
assert!(coin::balance<AptosCoin>(validator_address) == 800, 2);
|
|
2081
|
-
assert_validator_state(validator_address, 100, 0, 100, 0, 0);
|
|
2082
|
-
|
|
2083
|
-
// Pending_active stake is activated in the new epoch.
|
|
2084
|
-
// Rewards of 1 coin are also distributed for the existing active stake of 100 coins.
|
|
2085
|
-
end_epoch();
|
|
2086
|
-
assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_ACTIVE, 3);
|
|
2087
|
-
assert_validator_state(validator_address, 201, 0, 0, 0, 0);
|
|
2088
|
-
|
|
2089
|
-
// Request unlock of 100 coins. These 100 coins are moved to pending_inactive and will be unlocked when the
|
|
2090
|
-
// current lockup expires.
|
|
2091
|
-
unlock(validator, 100);
|
|
2092
|
-
assert_validator_state(validator_address, 101, 0, 0, 100, 0);
|
|
2093
|
-
|
|
2094
|
-
// Enough time has passed so the current lockup cycle should have ended.
|
|
2095
|
-
// The first epoch after the lockup cycle ended should automatically move unlocked (pending_inactive) stake
|
|
2096
|
-
// to inactive.
|
|
2097
|
-
timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS);
|
|
2098
|
-
end_epoch();
|
|
2099
|
-
// Rewards were also minted to pending_inactive, which got all moved to inactive.
|
|
2100
|
-
assert_validator_state(validator_address, 102, 101, 0, 0, 0);
|
|
2101
|
-
// Lockup is renewed and validator is still active.
|
|
2102
|
-
assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_ACTIVE, 4);
|
|
2103
|
-
assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS, 5);
|
|
2104
|
-
|
|
2105
|
-
// Validator withdraws from inactive stake multiple times.
|
|
2106
|
-
withdraw(validator, 50);
|
|
2107
|
-
assert!(coin::balance<AptosCoin>(validator_address) == 850, 6);
|
|
2108
|
-
assert_validator_state(validator_address, 102, 51, 0, 0, 0);
|
|
2109
|
-
withdraw(validator, 51);
|
|
2110
|
-
assert!(coin::balance<AptosCoin>(validator_address) == 901, 7);
|
|
2111
|
-
assert_validator_state(validator_address, 102, 0, 0, 0, 0);
|
|
2112
|
-
|
|
2113
|
-
// Enough time has passed again and the validator's lockup is renewed once more. Validator is still active.
|
|
2114
|
-
timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS);
|
|
2115
|
-
end_epoch();
|
|
2116
|
-
assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_ACTIVE, 8);
|
|
2117
|
-
assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS, 9);
|
|
2118
|
-
}
|
|
2119
|
-
|
|
2120
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2121
|
-
public entry fun test_inactive_validator_with_existing_lockup_join_validator_set(
|
|
2122
|
-
aptos_framework: &signer,
|
|
2123
|
-
validator: &signer,
|
|
2124
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2125
|
-
initialize_for_test(aptos_framework);
|
|
2126
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2127
|
-
initialize_test_validator(&pk, &pop, validator, 100, false, false);
|
|
2128
|
-
|
|
2129
|
-
// Validator sets lockup before even joining the set and lets half of lockup pass by.
|
|
2130
|
-
increase_lockup(validator);
|
|
2131
|
-
timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS / 2);
|
|
2132
|
-
let validator_address = signer::address_of(validator);
|
|
2133
|
-
assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS / 2, 1);
|
|
2134
|
-
|
|
2135
|
-
// Join the validator set with an existing lockup
|
|
2136
|
-
join_validator_set(validator, validator_address);
|
|
2137
|
-
|
|
2138
|
-
// Validator is added to the set but lockup time shouldn't have changed.
|
|
2139
|
-
end_epoch();
|
|
2140
|
-
assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_ACTIVE, 2);
|
|
2141
|
-
assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS / 2 - EPOCH_DURATION, 3);
|
|
2142
|
-
assert_validator_state(validator_address, 100, 0, 0, 0, 0);
|
|
2143
|
-
}
|
|
2144
|
-
|
|
2145
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2146
|
-
#[expected_failure(abort_code = 0x10012, location = Self)]
|
|
2147
|
-
public entry fun test_cannot_reduce_lockup(
|
|
2148
|
-
aptos_framework: &signer,
|
|
2149
|
-
validator: &signer,
|
|
2150
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2151
|
-
initialize_for_test(aptos_framework);
|
|
2152
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2153
|
-
initialize_test_validator(&pk, &pop, validator, 100, false, false);
|
|
2154
|
-
|
|
2155
|
-
// Increase lockup.
|
|
2156
|
-
increase_lockup(validator);
|
|
2157
|
-
// Reduce recurring lockup to 0.
|
|
2158
|
-
staking_config::update_recurring_lockup_duration_secs(aptos_framework, 1);
|
|
2159
|
-
// INcrease lockup should now fail because the new lockup < old lockup.
|
|
2160
|
-
increase_lockup(validator);
|
|
2161
|
-
}
|
|
2162
|
-
|
|
2163
|
-
#[test(aptos_framework = @aptos_framework, validator_1 = @0x123, validator_2 = @0x234)]
|
|
2164
|
-
#[expected_failure(abort_code = 0x1000D, location = Self)]
|
|
2165
|
-
public entry fun test_inactive_validator_cannot_join_if_exceed_increase_limit(
|
|
2166
|
-
aptos_framework: &signer,
|
|
2167
|
-
validator_1: &signer,
|
|
2168
|
-
validator_2: &signer,
|
|
2169
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2170
|
-
// Only 50% voting power increase is allowed in each epoch.
|
|
2171
|
-
initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 50);
|
|
2172
|
-
let (_sk_1, pk_1, pop_1) = generate_identity();
|
|
2173
|
-
let (_sk_2, pk_2, pop_2) = generate_identity();
|
|
2174
|
-
initialize_test_validator(&pk_1, &pop_1, validator_1, 100, false, false);
|
|
2175
|
-
initialize_test_validator(&pk_2, &pop_2, validator_2, 100, false, false);
|
|
2176
|
-
|
|
2177
|
-
// Validator 1 needs to be in the set so validator 2's added stake counts against the limit.
|
|
2178
|
-
join_validator_set(validator_1, signer::address_of(validator_1));
|
|
2179
|
-
end_epoch();
|
|
2180
|
-
|
|
2181
|
-
// Validator 2 joins the validator set but their stake would lead to exceeding the voting power increase limit.
|
|
2182
|
-
// Therefore, this should fail.
|
|
2183
|
-
join_validator_set(validator_2, signer::address_of(validator_2));
|
|
2184
|
-
}
|
|
2185
|
-
|
|
2186
|
-
#[test(aptos_framework = @aptos_framework, validator_1 = @0x123, validator_2 = @0x234)]
|
|
2187
|
-
public entry fun test_pending_active_validator_can_add_more_stake(
|
|
2188
|
-
aptos_framework: &signer,
|
|
2189
|
-
validator_1: &signer,
|
|
2190
|
-
validator_2: &signer,
|
|
2191
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2192
|
-
initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 10000);
|
|
2193
|
-
// Need 1 validator to be in the active validator set so joining limit works.
|
|
2194
|
-
let (_sk_1, pk_1, pop_1) = generate_identity();
|
|
2195
|
-
let (_sk_2, pk_2, pop_2) = generate_identity();
|
|
2196
|
-
initialize_test_validator(&pk_1, &pop_1, validator_1, 100, false, true);
|
|
2197
|
-
initialize_test_validator(&pk_2, &pop_2, validator_2, 100, false, false);
|
|
2198
|
-
|
|
2199
|
-
// Add more stake while still pending_active.
|
|
2200
|
-
let validator_2_address = signer::address_of(validator_2);
|
|
2201
|
-
join_validator_set(validator_2, validator_2_address);
|
|
2202
|
-
assert!(get_validator_state(validator_2_address) == VALIDATOR_STATUS_PENDING_ACTIVE, 0);
|
|
2203
|
-
mint_and_add_stake(validator_2, 100);
|
|
2204
|
-
assert_validator_state(validator_2_address, 200, 0, 0, 0, 0);
|
|
2205
|
-
}
|
|
2206
|
-
|
|
2207
|
-
#[test(aptos_framework = @aptos_framework, validator_1 = @0x123, validator_2 = @0x234)]
|
|
2208
|
-
#[expected_failure(abort_code = 0x1000D, location = Self)]
|
|
2209
|
-
public entry fun test_pending_active_validator_cannot_add_more_stake_than_limit(
|
|
2210
|
-
aptos_framework: &signer,
|
|
2211
|
-
validator_1: &signer,
|
|
2212
|
-
validator_2: &signer,
|
|
2213
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2214
|
-
// 100% voting power increase is allowed in each epoch.
|
|
2215
|
-
initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 100);
|
|
2216
|
-
// Need 1 validator to be in the active validator set so joining limit works.
|
|
2217
|
-
let (_sk_1, pk_1, pop_1) = generate_identity();
|
|
2218
|
-
initialize_test_validator(&pk_1, &pop_1, validator_1, 100, true, true);
|
|
2219
|
-
|
|
2220
|
-
// Validator 2 joins the validator set but epoch has not ended so they're still pending_active.
|
|
2221
|
-
// Current voting power increase is already 100%. This is not failing yet.
|
|
2222
|
-
let (_sk_2, pk_2, pop_2) = generate_identity();
|
|
2223
|
-
initialize_test_validator(&pk_2, &pop_2, validator_2, 100, true, false);
|
|
2224
|
-
|
|
2225
|
-
// Add more stake, which now exceeds the 100% limit. This should fail.
|
|
2226
|
-
mint_and_add_stake(validator_2, 1);
|
|
2227
|
-
}
|
|
2228
|
-
|
|
2229
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2230
|
-
public entry fun test_pending_active_validator_leaves_validator_set(
|
|
2231
|
-
aptos_framework: &signer,
|
|
2232
|
-
validator: &signer,
|
|
2233
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2234
|
-
initialize_for_test(aptos_framework);
|
|
2235
|
-
// Validator joins but epoch hasn't ended, so the validator is still pending_active.
|
|
2236
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2237
|
-
initialize_test_validator(&pk, &pop, validator, 100, true, false);
|
|
2238
|
-
let validator_address = signer::address_of(validator);
|
|
2239
|
-
assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_PENDING_ACTIVE, 0);
|
|
2240
|
-
|
|
2241
|
-
// Check that voting power increase is tracked.
|
|
2242
|
-
assert!(borrow_global<ValidatorSet>(@aptos_framework).total_joining_power == 100, 0);
|
|
2243
|
-
|
|
2244
|
-
// Leave the validator set immediately.
|
|
2245
|
-
leave_validator_set(validator, validator_address);
|
|
2246
|
-
assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_INACTIVE, 1);
|
|
2247
|
-
|
|
2248
|
-
// Check that voting power increase has been decreased when the pending active validator leaves.
|
|
2249
|
-
assert!(borrow_global<ValidatorSet>(@aptos_framework).total_joining_power == 0, 1);
|
|
2250
|
-
}
|
|
2251
|
-
|
|
2252
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2253
|
-
#[expected_failure(abort_code = 0x1000D, location = Self)]
|
|
2254
|
-
public entry fun test_active_validator_cannot_add_more_stake_than_limit_in_multiple_epochs(
|
|
2255
|
-
aptos_framework: &signer,
|
|
2256
|
-
validator: &signer,
|
|
2257
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2258
|
-
// Only 50% voting power increase is allowed in each epoch.
|
|
2259
|
-
initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 50);
|
|
2260
|
-
// Add initial stake and join the validator set.
|
|
2261
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2262
|
-
initialize_test_validator(&pk, &pop, validator, 100, true, true);
|
|
2263
|
-
|
|
2264
|
-
let validator_address = signer::address_of(validator);
|
|
2265
|
-
assert_validator_state(validator_address, 100, 0, 0, 0, 0);
|
|
2266
|
-
end_epoch();
|
|
2267
|
-
assert_validator_state(validator_address, 110, 0, 0, 0, 0);
|
|
2268
|
-
end_epoch();
|
|
2269
|
-
assert_validator_state(validator_address, 121, 0, 0, 0, 0);
|
|
2270
|
-
// Add more than 50% limit. The following line should fail.
|
|
2271
|
-
mint_and_add_stake(validator, 99);
|
|
2272
|
-
}
|
|
2273
|
-
|
|
2274
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2275
|
-
#[expected_failure(abort_code = 0x1000D, location = Self)]
|
|
2276
|
-
public entry fun test_active_validator_cannot_add_more_stake_than_limit(
|
|
2277
|
-
aptos_framework: &signer,
|
|
2278
|
-
validator: &signer,
|
|
2279
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2280
|
-
// Only 50% voting power increase is allowed in each epoch.
|
|
2281
|
-
initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 50);
|
|
2282
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2283
|
-
initialize_test_validator(&pk, &pop, validator, 100, true, true);
|
|
2284
|
-
|
|
2285
|
-
// Add more than 50% limit. This should fail.
|
|
2286
|
-
mint_and_add_stake(validator, 51);
|
|
2287
|
-
}
|
|
2288
|
-
|
|
2289
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2290
|
-
public entry fun test_active_validator_unlock_partial_stake(
|
|
2291
|
-
aptos_framework: &signer,
|
|
2292
|
-
validator: &signer,
|
|
2293
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2294
|
-
// Reward rate = 10%.
|
|
2295
|
-
initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 100);
|
|
2296
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2297
|
-
initialize_test_validator(&pk, &pop, validator, 100, true, true);
|
|
2298
|
-
|
|
2299
|
-
// Unlock half of the coins.
|
|
2300
|
-
let validator_address = signer::address_of(validator);
|
|
2301
|
-
assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS, 1);
|
|
2302
|
-
unlock(validator, 50);
|
|
2303
|
-
assert_validator_state(validator_address, 50, 0, 0, 50, 0);
|
|
2304
|
-
|
|
2305
|
-
// Enough time has passed so the current lockup cycle should have ended.
|
|
2306
|
-
// 50 coins should have unlocked while the remaining 51 (50 + rewards) should stay locked for another cycle.
|
|
2307
|
-
timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS);
|
|
2308
|
-
end_epoch();
|
|
2309
|
-
assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_ACTIVE, 2);
|
|
2310
|
-
// Validator received rewards in both active and pending inactive.
|
|
2311
|
-
assert_validator_state(validator_address, 55, 55, 0, 0, 0);
|
|
2312
|
-
assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS, 3);
|
|
2313
|
-
}
|
|
2314
|
-
|
|
2315
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2316
|
-
public entry fun test_active_validator_can_withdraw_all_stake_and_rewards_at_once(
|
|
2317
|
-
aptos_framework: &signer,
|
|
2318
|
-
validator: &signer,
|
|
2319
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2320
|
-
initialize_for_test(aptos_framework);
|
|
2321
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2322
|
-
initialize_test_validator(&pk, &pop, validator, 100, true, true);
|
|
2323
|
-
let validator_address = signer::address_of(validator);
|
|
2324
|
-
assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS, 0);
|
|
2325
|
-
|
|
2326
|
-
// One more epoch passes to generate rewards.
|
|
2327
|
-
end_epoch();
|
|
2328
|
-
assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_ACTIVE, 1);
|
|
2329
|
-
assert_validator_state(validator_address, 101, 0, 0, 0, 0);
|
|
2330
|
-
|
|
2331
|
-
// Unlock all coins while still having a lockup.
|
|
2332
|
-
assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS - EPOCH_DURATION, 2);
|
|
2333
|
-
unlock(validator, 101);
|
|
2334
|
-
assert_validator_state(validator_address, 0, 0, 0, 101, 0);
|
|
2335
|
-
|
|
2336
|
-
// One more epoch passes while the current lockup cycle (3600 secs) has not ended.
|
|
2337
|
-
timestamp::fast_forward_seconds(1000);
|
|
2338
|
-
end_epoch();
|
|
2339
|
-
// Validator should not be removed from the validator set since their 100 coins in pending_inactive state should
|
|
2340
|
-
// still count toward voting power.
|
|
2341
|
-
assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_ACTIVE, 3);
|
|
2342
|
-
assert_validator_state(validator_address, 0, 0, 0, 102, 0);
|
|
2343
|
-
|
|
2344
|
-
// Enough time has passed so the current lockup cycle should have ended. Funds are now fully unlocked.
|
|
2345
|
-
timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS);
|
|
2346
|
-
end_epoch();
|
|
2347
|
-
assert_validator_state(validator_address, 0, 103, 0, 0, 0);
|
|
2348
|
-
// Validator ahs been kicked out of the validator set as their stake is 0 now.
|
|
2349
|
-
assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_INACTIVE, 4);
|
|
2350
|
-
}
|
|
2351
|
-
|
|
2352
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2353
|
-
public entry fun test_active_validator_unlocking_more_than_available_stake_should_cap(
|
|
2354
|
-
aptos_framework: &signer,
|
|
2355
|
-
validator: &signer,
|
|
2356
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2357
|
-
initialize_for_test(aptos_framework);
|
|
2358
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2359
|
-
initialize_test_validator(&pk, &pop, validator, 100, false, false);
|
|
2360
|
-
|
|
2361
|
-
// Validator unlocks more stake than they have active. This should limit the unlock to 100.
|
|
2362
|
-
unlock(validator, 200);
|
|
2363
|
-
assert_validator_state(signer::address_of(validator), 0, 0, 0, 100, 0);
|
|
2364
|
-
}
|
|
2365
|
-
|
|
2366
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2367
|
-
public entry fun test_active_validator_withdraw_should_cap_by_inactive_stake(
|
|
2368
|
-
aptos_framework: &signer,
|
|
2369
|
-
validator: &signer,
|
|
2370
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2371
|
-
initialize_for_test(aptos_framework);
|
|
2372
|
-
// Initial balance = 900 (idle) + 100 (staked) = 1000.
|
|
2373
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2374
|
-
initialize_test_validator(&pk, &pop, validator, 100, true, true);
|
|
2375
|
-
mint(validator, 900);
|
|
2376
|
-
|
|
2377
|
-
// Validator unlocks stake.
|
|
2378
|
-
unlock(validator, 100);
|
|
2379
|
-
// Enough time has passed so the stake is fully unlocked.
|
|
2380
|
-
timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS);
|
|
2381
|
-
end_epoch();
|
|
2382
|
-
|
|
2383
|
-
// Validator can only withdraw a max of 100 unlocked coins even if they request to withdraw more than 100.
|
|
2384
|
-
withdraw(validator, 200);
|
|
2385
|
-
let validator_address = signer::address_of(validator);
|
|
2386
|
-
// Receive back all coins with an extra 1 for rewards.
|
|
2387
|
-
assert!(coin::balance<AptosCoin>(validator_address) == 1001, 2);
|
|
2388
|
-
assert_validator_state(validator_address, 0, 0, 0, 0, 0);
|
|
2389
|
-
}
|
|
2390
|
-
|
|
2391
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2392
|
-
public entry fun test_active_validator_can_reactivate_pending_inactive_stake(
|
|
2393
|
-
aptos_framework: &signer,
|
|
2394
|
-
validator: &signer,
|
|
2395
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2396
|
-
initialize_for_test(aptos_framework);
|
|
2397
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2398
|
-
initialize_test_validator(&pk, &pop, validator, 100, true, true);
|
|
2399
|
-
|
|
2400
|
-
// Validator unlocks stake, which gets moved into pending_inactive.
|
|
2401
|
-
unlock(validator, 50);
|
|
2402
|
-
let validator_address = signer::address_of(validator);
|
|
2403
|
-
assert_validator_state(validator_address, 50, 0, 0, 50, 0);
|
|
2404
|
-
|
|
2405
|
-
// Validator can reactivate pending_inactive stake.
|
|
2406
|
-
reactivate_stake(validator, 50);
|
|
2407
|
-
assert_validator_state(validator_address, 100, 0, 0, 0, 0);
|
|
2408
|
-
}
|
|
2409
|
-
|
|
2410
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2411
|
-
public entry fun test_active_validator_reactivate_more_than_available_pending_inactive_stake_should_cap(
|
|
2412
|
-
aptos_framework: &signer,
|
|
2413
|
-
validator: &signer,
|
|
2414
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2415
|
-
initialize_for_test(aptos_framework);
|
|
2416
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2417
|
-
initialize_test_validator(&pk, &pop, validator, 100, true, true);
|
|
2418
|
-
|
|
2419
|
-
// Validator tries to reactivate more than available pending_inactive stake, which should limit to 50.
|
|
2420
|
-
unlock(validator, 50);
|
|
2421
|
-
let validator_address = signer::address_of(validator);
|
|
2422
|
-
assert_validator_state(validator_address, 50, 0, 0, 50, 0);
|
|
2423
|
-
reactivate_stake(validator, 51);
|
|
2424
|
-
assert_validator_state(validator_address, 100, 0, 0, 0, 0);
|
|
2425
|
-
}
|
|
2426
|
-
|
|
2427
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2428
|
-
public entry fun test_active_validator_having_insufficient_remaining_stake_after_withdrawal_gets_kicked(
|
|
2429
|
-
aptos_framework: &signer,
|
|
2430
|
-
validator: &signer,
|
|
2431
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2432
|
-
initialize_for_test(aptos_framework);
|
|
2433
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2434
|
-
initialize_test_validator(&pk, &pop, validator, 100, true, true);
|
|
2435
|
-
|
|
2436
|
-
// Unlock enough coins that the remaining is not enough to meet the min required.
|
|
2437
|
-
let validator_address = signer::address_of(validator);
|
|
2438
|
-
assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS, 1);
|
|
2439
|
-
unlock(validator, 50);
|
|
2440
|
-
assert_validator_state(validator_address, 50, 0, 0, 50, 0);
|
|
2441
|
-
|
|
2442
|
-
// Enough time has passed so the current lockup cycle should have ended.
|
|
2443
|
-
// 50 coins should have unlocked while the remaining 51 (50 + rewards) is not enough so the validator is kicked
|
|
2444
|
-
// from the validator set.
|
|
2445
|
-
assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_ACTIVE, 2);
|
|
2446
|
-
timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS);
|
|
2447
|
-
end_epoch();
|
|
2448
|
-
assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_INACTIVE, 2);
|
|
2449
|
-
assert_validator_state(validator_address, 50, 50, 0, 0, 0);
|
|
2450
|
-
// Lockup is no longer renewed since the validator is no longer a part of the validator set.
|
|
2451
|
-
assert!(get_remaining_lockup_secs(validator_address) == 0, 3);
|
|
2452
|
-
}
|
|
2453
|
-
|
|
2454
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123, validator_2 = @0x234)]
|
|
2455
|
-
public entry fun test_active_validator_leaves_staking_but_still_has_a_lockup(
|
|
2456
|
-
aptos_framework: &signer,
|
|
2457
|
-
validator: &signer,
|
|
2458
|
-
validator_2: &signer,
|
|
2459
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2460
|
-
initialize_for_test(aptos_framework);
|
|
2461
|
-
let (_sk_1, pk_1, pop_1) = generate_identity();
|
|
2462
|
-
let (_sk_2, pk_2, pop_2) = generate_identity();
|
|
2463
|
-
initialize_test_validator(&pk_1, &pop_1, validator, 100, true, false);
|
|
2464
|
-
// We need a second validator here just so the first validator can leave.
|
|
2465
|
-
initialize_test_validator(&pk_2, &pop_2, validator_2, 100, true, true);
|
|
2466
|
-
|
|
2467
|
-
// Leave the validator set while still having a lockup.
|
|
2468
|
-
let validator_address = signer::address_of(validator);
|
|
2469
|
-
assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS, 0);
|
|
2470
|
-
leave_validator_set(validator, validator_address);
|
|
2471
|
-
// Validator is in pending_inactive state but is technically still part of the validator set.
|
|
2472
|
-
assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_PENDING_INACTIVE, 2);
|
|
2473
|
-
assert_validator_state(validator_address, 100, 0, 0, 0, 1);
|
|
2474
|
-
end_epoch();
|
|
2475
|
-
|
|
2476
|
-
// Epoch has ended so validator is no longer part of the validator set.
|
|
2477
|
-
assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_INACTIVE, 3);
|
|
2478
|
-
// However, their stake, including rewards, should still subject to the existing lockup.
|
|
2479
|
-
assert_validator_state(validator_address, 101, 0, 0, 0, 1);
|
|
2480
|
-
assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS - EPOCH_DURATION, 4);
|
|
2481
|
-
|
|
2482
|
-
// If they try to unlock, their stake is moved to pending_inactive and would only be withdrawable after the
|
|
2483
|
-
// lockup has expired.
|
|
2484
|
-
unlock(validator, 50);
|
|
2485
|
-
assert_validator_state(validator_address, 51, 0, 0, 50, 1);
|
|
2486
|
-
// A couple of epochs passed but lockup has not expired so the validator's stake remains the same.
|
|
2487
|
-
end_epoch();
|
|
2488
|
-
end_epoch();
|
|
2489
|
-
end_epoch();
|
|
2490
|
-
assert_validator_state(validator_address, 51, 0, 0, 50, 1);
|
|
2491
|
-
// Fast forward enough so the lockup expires. Now the validator can just call withdraw directly to withdraw
|
|
2492
|
-
// pending_inactive stakes.
|
|
2493
|
-
timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS);
|
|
2494
|
-
withdraw(validator, 50);
|
|
2495
|
-
assert_validator_state(validator_address, 51, 0, 0, 0, 1);
|
|
2496
|
-
}
|
|
2497
|
-
|
|
2498
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123, validator_2 = @0x234)]
|
|
2499
|
-
public entry fun test_active_validator_leaves_staking_and_rejoins_with_expired_lockup_should_be_renewed(
|
|
2500
|
-
aptos_framework: &signer,
|
|
2501
|
-
validator: &signer,
|
|
2502
|
-
validator_2: &signer,
|
|
2503
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2504
|
-
initialize_for_test(aptos_framework);
|
|
2505
|
-
let (_sk_1, pk_1, pop_1) = generate_identity();
|
|
2506
|
-
let (_sk_2, pk_2, pop_2) = generate_identity();
|
|
2507
|
-
initialize_test_validator(&pk_1, &pop_1, validator, 100, true, false);
|
|
2508
|
-
// We need a second validator here just so the first validator can leave.
|
|
2509
|
-
initialize_test_validator(&pk_2, &pop_2, validator_2, 100, true, true);
|
|
2510
|
-
|
|
2511
|
-
// Leave the validator set while still having a lockup.
|
|
2512
|
-
let validator_address = signer::address_of(validator);
|
|
2513
|
-
assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS, 0);
|
|
2514
|
-
leave_validator_set(validator, validator_address);
|
|
2515
|
-
end_epoch();
|
|
2516
|
-
|
|
2517
|
-
// Fast forward enough so the lockup expires.
|
|
2518
|
-
timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS);
|
|
2519
|
-
assert!(get_remaining_lockup_secs(validator_address) == 0, 1);
|
|
2520
|
-
|
|
2521
|
-
// Validator rejoins the validator set. Once the current epoch ends, their lockup should be automatically
|
|
2522
|
-
// renewed.
|
|
2523
|
-
join_validator_set(validator, validator_address);
|
|
2524
|
-
end_epoch();
|
|
2525
|
-
assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_ACTIVE, 2);
|
|
2526
|
-
assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS, 2);
|
|
2527
|
-
}
|
|
2528
|
-
|
|
2529
|
-
#[test(aptos_framework = @aptos_framework, validator_1 = @0x123, validator_2 = @0x234)]
|
|
2530
|
-
public entry fun test_pending_inactive_validator_does_not_count_in_increase_limit(
|
|
2531
|
-
aptos_framework: &signer,
|
|
2532
|
-
validator_1: &signer,
|
|
2533
|
-
validator_2: &signer,
|
|
2534
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2535
|
-
// Only 50% voting power increase is allowed in each epoch.
|
|
2536
|
-
initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 50);
|
|
2537
|
-
let (_sk_1, pk_1, pop_1) = generate_identity();
|
|
2538
|
-
let (_sk_2, pk_2, pop_2) = generate_identity();
|
|
2539
|
-
initialize_test_validator(&pk_1, &pop_1, validator_1, 100, true, false);
|
|
2540
|
-
// We need a second validator here just so the first validator can leave.
|
|
2541
|
-
initialize_test_validator(&pk_2, &pop_2, validator_2, 100, true, true);
|
|
2542
|
-
|
|
2543
|
-
// Validator 1 leaves the validator set. Epoch has not ended so they're still pending_inactive.
|
|
2544
|
-
leave_validator_set(validator_1, signer::address_of(validator_1));
|
|
2545
|
-
// Validator 1 adds more stake. This should not succeed as it should not count as a voting power increase.
|
|
2546
|
-
mint_and_add_stake(validator_1, 51);
|
|
2547
|
-
}
|
|
2548
|
-
|
|
2549
|
-
#[test(aptos_framework = @0x1, validator_1 = @0x123, validator_2 = @0x234, validator_3 = @0x345)]
|
|
2550
|
-
public entry fun test_multiple_validators_join_and_leave(
|
|
2551
|
-
aptos_framework: &signer,
|
|
2552
|
-
validator_1: &signer,
|
|
2553
|
-
validator_2: &signer,
|
|
2554
|
-
validator_3: &signer
|
|
2555
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2556
|
-
let validator_1_address = signer::address_of(validator_1);
|
|
2557
|
-
let validator_2_address = signer::address_of(validator_2);
|
|
2558
|
-
let validator_3_address = signer::address_of(validator_3);
|
|
2559
|
-
|
|
2560
|
-
initialize_for_test_custom(aptos_framework, 100, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 100, 100);
|
|
2561
|
-
let (_sk_1, pk_1, pop_1) = generate_identity();
|
|
2562
|
-
let pk_1_bytes = bls12381::public_key_to_bytes(&pk_1);
|
|
2563
|
-
let (_sk_2, pk_2, pop_2) = generate_identity();
|
|
2564
|
-
let (_sk_3, pk_3, pop_3) = generate_identity();
|
|
2565
|
-
initialize_test_validator(&pk_1, &pop_1, validator_1, 100, false, false);
|
|
2566
|
-
initialize_test_validator(&pk_2, &pop_2, validator_2, 100, false, false);
|
|
2567
|
-
initialize_test_validator(&pk_3, &pop_3, validator_3, 100, false, false);
|
|
2568
|
-
|
|
2569
|
-
// Validator 1 and 2 join the validator set.
|
|
2570
|
-
join_validator_set(validator_2, validator_2_address);
|
|
2571
|
-
join_validator_set(validator_1, validator_1_address);
|
|
2572
|
-
end_epoch();
|
|
2573
|
-
assert!(get_validator_state(validator_1_address) == VALIDATOR_STATUS_ACTIVE, 0);
|
|
2574
|
-
assert!(get_validator_state(validator_2_address) == VALIDATOR_STATUS_ACTIVE, 1);
|
|
2575
|
-
|
|
2576
|
-
// Validator indices is the reverse order of the joining order.
|
|
2577
|
-
assert_validator_state(validator_1_address, 100, 0, 0, 0, 0);
|
|
2578
|
-
assert_validator_state(validator_2_address, 100, 0, 0, 0, 1);
|
|
2579
|
-
let validator_set = borrow_global<ValidatorSet>(@aptos_framework);
|
|
2580
|
-
let validator_config_1 = vector::borrow(&validator_set.active_validators, 0);
|
|
2581
|
-
assert!(validator_config_1.addr == validator_1_address, 2);
|
|
2582
|
-
assert!(validator_config_1.config.validator_index == 0, 3);
|
|
2583
|
-
let validator_config_2 = vector::borrow(&validator_set.active_validators, 1);
|
|
2584
|
-
assert!(validator_config_2.addr == validator_2_address, 4);
|
|
2585
|
-
assert!(validator_config_2.config.validator_index == 1, 5);
|
|
2586
|
-
|
|
2587
|
-
// Validator 1 rotates consensus key. Validator 2 leaves. Validator 3 joins.
|
|
2588
|
-
let (_sk_1b, pk_1b, pop_1b) = generate_identity();
|
|
2589
|
-
let pk_1b_bytes = bls12381::public_key_to_bytes(&pk_1b);
|
|
2590
|
-
let pop_1b_bytes = bls12381::proof_of_possession_to_bytes(&pop_1b);
|
|
2591
|
-
rotate_consensus_key(validator_1, validator_1_address, pk_1b_bytes, pop_1b_bytes);
|
|
2592
|
-
leave_validator_set(validator_2, validator_2_address);
|
|
2593
|
-
join_validator_set(validator_3, validator_3_address);
|
|
2594
|
-
// Validator 2 is not effectively removed until next epoch.
|
|
2595
|
-
assert!(get_validator_state(validator_2_address) == VALIDATOR_STATUS_PENDING_INACTIVE, 6);
|
|
2596
|
-
assert!(
|
|
2597
|
-
vector::borrow(
|
|
2598
|
-
&borrow_global<ValidatorSet>(@aptos_framework).pending_inactive,
|
|
2599
|
-
0
|
|
2600
|
-
).addr == validator_2_address,
|
|
2601
|
-
0
|
|
2602
|
-
);
|
|
2603
|
-
// Validator 3 is not effectively added until next epoch.
|
|
2604
|
-
assert!(get_validator_state(validator_3_address) == VALIDATOR_STATUS_PENDING_ACTIVE, 7);
|
|
2605
|
-
assert!(
|
|
2606
|
-
vector::borrow(
|
|
2607
|
-
&borrow_global<ValidatorSet>(@aptos_framework).pending_active,
|
|
2608
|
-
0
|
|
2609
|
-
).addr == validator_3_address,
|
|
2610
|
-
0
|
|
2611
|
-
);
|
|
2612
|
-
assert!(
|
|
2613
|
-
vector::borrow(
|
|
2614
|
-
&borrow_global<ValidatorSet>(@aptos_framework).active_validators,
|
|
2615
|
-
0
|
|
2616
|
-
).config.consensus_pubkey == pk_1_bytes,
|
|
2617
|
-
0
|
|
2618
|
-
);
|
|
2619
|
-
|
|
2620
|
-
// Changes applied after new epoch
|
|
2621
|
-
end_epoch();
|
|
2622
|
-
assert!(get_validator_state(validator_1_address) == VALIDATOR_STATUS_ACTIVE, 8);
|
|
2623
|
-
assert_validator_state(validator_1_address, 101, 0, 0, 0, 0);
|
|
2624
|
-
assert!(get_validator_state(validator_2_address) == VALIDATOR_STATUS_INACTIVE, 9);
|
|
2625
|
-
// The validator index of validator 2 stays the same but this doesn't matter as the next time they rejoin the
|
|
2626
|
-
// validator set, their index will get set correctly.
|
|
2627
|
-
assert_validator_state(validator_2_address, 101, 0, 0, 0, 1);
|
|
2628
|
-
assert!(get_validator_state(validator_3_address) == VALIDATOR_STATUS_ACTIVE, 10);
|
|
2629
|
-
assert_validator_state(validator_3_address, 100, 0, 0, 0, 1);
|
|
2630
|
-
assert!(
|
|
2631
|
-
vector::borrow(
|
|
2632
|
-
&borrow_global<ValidatorSet>(@aptos_framework).active_validators,
|
|
2633
|
-
0
|
|
2634
|
-
).config.consensus_pubkey == pk_1b_bytes,
|
|
2635
|
-
0
|
|
2636
|
-
);
|
|
2637
|
-
|
|
2638
|
-
// Validators without enough stake will be removed.
|
|
2639
|
-
unlock(validator_1, 50);
|
|
2640
|
-
timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS);
|
|
2641
|
-
end_epoch();
|
|
2642
|
-
assert!(get_validator_state(validator_1_address) == VALIDATOR_STATUS_INACTIVE, 11);
|
|
2643
|
-
}
|
|
2644
|
-
|
|
2645
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2646
|
-
public entry fun test_delegated_staking_with_owner_cap(
|
|
2647
|
-
aptos_framework: &signer,
|
|
2648
|
-
validator: &signer,
|
|
2649
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2650
|
-
initialize_for_test_custom(aptos_framework, 100, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 100, 100);
|
|
2651
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2652
|
-
initialize_test_validator(&pk, &pop, validator, 0, false, false);
|
|
2653
|
-
let owner_cap = extract_owner_cap(validator);
|
|
2654
|
-
|
|
2655
|
-
// Add stake when the validator is not yet activated.
|
|
2656
|
-
add_stake_with_cap(&owner_cap, mint_coins(100));
|
|
2657
|
-
let pool_address = signer::address_of(validator);
|
|
2658
|
-
assert_validator_state(pool_address, 100, 0, 0, 0, 0);
|
|
2659
|
-
|
|
2660
|
-
// Join the validator set with enough stake.
|
|
2661
|
-
join_validator_set(validator, pool_address);
|
|
2662
|
-
end_epoch();
|
|
2663
|
-
assert!(get_validator_state(pool_address) == VALIDATOR_STATUS_ACTIVE, 0);
|
|
2664
|
-
|
|
2665
|
-
// Unlock the entire stake.
|
|
2666
|
-
unlock_with_cap(100, &owner_cap);
|
|
2667
|
-
assert_validator_state(pool_address, 0, 0, 0, 100, 0);
|
|
2668
|
-
timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS);
|
|
2669
|
-
end_epoch();
|
|
2670
|
-
|
|
2671
|
-
// Withdraw stake + rewards.
|
|
2672
|
-
assert_validator_state(pool_address, 0, 101, 0, 0, 0);
|
|
2673
|
-
let coins = withdraw_with_cap(&owner_cap, 101);
|
|
2674
|
-
assert!(coin::value(&coins) == 101, 1);
|
|
2675
|
-
assert_validator_state(pool_address, 0, 0, 0, 0, 0);
|
|
2676
|
-
|
|
2677
|
-
// Operator can separately rotate consensus key.
|
|
2678
|
-
let (_sk_new, pk_new, pop_new) = generate_identity();
|
|
2679
|
-
let pk_new_bytes = bls12381::public_key_to_bytes(&pk_new);
|
|
2680
|
-
let pop_new_bytes = bls12381::proof_of_possession_to_bytes(&pop_new);
|
|
2681
|
-
rotate_consensus_key(validator, pool_address, pk_new_bytes, pop_new_bytes);
|
|
2682
|
-
let validator_config = borrow_global<ValidatorConfig>(pool_address);
|
|
2683
|
-
assert!(validator_config.consensus_pubkey == pk_new_bytes, 2);
|
|
2684
|
-
|
|
2685
|
-
// Operator can update network and fullnode addresses.
|
|
2686
|
-
update_network_and_fullnode_addresses(validator, pool_address, b"1", b"2");
|
|
2687
|
-
let validator_config = borrow_global<ValidatorConfig>(pool_address);
|
|
2688
|
-
assert!(validator_config.network_addresses == b"1", 3);
|
|
2689
|
-
assert!(validator_config.fullnode_addresses == b"2", 4);
|
|
2690
|
-
|
|
2691
|
-
// Cleanups.
|
|
2692
|
-
coin::register<AptosCoin>(validator);
|
|
2693
|
-
coin::deposit(pool_address, coins);
|
|
2694
|
-
deposit_owner_cap(validator, owner_cap);
|
|
2695
|
-
}
|
|
2696
|
-
|
|
2697
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2698
|
-
#[expected_failure(abort_code = 0x1000A, location = Self)]
|
|
2699
|
-
public entry fun test_validator_cannot_join_post_genesis(
|
|
2700
|
-
aptos_framework: &signer,
|
|
2701
|
-
validator: &signer,
|
|
2702
|
-
) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2703
|
-
initialize_for_test_custom(aptos_framework, 100, 10000, LOCKUP_CYCLE_SECONDS, false, 1, 100, 100);
|
|
2704
|
-
|
|
2705
|
-
// Joining the validator set should fail as post genesis validator set change is not allowed.
|
|
2706
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2707
|
-
initialize_test_validator(&pk, &pop, validator, 100, true, true);
|
|
2708
|
-
}
|
|
2709
|
-
|
|
2710
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2711
|
-
#[expected_failure(abort_code = 0x1000E, location = Self)]
|
|
2712
|
-
public entry fun test_invalid_pool_address(
|
|
2713
|
-
aptos_framework: &signer,
|
|
2714
|
-
validator: &signer,
|
|
2715
|
-
) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2716
|
-
initialize_for_test(aptos_framework);
|
|
2717
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2718
|
-
initialize_test_validator(&pk, &pop, validator, 100, true, true);
|
|
2719
|
-
join_validator_set(validator, @0x234);
|
|
2720
|
-
}
|
|
2721
|
-
|
|
2722
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2723
|
-
#[expected_failure(abort_code = 0x1000A, location = Self)]
|
|
2724
|
-
public entry fun test_validator_cannot_leave_post_genesis(
|
|
2725
|
-
aptos_framework: &signer,
|
|
2726
|
-
validator: &signer,
|
|
2727
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2728
|
-
initialize_for_test_custom(aptos_framework, 100, 10000, LOCKUP_CYCLE_SECONDS, false, 1, 100, 100);
|
|
2729
|
-
let (_sk, pk, pop) = generate_identity();
|
|
2730
|
-
initialize_test_validator(&pk, &pop, validator, 100, false, false);
|
|
2731
|
-
|
|
2732
|
-
// Bypass the check to join. This is the same function called during Genesis.
|
|
2733
|
-
let validator_address = signer::address_of(validator);
|
|
2734
|
-
join_validator_set_internal(validator, validator_address);
|
|
2735
|
-
end_epoch();
|
|
2736
|
-
|
|
2737
|
-
// Leaving the validator set should fail as post genesis validator set change is not allowed.
|
|
2738
|
-
leave_validator_set(validator, validator_address);
|
|
2739
|
-
}
|
|
2740
|
-
|
|
2741
|
-
#[test(
|
|
2742
|
-
aptos_framework = @aptos_framework,
|
|
2743
|
-
validator_1 = @aptos_framework,
|
|
2744
|
-
validator_2 = @0x2,
|
|
2745
|
-
validator_3 = @0x3,
|
|
2746
|
-
validator_4 = @0x4,
|
|
2747
|
-
validator_5 = @0x5
|
|
2748
|
-
)]
|
|
2749
|
-
fun test_validator_consensus_infos_from_validator_set(
|
|
2750
|
-
aptos_framework: &signer,
|
|
2751
|
-
validator_1: &signer,
|
|
2752
|
-
validator_2: &signer,
|
|
2753
|
-
validator_3: &signer,
|
|
2754
|
-
validator_4: &signer,
|
|
2755
|
-
validator_5: &signer,
|
|
2756
|
-
) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2757
|
-
let v1_addr = signer::address_of(validator_1);
|
|
2758
|
-
let v2_addr = signer::address_of(validator_2);
|
|
2759
|
-
let v3_addr = signer::address_of(validator_3);
|
|
2760
|
-
let v4_addr = signer::address_of(validator_4);
|
|
2761
|
-
let v5_addr = signer::address_of(validator_5);
|
|
2762
|
-
|
|
2763
|
-
initialize_for_test(aptos_framework);
|
|
2764
|
-
|
|
2765
|
-
let (_sk_1, pk_1, pop_1) = generate_identity();
|
|
2766
|
-
let (_sk_2, pk_2, pop_2) = generate_identity();
|
|
2767
|
-
let (_sk_3, pk_3, pop_3) = generate_identity();
|
|
2768
|
-
let (_sk_4, pk_4, pop_4) = generate_identity();
|
|
2769
|
-
let (_sk_5, pk_5, pop_5) = generate_identity();
|
|
2770
|
-
let pk_1_bytes = bls12381::public_key_to_bytes(&pk_1);
|
|
2771
|
-
let pk_3_bytes = bls12381::public_key_to_bytes(&pk_3);
|
|
2772
|
-
let pk_5_bytes = bls12381::public_key_to_bytes(&pk_5);
|
|
2773
|
-
|
|
2774
|
-
initialize_test_validator(&pk_1, &pop_1, validator_1, 101, false, false);
|
|
2775
|
-
initialize_test_validator(&pk_2, &pop_2, validator_2, 102, false, false);
|
|
2776
|
-
initialize_test_validator(&pk_3, &pop_3, validator_3, 103, false, false);
|
|
2777
|
-
initialize_test_validator(&pk_4, &pop_4, validator_4, 104, false, false);
|
|
2778
|
-
initialize_test_validator(&pk_5, &pop_5, validator_5, 105, false, false);
|
|
2779
|
-
|
|
2780
|
-
join_validator_set(validator_3, v3_addr);
|
|
2781
|
-
join_validator_set(validator_1, v1_addr);
|
|
2782
|
-
join_validator_set(validator_5, v5_addr);
|
|
2783
|
-
end_epoch();
|
|
2784
|
-
let vci_vec_0 = validator_consensus_infos_from_validator_set(borrow_global<ValidatorSet>(@aptos_framework));
|
|
2785
|
-
let vci_addrs = vector::map_ref(&vci_vec_0, |obj|{
|
|
2786
|
-
let vci: &ValidatorConsensusInfo = obj;
|
|
2787
|
-
validator_consensus_info::get_addr(vci)
|
|
2788
|
-
});
|
|
2789
|
-
let vci_pks = vector::map_ref(&vci_vec_0, |obj|{
|
|
2790
|
-
let vci: &ValidatorConsensusInfo = obj;
|
|
2791
|
-
validator_consensus_info::get_pk_bytes(vci)
|
|
2792
|
-
});
|
|
2793
|
-
let vci_voting_powers = vector::map_ref(&vci_vec_0, |obj|{
|
|
2794
|
-
let vci: &ValidatorConsensusInfo = obj;
|
|
2795
|
-
validator_consensus_info::get_voting_power(vci)
|
|
2796
|
-
});
|
|
2797
|
-
assert!(vector[@0x5, @aptos_framework, @0x3] == vci_addrs, 1);
|
|
2798
|
-
assert!(vector[pk_5_bytes, pk_1_bytes, pk_3_bytes] == vci_pks, 2);
|
|
2799
|
-
assert!(vector[105, 101, 103] == vci_voting_powers, 3);
|
|
2800
|
-
leave_validator_set(validator_3, v3_addr);
|
|
2801
|
-
let vci_vec_1 = validator_consensus_infos_from_validator_set(borrow_global<ValidatorSet>(@aptos_framework));
|
|
2802
|
-
assert!(vci_vec_0 == vci_vec_1, 11);
|
|
2803
|
-
join_validator_set(validator_2, v2_addr);
|
|
2804
|
-
let vci_vec_2 = validator_consensus_infos_from_validator_set(borrow_global<ValidatorSet>(@aptos_framework));
|
|
2805
|
-
assert!(vci_vec_0 == vci_vec_2, 12);
|
|
2806
|
-
leave_validator_set(validator_1, v1_addr);
|
|
2807
|
-
let vci_vec_3 = validator_consensus_infos_from_validator_set(borrow_global<ValidatorSet>(@aptos_framework));
|
|
2808
|
-
assert!(vci_vec_0 == vci_vec_3, 13);
|
|
2809
|
-
join_validator_set(validator_4, v4_addr);
|
|
2810
|
-
let vci_vec_4 = validator_consensus_infos_from_validator_set(borrow_global<ValidatorSet>(@aptos_framework));
|
|
2811
|
-
assert!(vci_vec_0 == vci_vec_4, 14);
|
|
2812
|
-
}
|
|
2813
|
-
|
|
2814
|
-
#[test(
|
|
2815
|
-
aptos_framework = @aptos_framework,
|
|
2816
|
-
validator_1 = @aptos_framework,
|
|
2817
|
-
validator_2 = @0x2,
|
|
2818
|
-
validator_3 = @0x3,
|
|
2819
|
-
validator_4 = @0x4,
|
|
2820
|
-
validator_5 = @0x5
|
|
2821
|
-
)]
|
|
2822
|
-
public entry fun test_staking_validator_index(
|
|
2823
|
-
aptos_framework: &signer,
|
|
2824
|
-
validator_1: &signer,
|
|
2825
|
-
validator_2: &signer,
|
|
2826
|
-
validator_3: &signer,
|
|
2827
|
-
validator_4: &signer,
|
|
2828
|
-
validator_5: &signer,
|
|
2829
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2830
|
-
let v1_addr = signer::address_of(validator_1);
|
|
2831
|
-
let v2_addr = signer::address_of(validator_2);
|
|
2832
|
-
let v3_addr = signer::address_of(validator_3);
|
|
2833
|
-
let v4_addr = signer::address_of(validator_4);
|
|
2834
|
-
let v5_addr = signer::address_of(validator_5);
|
|
2835
|
-
|
|
2836
|
-
initialize_for_test(aptos_framework);
|
|
2837
|
-
|
|
2838
|
-
let (_sk_1, pk_1, pop_1) = generate_identity();
|
|
2839
|
-
let (_sk_2, pk_2, pop_2) = generate_identity();
|
|
2840
|
-
let (_sk_3, pk_3, pop_3) = generate_identity();
|
|
2841
|
-
let (_sk_4, pk_4, pop_4) = generate_identity();
|
|
2842
|
-
let (_sk_5, pk_5, pop_5) = generate_identity();
|
|
2843
|
-
|
|
2844
|
-
initialize_test_validator(&pk_1, &pop_1, validator_1, 100, false, false);
|
|
2845
|
-
initialize_test_validator(&pk_2, &pop_2, validator_2, 100, false, false);
|
|
2846
|
-
initialize_test_validator(&pk_3, &pop_3, validator_3, 100, false, false);
|
|
2847
|
-
initialize_test_validator(&pk_4, &pop_4, validator_4, 100, false, false);
|
|
2848
|
-
initialize_test_validator(&pk_5, &pop_5, validator_5, 100, false, false);
|
|
2849
|
-
|
|
2850
|
-
join_validator_set(validator_3, v3_addr);
|
|
2851
|
-
end_epoch();
|
|
2852
|
-
assert!(get_validator_index(v3_addr) == 0, 0);
|
|
2853
|
-
|
|
2854
|
-
join_validator_set(validator_4, v4_addr);
|
|
2855
|
-
end_epoch();
|
|
2856
|
-
assert!(get_validator_index(v3_addr) == 0, 1);
|
|
2857
|
-
assert!(get_validator_index(v4_addr) == 1, 2);
|
|
2858
|
-
|
|
2859
|
-
join_validator_set(validator_1, v1_addr);
|
|
2860
|
-
join_validator_set(validator_2, v2_addr);
|
|
2861
|
-
// pending_inactive is appended in reverse order
|
|
2862
|
-
end_epoch();
|
|
2863
|
-
assert!(get_validator_index(v3_addr) == 0, 6);
|
|
2864
|
-
assert!(get_validator_index(v4_addr) == 1, 7);
|
|
2865
|
-
assert!(get_validator_index(v2_addr) == 2, 8);
|
|
2866
|
-
assert!(get_validator_index(v1_addr) == 3, 9);
|
|
2867
|
-
|
|
2868
|
-
join_validator_set(validator_5, v5_addr);
|
|
2869
|
-
end_epoch();
|
|
2870
|
-
assert!(get_validator_index(v3_addr) == 0, 10);
|
|
2871
|
-
assert!(get_validator_index(v4_addr) == 1, 11);
|
|
2872
|
-
assert!(get_validator_index(v2_addr) == 2, 12);
|
|
2873
|
-
assert!(get_validator_index(v1_addr) == 3, 13);
|
|
2874
|
-
assert!(get_validator_index(v5_addr) == 4, 14);
|
|
2875
|
-
|
|
2876
|
-
// after swap remove, it's 3,4,2,5
|
|
2877
|
-
leave_validator_set(validator_1, v1_addr);
|
|
2878
|
-
// after swap remove, it's 5,4,2
|
|
2879
|
-
leave_validator_set(validator_3, v3_addr);
|
|
2880
|
-
end_epoch();
|
|
2881
|
-
|
|
2882
|
-
assert!(get_validator_index(v5_addr) == 0, 15);
|
|
2883
|
-
assert!(get_validator_index(v4_addr) == 1, 16);
|
|
2884
|
-
assert!(get_validator_index(v2_addr) == 2, 17);
|
|
2885
|
-
}
|
|
2886
|
-
|
|
2887
|
-
#[test(aptos_framework = @aptos_framework, validator_1 = @0x123, validator_2 = @0x234)]
|
|
2888
|
-
public entry fun test_validator_rewards_are_performance_based(
|
|
2889
|
-
aptos_framework: &signer,
|
|
2890
|
-
validator_1: &signer,
|
|
2891
|
-
validator_2: &signer,
|
|
2892
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2893
|
-
initialize_for_test(aptos_framework);
|
|
2894
|
-
|
|
2895
|
-
let validator_1_address = signer::address_of(validator_1);
|
|
2896
|
-
let validator_2_address = signer::address_of(validator_2);
|
|
2897
|
-
|
|
2898
|
-
// Both validators join the set.
|
|
2899
|
-
let (_sk_1, pk_1, pop_1) = generate_identity();
|
|
2900
|
-
let (_sk_2, pk_2, pop_2) = generate_identity();
|
|
2901
|
-
initialize_test_validator(&pk_1, &pop_1, validator_1, 100, true, false);
|
|
2902
|
-
initialize_test_validator(&pk_2, &pop_2, validator_2, 100, true, true);
|
|
2903
|
-
|
|
2904
|
-
// Validator 2 failed proposal.
|
|
2905
|
-
let failed_proposer_indices = vector::empty<u64>();
|
|
2906
|
-
let validator_1_index = borrow_global<ValidatorConfig>(validator_1_address).validator_index;
|
|
2907
|
-
let validator_2_index = borrow_global<ValidatorConfig>(validator_2_address).validator_index;
|
|
2908
|
-
vector::push_back(&mut failed_proposer_indices, validator_2_index);
|
|
2909
|
-
let proposer_indices = option::some(validator_1_index);
|
|
2910
|
-
update_performance_statistics(proposer_indices, failed_proposer_indices);
|
|
2911
|
-
end_epoch();
|
|
2912
|
-
|
|
2913
|
-
// Validator 2 received no rewards. Validator 1 didn't fail proposals, so it still receives rewards.
|
|
2914
|
-
assert_validator_state(validator_1_address, 101, 0, 0, 0, 1);
|
|
2915
|
-
assert_validator_state(validator_2_address, 100, 0, 0, 0, 0);
|
|
2916
|
-
|
|
2917
|
-
// Validator 2 decides to leave. Both validators failed proposals.
|
|
2918
|
-
unlock(validator_2, 100);
|
|
2919
|
-
leave_validator_set(validator_2, validator_2_address);
|
|
2920
|
-
let failed_proposer_indices = vector::empty<u64>();
|
|
2921
|
-
let validator_1_index = borrow_global<ValidatorConfig>(validator_1_address).validator_index;
|
|
2922
|
-
let validator_2_index = borrow_global<ValidatorConfig>(validator_2_address).validator_index;
|
|
2923
|
-
vector::push_back(&mut failed_proposer_indices, validator_1_index);
|
|
2924
|
-
vector::push_back(&mut failed_proposer_indices, validator_2_index);
|
|
2925
|
-
update_performance_statistics(option::none(), failed_proposer_indices);
|
|
2926
|
-
// Fast forward so validator 2's stake is fully unlocked.
|
|
2927
|
-
timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS);
|
|
2928
|
-
end_epoch();
|
|
2929
|
-
|
|
2930
|
-
// Validator 1 and 2 received no additional rewards due to failed proposals
|
|
2931
|
-
assert_validator_state(validator_1_address, 101, 0, 0, 0, 0);
|
|
2932
|
-
assert_validator_state(validator_2_address, 0, 100, 0, 0, 0);
|
|
2933
|
-
}
|
|
2934
|
-
|
|
2935
|
-
#[test(aptos_framework = @aptos_framework, validator_1 = @0x123, validator_2 = @0x234)]
|
|
2936
|
-
public entry fun test_validator_rewards_rate_decrease_over_time(
|
|
2937
|
-
aptos_framework: &signer,
|
|
2938
|
-
validator_1: &signer,
|
|
2939
|
-
validator_2: &signer,
|
|
2940
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2941
|
-
initialize_for_test(aptos_framework);
|
|
2942
|
-
|
|
2943
|
-
let genesis_time_in_secs = timestamp::now_seconds();
|
|
2944
|
-
|
|
2945
|
-
let validator_1_address = signer::address_of(validator_1);
|
|
2946
|
-
let validator_2_address = signer::address_of(validator_2);
|
|
2947
|
-
|
|
2948
|
-
// Both validators join the set.
|
|
2949
|
-
let (_sk_1, pk_1, pop_1) = generate_identity();
|
|
2950
|
-
let (_sk_2, pk_2, pop_2) = generate_identity();
|
|
2951
|
-
initialize_test_validator(&pk_1, &pop_1, validator_1, 1000, true, false);
|
|
2952
|
-
initialize_test_validator(&pk_2, &pop_2, validator_2, 10000, true, true);
|
|
2953
|
-
|
|
2954
|
-
// One epoch passed. Validator 1 and validator 2 should receive rewards at rewards rate = 1% every epoch.
|
|
2955
|
-
end_epoch();
|
|
2956
|
-
assert_validator_state(validator_1_address, 1010, 0, 0, 0, 1);
|
|
2957
|
-
assert_validator_state(validator_2_address, 10100, 0, 0, 0, 0);
|
|
2958
|
-
|
|
2959
|
-
// Enable rewards rate decrease. Initially rewards rate is still 1% every epoch. Rewards rate halves every year.
|
|
2960
|
-
let one_year_in_secs: u64 = 31536000;
|
|
2961
|
-
staking_config::initialize_rewards(
|
|
2962
|
-
aptos_framework,
|
|
2963
|
-
fixed_point64::create_from_rational(1, 100),
|
|
2964
|
-
fixed_point64::create_from_rational(3, 1000),
|
|
2965
|
-
one_year_in_secs,
|
|
2966
|
-
genesis_time_in_secs,
|
|
2967
|
-
fixed_point64::create_from_rational(50, 100),
|
|
2968
|
-
);
|
|
2969
|
-
features::change_feature_flags_for_testing(aptos_framework, vector[features::get_periodical_reward_rate_decrease_feature()], vector[]);
|
|
2970
|
-
|
|
2971
|
-
// For some reason, this epoch is very long. It has been 1 year since genesis when the epoch ends.
|
|
2972
|
-
timestamp::fast_forward_seconds(one_year_in_secs - EPOCH_DURATION * 3);
|
|
2973
|
-
end_epoch();
|
|
2974
|
-
// Validator 1 and validator 2 should still receive rewards at rewards rate = 1% every epoch. Rewards rate has halved after this epoch.
|
|
2975
|
-
assert_validator_state(validator_1_address, 1020, 0, 0, 0, 1);
|
|
2976
|
-
assert_validator_state(validator_2_address, 10200, 0, 0, 0, 0);
|
|
2977
|
-
|
|
2978
|
-
// For some reason, this epoch is also very long. One year passed.
|
|
2979
|
-
timestamp::fast_forward_seconds(one_year_in_secs - EPOCH_DURATION);
|
|
2980
|
-
end_epoch();
|
|
2981
|
-
// Validator 1 and validator 2 should still receive rewards at rewards rate = 0.5% every epoch. Rewards rate has halved after this epoch.
|
|
2982
|
-
assert_validator_state(validator_1_address, 1025, 0, 0, 0, 1);
|
|
2983
|
-
assert_validator_state(validator_2_address, 10250, 0, 0, 0, 0);
|
|
2984
|
-
|
|
2985
|
-
end_epoch();
|
|
2986
|
-
// Rewards rate has halved but cannot become lower than min_rewards_rate.
|
|
2987
|
-
// Validator 1 and validator 2 should receive rewards at rewards rate = 0.3% every epoch.
|
|
2988
|
-
assert_validator_state(validator_1_address, 1028, 0, 0, 0, 1);
|
|
2989
|
-
assert_validator_state(validator_2_address, 10280, 0, 0, 0, 0);
|
|
2990
|
-
}
|
|
2991
|
-
|
|
2992
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
2993
|
-
public entry fun test_update_performance_statistics_should_not_fail_due_to_out_of_bounds(
|
|
2994
|
-
aptos_framework: &signer,
|
|
2995
|
-
validator: &signer,
|
|
2996
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
2997
|
-
initialize_for_test(aptos_framework);
|
|
2998
|
-
|
|
2999
|
-
let validator_address = signer::address_of(validator);
|
|
3000
|
-
let (_sk, pk, pop) = generate_identity();
|
|
3001
|
-
initialize_test_validator(&pk, &pop, validator, 100, true, true);
|
|
3002
|
-
|
|
3003
|
-
let valid_validator_index = borrow_global<ValidatorConfig>(validator_address).validator_index;
|
|
3004
|
-
let out_of_bounds_index = valid_validator_index + 100;
|
|
3005
|
-
|
|
3006
|
-
// Invalid validator index in the failed proposers vector should not lead to abort.
|
|
3007
|
-
let failed_proposer_indices = vector::empty<u64>();
|
|
3008
|
-
vector::push_back(&mut failed_proposer_indices, valid_validator_index);
|
|
3009
|
-
vector::push_back(&mut failed_proposer_indices, out_of_bounds_index);
|
|
3010
|
-
update_performance_statistics(option::none(), failed_proposer_indices);
|
|
3011
|
-
end_epoch();
|
|
3012
|
-
|
|
3013
|
-
// Validator received no rewards due to failing to propose.
|
|
3014
|
-
assert_validator_state(validator_address, 100, 0, 0, 0, 0);
|
|
3015
|
-
|
|
3016
|
-
// Invalid validator index in the proposer should not lead to abort.
|
|
3017
|
-
let proposer_index_optional = option::some(out_of_bounds_index);
|
|
3018
|
-
update_performance_statistics(proposer_index_optional, vector::empty<u64>());
|
|
3019
|
-
end_epoch();
|
|
3020
|
-
}
|
|
3021
|
-
|
|
3022
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
3023
|
-
#[expected_failure(abort_code = 0x1000B, location = Self)]
|
|
3024
|
-
public entry fun test_invalid_config(
|
|
3025
|
-
aptos_framework: &signer,
|
|
3026
|
-
validator: &signer,
|
|
3027
|
-
) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorSet {
|
|
3028
|
-
initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 100, 100);
|
|
3029
|
-
|
|
3030
|
-
// Call initialize_stake_owner, which only initializes the stake pool but not validator config.
|
|
3031
|
-
let validator_address = signer::address_of(validator);
|
|
3032
|
-
account::create_account_for_test(validator_address);
|
|
3033
|
-
initialize_stake_owner(validator, 0, validator_address, validator_address);
|
|
3034
|
-
mint_and_add_stake(validator, 100);
|
|
3035
|
-
|
|
3036
|
-
// Join the validator set with enough stake. This should fail because the validator didn't initialize validator
|
|
3037
|
-
// config.
|
|
3038
|
-
join_validator_set(validator, validator_address);
|
|
3039
|
-
}
|
|
3040
|
-
|
|
3041
|
-
#[test(aptos_framework = @aptos_framework, validator = @0x123)]
|
|
3042
|
-
public entry fun test_valid_config(
|
|
3043
|
-
aptos_framework: &signer,
|
|
3044
|
-
validator: &signer,
|
|
3045
|
-
) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorSet {
|
|
3046
|
-
initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 100, 100);
|
|
3047
|
-
|
|
3048
|
-
// Call initialize_stake_owner, which only initializes the stake pool but not validator config.
|
|
3049
|
-
let validator_address = signer::address_of(validator);
|
|
3050
|
-
account::create_account_for_test(validator_address);
|
|
3051
|
-
initialize_stake_owner(validator, 0, validator_address, validator_address);
|
|
3052
|
-
mint_and_add_stake(validator, 100);
|
|
3053
|
-
|
|
3054
|
-
// Initialize validator config.
|
|
3055
|
-
let validator_address = signer::address_of(validator);
|
|
3056
|
-
let (_sk_new, pk_new, pop_new) = generate_identity();
|
|
3057
|
-
let pk_new_bytes = bls12381::public_key_to_bytes(&pk_new);
|
|
3058
|
-
let pop_new_bytes = bls12381::proof_of_possession_to_bytes(&pop_new);
|
|
3059
|
-
rotate_consensus_key(validator, validator_address, pk_new_bytes, pop_new_bytes);
|
|
3060
|
-
|
|
3061
|
-
// Join the validator set with enough stake. This now wouldn't fail since the validator config already exists.
|
|
3062
|
-
join_validator_set(validator, validator_address);
|
|
3063
|
-
}
|
|
3064
|
-
|
|
3065
|
-
#[test]
|
|
3066
|
-
public entry fun test_rewards_calculation() {
|
|
3067
|
-
let stake_amount = 2000;
|
|
3068
|
-
let num_successful_proposals = 199;
|
|
3069
|
-
let num_total_proposals = 200;
|
|
3070
|
-
let rewards_rate = 700;
|
|
3071
|
-
let rewards_rate_denominator = 777;
|
|
3072
|
-
let rewards_amount = calculate_rewards_amount(
|
|
3073
|
-
stake_amount,
|
|
3074
|
-
num_successful_proposals,
|
|
3075
|
-
num_total_proposals,
|
|
3076
|
-
rewards_rate,
|
|
3077
|
-
rewards_rate_denominator
|
|
3078
|
-
);
|
|
3079
|
-
// Consider `amount_imprecise` and `amount_precise` defined as follows:
|
|
3080
|
-
// amount_imprecise = (stake_amount * rewards_rate / rewards_rate_denominator) * num_successful_proposals / num_total_proposals
|
|
3081
|
-
// amount_precise = stake_amount * rewards_rate * num_successful_proposals / (rewards_rate_denominator * num_total_proposals)
|
|
3082
|
-
// Although they are equivalent in the real arithmetic, they are not in the integer arithmetic due to a rounding error.
|
|
3083
|
-
// With the test parameters above, `amount_imprecise` is equal to 1791 because of an unbounded rounding error
|
|
3084
|
-
// while `amount_precise` is equal to 1792. We expect the output of `calculate_rewards_amount` to be 1792.
|
|
3085
|
-
assert!(rewards_amount == 1792, 0);
|
|
3086
|
-
|
|
3087
|
-
let stake_amount = 100000000000000000;
|
|
3088
|
-
let num_successful_proposals = 9999;
|
|
3089
|
-
let num_total_proposals = 10000;
|
|
3090
|
-
let rewards_rate = 3141592;
|
|
3091
|
-
let rewards_rate_denominator = 10000000;
|
|
3092
|
-
// This should not abort due to an arithmetic overflow.
|
|
3093
|
-
let rewards_amount = calculate_rewards_amount(
|
|
3094
|
-
stake_amount,
|
|
3095
|
-
num_successful_proposals,
|
|
3096
|
-
num_total_proposals,
|
|
3097
|
-
rewards_rate,
|
|
3098
|
-
rewards_rate_denominator
|
|
3099
|
-
);
|
|
3100
|
-
assert!(rewards_amount == 31412778408000000, 0);
|
|
3101
|
-
}
|
|
3102
|
-
|
|
3103
|
-
#[test_only]
|
|
3104
|
-
public fun set_validator_perf_at_least_one_block() acquires ValidatorPerformance {
|
|
3105
|
-
let validator_perf = borrow_global_mut<ValidatorPerformance>(@aptos_framework);
|
|
3106
|
-
vector::for_each_mut(&mut validator_perf.validators, |validator|{
|
|
3107
|
-
let validator: &mut IndividualValidatorPerformance = validator;
|
|
3108
|
-
if (validator.successful_proposals + validator.failed_proposals < 1) {
|
|
3109
|
-
validator.successful_proposals = 1;
|
|
3110
|
-
};
|
|
3111
|
-
});
|
|
3112
|
-
}
|
|
3113
|
-
|
|
3114
|
-
#[test(aptos_framework = @0x1, validator_1 = @0x123, validator_2 = @0x234)]
|
|
3115
|
-
public entry fun test_removing_validator_from_active_set(
|
|
3116
|
-
aptos_framework: &signer,
|
|
3117
|
-
validator_1: &signer,
|
|
3118
|
-
validator_2: &signer,
|
|
3119
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
3120
|
-
initialize_for_test(aptos_framework);
|
|
3121
|
-
let (_sk_1, pk_1, pop_1) = generate_identity();
|
|
3122
|
-
let (_sk_2, pk_2, pop_2) = generate_identity();
|
|
3123
|
-
initialize_test_validator(&pk_1, &pop_1, validator_1, 100, true, false);
|
|
3124
|
-
initialize_test_validator(&pk_2, &pop_2, validator_2, 100, true, true);
|
|
3125
|
-
assert!(vector::length(&borrow_global<ValidatorSet>(@aptos_framework).active_validators) == 2, 0);
|
|
3126
|
-
|
|
3127
|
-
// Remove validator 1 from the active validator set. Only validator 2 remains.
|
|
3128
|
-
let validator_to_remove = signer::address_of(validator_1);
|
|
3129
|
-
remove_validators(aptos_framework, &vector[validator_to_remove]);
|
|
3130
|
-
assert!(vector::length(&borrow_global<ValidatorSet>(@aptos_framework).active_validators) == 1, 0);
|
|
3131
|
-
assert!(get_validator_state(validator_to_remove) == VALIDATOR_STATUS_PENDING_INACTIVE, 1);
|
|
3132
|
-
}
|
|
3133
|
-
|
|
3134
|
-
#[test_only]
|
|
3135
|
-
public fun end_epoch(
|
|
3136
|
-
) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
3137
|
-
// Set the number of blocks to 1, to give out rewards to non-failing validators.
|
|
3138
|
-
set_validator_perf_at_least_one_block();
|
|
3139
|
-
timestamp::fast_forward_seconds(EPOCH_DURATION);
|
|
3140
|
-
reconfiguration_state::on_reconfig_start();
|
|
3141
|
-
on_new_epoch();
|
|
3142
|
-
reconfiguration_state::on_reconfig_finish();
|
|
3143
|
-
}
|
|
3144
|
-
|
|
3145
|
-
#[test_only]
|
|
3146
|
-
public fun assert_stake_pool(
|
|
3147
|
-
pool_address: address,
|
|
3148
|
-
active_stake: u64,
|
|
3149
|
-
inactive_stake: u64,
|
|
3150
|
-
pending_active_stake: u64,
|
|
3151
|
-
pending_inactive_stake: u64,
|
|
3152
|
-
) acquires StakePool {
|
|
3153
|
-
let stake_pool = borrow_global<StakePool>(pool_address);
|
|
3154
|
-
let actual_active_stake = coin::value(&stake_pool.active);
|
|
3155
|
-
assert!(actual_active_stake == active_stake, actual_active_stake);
|
|
3156
|
-
let actual_inactive_stake = coin::value(&stake_pool.inactive);
|
|
3157
|
-
assert!(actual_inactive_stake == inactive_stake, actual_inactive_stake);
|
|
3158
|
-
let actual_pending_active_stake = coin::value(&stake_pool.pending_active);
|
|
3159
|
-
assert!(actual_pending_active_stake == pending_active_stake, actual_pending_active_stake);
|
|
3160
|
-
let actual_pending_inactive_stake = coin::value(&stake_pool.pending_inactive);
|
|
3161
|
-
assert!(actual_pending_inactive_stake == pending_inactive_stake, actual_pending_inactive_stake);
|
|
3162
|
-
}
|
|
3163
|
-
|
|
3164
|
-
#[test_only]
|
|
3165
|
-
public fun assert_validator_state(
|
|
3166
|
-
pool_address: address,
|
|
3167
|
-
active_stake: u64,
|
|
3168
|
-
inactive_stake: u64,
|
|
3169
|
-
pending_active_stake: u64,
|
|
3170
|
-
pending_inactive_stake: u64,
|
|
3171
|
-
validator_index: u64,
|
|
3172
|
-
) acquires StakePool, ValidatorConfig {
|
|
3173
|
-
assert_stake_pool(pool_address, active_stake, inactive_stake, pending_active_stake, pending_inactive_stake);
|
|
3174
|
-
let validator_config = borrow_global<ValidatorConfig>(pool_address);
|
|
3175
|
-
assert!(validator_config.validator_index == validator_index, validator_config.validator_index);
|
|
3176
|
-
}
|
|
3177
|
-
|
|
3178
|
-
#[test(aptos_framework = @0x1, validator = @0x123)]
|
|
3179
|
-
public entry fun test_allowed_validators(
|
|
3180
|
-
aptos_framework: &signer,
|
|
3181
|
-
validator: &signer,
|
|
3182
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, ValidatorSet {
|
|
3183
|
-
let addr = signer::address_of(validator);
|
|
3184
|
-
let (burn, mint) = aptos_coin::initialize_for_test(aptos_framework);
|
|
3185
|
-
configure_allowed_validators(aptos_framework, vector[addr]);
|
|
3186
|
-
|
|
3187
|
-
account::create_account_for_test(addr);
|
|
3188
|
-
coin::register<AptosCoin>(validator);
|
|
3189
|
-
initialize_stake_owner(validator, 0, addr, addr);
|
|
3190
|
-
coin::destroy_burn_cap(burn);
|
|
3191
|
-
coin::destroy_mint_cap(mint);
|
|
3192
|
-
}
|
|
3193
|
-
|
|
3194
|
-
#[test(aptos_framework = @0x1, validator = @0x123)]
|
|
3195
|
-
#[expected_failure(abort_code = 0x60011, location = Self)]
|
|
3196
|
-
public entry fun test_not_allowed_validators(
|
|
3197
|
-
aptos_framework: &signer,
|
|
3198
|
-
validator: &signer,
|
|
3199
|
-
) acquires AllowedValidators, OwnerCapability, StakePool, ValidatorSet {
|
|
3200
|
-
configure_allowed_validators(aptos_framework, vector[]);
|
|
3201
|
-
let (burn, mint) = aptos_coin::initialize_for_test(aptos_framework);
|
|
3202
|
-
|
|
3203
|
-
let addr = signer::address_of(validator);
|
|
3204
|
-
account::create_account_for_test(addr);
|
|
3205
|
-
coin::register<AptosCoin>(validator);
|
|
3206
|
-
initialize_stake_owner(validator, 0, addr, addr);
|
|
3207
|
-
coin::destroy_burn_cap(burn);
|
|
3208
|
-
coin::destroy_mint_cap(mint);
|
|
3209
|
-
}
|
|
3210
|
-
|
|
3211
|
-
#[test_only]
|
|
3212
|
-
public fun with_rewards(amount: u64): u64 {
|
|
3213
|
-
let (numerator, denominator) = staking_config::get_reward_rate(&staking_config::get());
|
|
3214
|
-
amount + amount * numerator / denominator
|
|
3215
|
-
}
|
|
3216
|
-
|
|
3217
|
-
#[test_only]
|
|
3218
|
-
public fun get_validator_fee(validator_addr: address): u64 acquires ValidatorFees {
|
|
3219
|
-
let fees_table = &borrow_global<ValidatorFees>(@aptos_framework).fees_table;
|
|
3220
|
-
let coin = table::borrow(fees_table, validator_addr);
|
|
3221
|
-
coin::value(coin)
|
|
3222
|
-
}
|
|
3223
|
-
|
|
3224
|
-
#[test_only]
|
|
3225
|
-
public fun assert_no_fees_for_validator(validator_addr: address) acquires ValidatorFees {
|
|
3226
|
-
let fees_table = &borrow_global<ValidatorFees>(@aptos_framework).fees_table;
|
|
3227
|
-
assert!(!table::contains(fees_table, validator_addr), 0);
|
|
3228
|
-
}
|
|
3229
|
-
|
|
3230
|
-
#[test_only]
|
|
3231
|
-
const COLLECT_AND_DISTRIBUTE_GAS_FEES: u64 = 6;
|
|
3232
|
-
|
|
3233
|
-
#[test(aptos_framework = @0x1, validator_1 = @0x123, validator_2 = @0x234, validator_3 = @0x345)]
|
|
3234
|
-
fun test_distribute_validator_fees(
|
|
3235
|
-
aptos_framework: &signer,
|
|
3236
|
-
validator_1: &signer,
|
|
3237
|
-
validator_2: &signer,
|
|
3238
|
-
validator_3: &signer,
|
|
3239
|
-
) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
|
|
3240
|
-
// Make sure that fees collection and distribution is enabled.
|
|
3241
|
-
features::change_feature_flags_for_testing(aptos_framework, vector[COLLECT_AND_DISTRIBUTE_GAS_FEES], vector[]);
|
|
3242
|
-
assert!(features::collect_and_distribute_gas_fees(), 0);
|
|
3243
|
-
|
|
3244
|
-
// Initialize staking and validator fees table.
|
|
3245
|
-
initialize_for_test(aptos_framework);
|
|
3246
|
-
initialize_validator_fees(aptos_framework);
|
|
3247
|
-
|
|
3248
|
-
let validator_1_address = signer::address_of(validator_1);
|
|
3249
|
-
let validator_2_address = signer::address_of(validator_2);
|
|
3250
|
-
let validator_3_address = signer::address_of(validator_3);
|
|
3251
|
-
|
|
3252
|
-
// Validators join the set and epoch ends.
|
|
3253
|
-
let (_sk_1, pk_1, pop_1) = generate_identity();
|
|
3254
|
-
let (_sk_2, pk_2, pop_2) = generate_identity();
|
|
3255
|
-
let (_sk_3, pk_3, pop_3) = generate_identity();
|
|
3256
|
-
initialize_test_validator(&pk_1, &pop_1, validator_1, 100, true, false);
|
|
3257
|
-
initialize_test_validator(&pk_2, &pop_2, validator_2, 100, true, false);
|
|
3258
|
-
initialize_test_validator(&pk_3, &pop_3, validator_3, 100, true, true);
|
|
3259
|
-
|
|
3260
|
-
// Next, simulate fees collection during three blocks, where proposers are
|
|
3261
|
-
// validators 1, 2, and 1 again.
|
|
3262
|
-
add_transaction_fee(validator_1_address, mint_coins(100));
|
|
3263
|
-
add_transaction_fee(validator_2_address, mint_coins(500));
|
|
3264
|
-
add_transaction_fee(validator_1_address, mint_coins(200));
|
|
3265
|
-
|
|
3266
|
-
// Fess have to be assigned to the right validators, but not
|
|
3267
|
-
// distributed yet.
|
|
3268
|
-
assert!(get_validator_fee(validator_1_address) == 300, 0);
|
|
3269
|
-
assert!(get_validator_fee(validator_2_address) == 500, 0);
|
|
3270
|
-
assert_no_fees_for_validator(validator_3_address);
|
|
3271
|
-
assert_validator_state(validator_1_address, 100, 0, 0, 0, 2);
|
|
3272
|
-
assert_validator_state(validator_2_address, 100, 0, 0, 0, 1);
|
|
3273
|
-
assert_validator_state(validator_3_address, 100, 0, 0, 0, 0);
|
|
3274
|
-
|
|
3275
|
-
end_epoch();
|
|
3276
|
-
|
|
3277
|
-
// Epoch ended. Validators must have recieved their rewards and, most importantly,
|
|
3278
|
-
// their fees.
|
|
3279
|
-
assert_no_fees_for_validator(validator_1_address);
|
|
3280
|
-
assert_no_fees_for_validator(validator_2_address);
|
|
3281
|
-
assert_no_fees_for_validator(validator_3_address);
|
|
3282
|
-
assert_validator_state(validator_1_address, 401, 0, 0, 0, 2);
|
|
3283
|
-
assert_validator_state(validator_2_address, 601, 0, 0, 0, 1);
|
|
3284
|
-
assert_validator_state(validator_3_address, 101, 0, 0, 0, 0);
|
|
3285
|
-
}
|
|
3286
|
-
}
|