From 5a7620bc6800af917fee5f1931a659a55a310623 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Wed, 14 Feb 2024 23:32:31 +0000 Subject: [PATCH 01/70] integrate non-native transaction into execution flow --- .../src/engine_state/engine_config.rs | 24 +- execution_engine/src/engine_state/error.rs | 9 +- .../src/engine_state/execute_request.rs | 376 ++++++++++++-- .../src/engine_state/execution_kind.rs | 194 ++++--- .../src/engine_state/execution_result.rs | 123 +++-- execution_engine/src/engine_state/mod.rs | 476 ++++++++---------- execution_engine/src/execution/error.rs | 6 +- execution_engine/src/execution/executor.rs | 79 +-- execution_engine/src/runtime/externals.rs | 7 +- execution_engine/src/runtime/mint_internal.rs | 6 +- execution_engine/src/runtime/mod.rs | 38 +- execution_engine/src/runtime_context/mod.rs | 52 +- execution_engine/src/runtime_context/tests.rs | 39 +- .../test_support/src/auction.rs | 386 -------------- .../test_support/src/deploy_item_builder.rs | 20 +- .../src/execute_request_builder.rs | 283 ++++++----- .../test_support/src/lib.rs | 10 +- .../test_support/src/transfer.rs | 281 ----------- .../test_support/src/utils.rs | 66 +-- .../test_support/src/wasm_test_builder.rs | 219 +++----- execution_engine_testing/tests/Cargo.toml | 15 - .../tests/benches/auction_bench.rs | 264 ---------- .../tests/benches/transfer_bench.rs | 469 ----------------- execution_engine_testing/tests/bin/README.md | 15 - .../tests/bin/disk_use.rs | 24 - .../tests/src/lmdb_fixture.rs | 2 +- .../src/test/bulk_update_with_scratch_trie.rs | 26 - .../contract_api/account/authorized_keys.rs | 30 +- .../tests/src/test/contract_api/dictionary.rs | 36 +- .../tests/src/test/contract_api/get_arg.rs | 8 +- .../src/test/contract_api/get_call_stack.rs | 22 +- .../tests/src/test/contract_api/get_phase.rs | 4 +- .../contract_api/list_authorization_keys.rs | 4 +- .../contract_api/multisig_authorization.rs | 4 +- .../tests/src/test/contract_api/runtime.rs | 4 +- .../tests/src/test/contract_api/subcall.rs | 22 +- .../tests/src/test/contract_api/transfer.rs | 5 +- .../src/test/contract_api/transfer_cached.rs | 27 +- .../tests/src/test/contract_context.rs | 2 +- .../src/test/deploy/context_association.rs | 4 +- .../src/test/deploy/non_standard_payment.rs | 4 +- .../tests/src/test/deploy/preconditions.rs | 12 +- .../tests/src/test/deploy/receipts.rs | 223 ++++---- .../tests/src/test/deploy/stored_contracts.rs | 75 +-- .../tests/src/test/explorer/faucet.rs | 7 +- .../tests/src/test/gas_counter.rs | 6 +- .../tests/src/test/groups.rs | 76 ++- .../tests/src/test/mod.rs | 1 - .../src/test/private_chain/management.rs | 36 +- .../private_chain/unrestricted_transfers.rs | 12 +- .../tests/src/test/regression/ee_1129.rs | 48 +- .../tests/src/test/regression/ee_1160.rs | 3 - .../tests/src/test/regression/ee_1163.rs | 5 +- .../tests/src/test/regression/ee_1174.rs | 2 - .../tests/src/test/regression/ee_532.rs | 5 +- .../tests/src/test/regression/ee_572.rs | 7 +- .../tests/src/test/regression/ee_597.rs | 6 +- .../tests/src/test/regression/ee_599.rs | 8 +- .../tests/src/test/regression/ee_601.rs | 4 +- .../tests/src/test/regression/ee_771.rs | 4 +- .../tests/src/test/regression/ee_890.rs | 14 +- .../tests/src/test/regression/ee_966.rs | 41 +- .../tests/src/test/regression/gh_1470.rs | 57 +-- .../tests/src/test/regression/gh_1688.rs | 16 +- .../tests/src/test/regression/gh_1902.rs | 16 +- .../tests/src/test/regression/gh_2280.rs | 70 +-- .../tests/src/test/regression/gh_3208.rs | 12 +- .../tests/src/test/regression/gov_42.rs | 5 +- .../tests/src/test/regression/gov_74.rs | 2 - ...host_function_metrics_size_and_gas_cost.rs | 2 +- .../test/regression/regression_20210707.rs | 12 +- .../test/regression/regression_20210924.rs | 23 +- .../test/regression/regression_20220221.rs | 2 - .../test/regression/regression_20220224.rs | 4 +- .../test/regression/regression_20220303.rs | 6 +- .../regression/transforms_must_be_ordered.rs | 3 +- .../tests/src/test/storage_costs.rs | 22 - .../src/test/system_contracts/auction/bids.rs | 80 ++- .../test/system_contracts/auction_bidding.rs | 27 +- .../src/test/system_contracts/genesis.rs | 3 +- .../handle_payment/finalize_payment.rs | 4 +- .../handle_payment/refund_purse.rs | 4 +- .../test/system_contracts/standard_payment.rs | 77 ++- .../src/test/system_contracts/upgrade.rs | 13 +- .../tests/src/test/system_costs.rs | 10 - .../tests/src/test/upgrade.rs | 27 +- .../tests/src/test/wasmless_transfer.rs | 9 +- node/src/components/contract_runtime.rs | 40 +- node/src/components/contract_runtime/error.rs | 11 +- .../components/contract_runtime/operations.rs | 196 +++----- .../components/contract_runtime/rewards.rs | 4 +- node/src/components/contract_runtime/tests.rs | 9 +- node/src/components/contract_runtime/types.rs | 28 +- node/src/components/contract_runtime/utils.rs | 4 +- node/src/components/rpc_server/rpcs/chain.rs | 16 +- .../rpc_server/rpcs/speculative_exec.rs | 27 +- node/src/components/storage.rs | 4 +- node/src/components/storage/tests.rs | 31 +- node/src/components/transaction_acceptor.rs | 10 +- .../components/transaction_acceptor/tests.rs | 8 +- node/src/effect.rs | 11 +- node/src/effect/requests.rs | 5 +- node/src/reactor/main_reactor.rs | 8 +- node/src/reactor/main_reactor/tests.rs | 14 +- node/src/types/appendable_block.rs | 1 - node/src/types/block/meta_block.rs | 34 +- node/src/utils/specimen.rs | 25 +- resources/local/chainspec.toml.in | 6 +- resources/production/chainspec.toml | 6 +- resources/test/rpc_schema.json | 206 +++++--- resources/test/sse_data_schema.json | 64 +-- .../contract/src/contract_api/runtime.rs | 6 +- .../contract/src/contract_api/storage.rs | 5 +- .../test/contract-context/src/main.rs | 2 +- .../test/do-nothing-stored-caller/src/main.rs | 2 +- .../contracts/test/groups/src/main.rs | 3 +- storage/src/data_access_layer.rs | 1 + storage/src/data_access_layer/execute.rs | 123 +++++ storage/src/global_state/state/mod.rs | 3 +- storage/src/system/error.rs | 2 +- storage/src/system/genesis.rs | 25 +- storage/src/system/mint/mint_native.rs | 14 +- storage/src/system/mint/runtime_provider.rs | 2 +- storage/src/system/protocol_upgrade.rs | 34 +- storage/src/tracking_copy/byte_size.rs | 1 + storage/src/tracking_copy/error.rs | 6 +- storage/src/tracking_copy/ext.rs | 2 +- storage/src/tracking_copy/ext_entity.rs | 10 +- storage/src/tracking_copy/mod.rs | 3 + types/benches/bytesrepr_bench.rs | 13 +- types/src/addressable_entity.rs | 217 +++++--- types/src/byte_code.rs | 3 + types/src/chainspec.rs | 4 +- .../vm_config/host_function_costs.rs | 8 +- types/src/cl_value.rs | 4 +- ..._registry.rs => system_entity_registry.rs} | 10 +- types/src/contracts.rs | 5 - types/src/deploy_info.rs | 31 +- types/src/execution/execution_result_v2.rs | 60 +-- types/src/execution/transform_kind.rs | 5 + types/src/gas.rs | 59 ++- types/src/gens.rs | 87 ++-- types/src/key.rs | 218 +++++--- types/src/lib.rs | 18 +- types/src/package.rs | 14 - types/src/stored_value.rs | 102 ++-- types/src/transaction.rs | 28 +- types/src/transaction/deploy.rs | 23 +- .../src/transaction/deploy/deploy_builder.rs | 8 +- .../deploy/executable_deploy_item.rs | 20 +- types/src/transaction/initiator_addr.rs | 12 + types/src/transaction/transaction_header.rs | 8 +- .../transaction_invocation_target.rs | 11 +- types/src/transaction/transaction_v1.rs | 17 + .../transaction/transaction_v1/errors_v1.rs | 25 +- .../transaction_v1/transaction_v1_body.rs | 29 +- .../transaction_v1_body/arg_handling.rs | 185 ++++--- .../transaction_v1/transaction_v1_builder.rs | 25 +- types/src/transaction/transfer_target.rs | 48 ++ types/src/transaction_info.rs | 185 +++++++ types/src/transfer.rs | 141 +++--- .../src/generic/state_tracker.rs | 4 +- utils/global-state-update-gen/src/main.rs | 8 +- ..._registry.rs => system_entity_registry.rs} | 10 +- utils/validation/src/generators.rs | 20 +- 165 files changed, 3288 insertions(+), 4175 deletions(-) delete mode 100644 execution_engine_testing/test_support/src/auction.rs delete mode 100644 execution_engine_testing/test_support/src/transfer.rs delete mode 100644 execution_engine_testing/tests/benches/auction_bench.rs delete mode 100644 execution_engine_testing/tests/benches/transfer_bench.rs delete mode 100644 execution_engine_testing/tests/bin/README.md delete mode 100644 execution_engine_testing/tests/bin/disk_use.rs delete mode 100644 execution_engine_testing/tests/src/test/bulk_update_with_scratch_trie.rs create mode 100644 storage/src/data_access_layer/execute.rs rename types/src/cl_value/{system_contract_registry.rs => system_entity_registry.rs} (87%) create mode 100644 types/src/transaction/transfer_target.rs create mode 100644 types/src/transaction_info.rs rename utils/global-state-update-gen/src/{system_contract_registry.rs => system_entity_registry.rs} (91%) diff --git a/execution_engine/src/engine_state/engine_config.rs b/execution_engine/src/engine_state/engine_config.rs index 88d460e2c8..5682f203f5 100644 --- a/execution_engine/src/engine_state/engine_config.rs +++ b/execution_engine/src/engine_state/engine_config.rs @@ -7,8 +7,8 @@ use num_rational::Ratio; use num_traits::One; use casper_types::{ - account::AccountHash, FeeHandling, PublicKey, RefundHandling, SystemConfig, WasmConfig, - DEFAULT_REFUND_HANDLING, + account::AccountHash, FeeHandling, ProtocolVersion, PublicKey, RefundHandling, SystemConfig, + WasmConfig, DEFAULT_REFUND_HANDLING, }; /// Default value for a maximum query depth configuration option. @@ -43,6 +43,8 @@ pub const DEFAULT_ALLOW_UNRESTRICTED_TRANSFERS: bool = true; pub const DEFAULT_FEE_HANDLING: FeeHandling = FeeHandling::PayToProposer; /// Default compute rewards. pub const DEFAULT_COMPUTE_REWARDS: bool = true; +/// Default protocol version. +pub const DEFAULT_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::V1_0_0; /// The runtime configuration of the execution engine #[derive(Debug, Clone)] @@ -62,6 +64,7 @@ pub struct EngineConfig { max_delegators_per_validator: Option, wasm_config: WasmConfig, system_config: SystemConfig, + protocol_version: ProtocolVersion, /// A private network specifies a list of administrative accounts. pub(crate) administrative_accounts: BTreeSet, /// Auction entrypoints such as "add_bid" or "delegate" are disabled if this flag is set to @@ -99,6 +102,7 @@ impl Default for EngineConfig { refund_handling: DEFAULT_REFUND_HANDLING, fee_handling: DEFAULT_FEE_HANDLING, compute_rewards: DEFAULT_COMPUTE_REWARDS, + protocol_version: DEFAULT_PROTOCOL_VERSION, } } } @@ -123,6 +127,7 @@ impl EngineConfig { max_delegators_per_validator: Option, wasm_config: WasmConfig, system_config: SystemConfig, + protocol_version: ProtocolVersion, ) -> EngineConfig { Self { max_query_depth, @@ -134,6 +139,7 @@ impl EngineConfig { max_delegators_per_validator, wasm_config, system_config, + protocol_version, administrative_accounts: Default::default(), allow_auction_bids: DEFAULT_ALLOW_AUCTION_BIDS, allow_unrestricted_transfers: DEFAULT_ALLOW_UNRESTRICTED_TRANSFERS, @@ -163,6 +169,11 @@ impl EngineConfig { &self.system_config } + /// Returns the current protocol version. + pub fn protocol_version(&self) -> ProtocolVersion { + self.protocol_version + } + /// Returns the minimum delegation amount in motes. pub fn minimum_delegation_amount(&self) -> u64 { self.minimum_delegation_amount @@ -234,6 +245,7 @@ pub struct EngineConfigBuilder { max_delegators_per_validator: Option, wasm_config: Option, system_config: Option, + protocol_version: Option, administrative_accounts: Option>, allow_auction_bids: Option, allow_unrestricted_transfers: Option, @@ -299,6 +311,12 @@ impl EngineConfigBuilder { self } + /// Sets the protocol version. + pub fn with_protocol_version(mut self, protocol_version: ProtocolVersion) -> Self { + self.protocol_version = Some(protocol_version); + self + } + /// Sets the maximum wasm stack height config option. pub fn with_wasm_max_stack_height(mut self, wasm_stack_height: u32) -> Self { let wasm_config = self.wasm_config.get_or_insert_with(WasmConfig::default); @@ -374,6 +392,7 @@ impl EngineConfigBuilder { .unwrap_or(DEFAULT_MINIMUM_DELEGATION_AMOUNT); let wasm_config = self.wasm_config.unwrap_or_default(); let system_config = self.system_config.unwrap_or_default(); + let protocol_version = self.protocol_version.unwrap_or(DEFAULT_PROTOCOL_VERSION); let administrative_accounts = { self.administrative_accounts .unwrap_or_default() @@ -406,6 +425,7 @@ impl EngineConfigBuilder { minimum_delegation_amount, wasm_config, system_config, + protocol_version, administrative_accounts, allow_auction_bids, allow_unrestricted_transfers, diff --git a/execution_engine/src/engine_state/error.rs b/execution_engine/src/engine_state/error.rs index 9c568f4887..bd1dc2eac9 100644 --- a/execution_engine/src/engine_state/error.rs +++ b/execution_engine/src/engine_state/error.rs @@ -74,12 +74,15 @@ pub enum Error { /// Invalid deploy item variant. #[error("Unsupported deploy item variant: {0}")] InvalidDeployItemVariant(String), + /// Empty module bytes cannot be used for custom payment. + #[error("empty module bytes cannot be used for custom payment")] + EmptyCustomPaymentModuleBytes, /// Commit error. #[error(transparent)] CommitError(#[from] CommitError), - /// Missing system contract registry. - #[error("Missing system contract registry")] - MissingSystemContractRegistry, + /// Missing system entity registry. + #[error("Missing system entity registry")] + MissingSystemEntityRegistry, /// Missing system contract hash. #[error("Missing system contract hash: {0}")] MissingSystemContractHash(String), diff --git a/execution_engine/src/engine_state/execute_request.rs b/execution_engine/src/engine_state/execute_request.rs index 4d51122dc1..63351779e1 100644 --- a/execution_engine/src/engine_state/execute_request.rs +++ b/execution_engine/src/engine_state/execute_request.rs @@ -1,65 +1,349 @@ -//! Code supporting an execution request. -use std::mem; +use std::{collections::BTreeSet, convert::TryFrom}; -use casper_types::{Digest, ProtocolVersion, PublicKey, SecretKey}; +use serde::Serialize; +use thiserror::Error; -use super::deploy_item::DeployItem; +use casper_types::{ + account::AccountHash, bytesrepr::Bytes, runtime_args, BlockTime, DeployHash, Digest, + ExecutableDeployItem, InitiatorAddr, PublicKey, RuntimeArgs, Transaction, + TransactionEntryPoint, TransactionHash, TransactionInvocationTarget, TransactionSessionKind, + TransactionTarget, TransactionV1Body, TransactionV1Hash, U512, +}; -/// Represents an execution request that can contain multiple deploys. +const DEFAULT_ENTRY_POINT: &str = "call"; + +/// The payment method for the transaction. +#[derive(Debug)] +pub enum Payment { + /// Standard payment (Wasmless execution). + Standard, + /// A stored entity or package to be executed as custom payment. + Stored(TransactionInvocationTarget), + /// Compiled Wasm as byte code to be executed as custom payment. + ModuleBytes(Bytes), + /// The session from this transaction should be executed as custom payment. + UseSession, +} + +/// The payment-related portion of an `ExecuteRequest`. +pub struct PaymentInfo { + /// The payment item. + pub payment: Payment, + /// The payment entry point. + pub entry_point: String, + /// The payment runtime args. + pub args: RuntimeArgs, +} + +impl TryFrom<(ExecutableDeployItem, DeployHash)> for PaymentInfo { + type Error = NewRequestError; + + fn try_from( + (payment_item, deploy_hash): (ExecutableDeployItem, DeployHash), + ) -> Result { + let payment: Payment; + let payment_entry_point: String; + let payment_args: RuntimeArgs; + match payment_item { + ExecutableDeployItem::ModuleBytes { module_bytes, args } => { + if module_bytes.is_empty() { + payment = Payment::Standard; + } else { + payment = Payment::ModuleBytes(module_bytes); + } + payment_entry_point = DEFAULT_ENTRY_POINT.to_string(); + payment_args = args; + } + ExecutableDeployItem::StoredContractByHash { + hash, + entry_point, + args, + } => { + payment = Payment::Stored(TransactionInvocationTarget::new_invocable_entity(hash)); + payment_entry_point = entry_point; + payment_args = args; + } + ExecutableDeployItem::StoredContractByName { + name, + entry_point, + args, + } => { + payment = Payment::Stored(TransactionInvocationTarget::new_invocable_entity_alias( + name, + )); + payment_entry_point = entry_point; + payment_args = args; + } + ExecutableDeployItem::StoredVersionedContractByHash { + hash, + version, + entry_point, + args, + } => { + payment = Payment::Stored(TransactionInvocationTarget::new_package(hash, version)); + payment_entry_point = entry_point; + payment_args = args; + } + ExecutableDeployItem::StoredVersionedContractByName { + name, + version, + entry_point, + args, + } => { + payment = Payment::Stored(TransactionInvocationTarget::new_package_alias( + name, version, + )); + payment_entry_point = entry_point; + payment_args = args; + } + ExecutableDeployItem::Transfer { .. } => { + return Err(NewRequestError::InvalidPaymentDeployItem(deploy_hash)); + } + } + Ok(PaymentInfo { + payment, + entry_point: payment_entry_point, + args: payment_args, + }) + } +} + +/// The session to be executed. +#[derive(Debug)] +pub enum Session { + /// A stored entity or package. + Stored(TransactionInvocationTarget), + /// Compiled Wasm as byte code. + ModuleBytes { + /// The kind of session. + kind: TransactionSessionKind, + /// The compiled Wasm. + module_bytes: Bytes, + }, +} + +/// The session-related portion of an `ExecuteRequest`. +pub struct SessionInfo { + /// The session item. + pub session: Session, + /// The session entry point. + pub entry_point: String, + /// The session runtime args. + pub args: RuntimeArgs, +} + +impl TryFrom<(ExecutableDeployItem, DeployHash)> for SessionInfo { + type Error = NewRequestError; + + fn try_from( + (session_item, deploy_hash): (ExecutableDeployItem, DeployHash), + ) -> Result { + let session: Session; + let session_entry_point: String; + let session_args: RuntimeArgs; + match session_item { + ExecutableDeployItem::ModuleBytes { module_bytes, args } => { + session = Session::ModuleBytes { + kind: TransactionSessionKind::Standard, + module_bytes, + }; + session_entry_point = DEFAULT_ENTRY_POINT.to_string(); + session_args = args; + } + ExecutableDeployItem::StoredContractByHash { + hash, + entry_point, + args, + } => { + session = Session::Stored(TransactionInvocationTarget::new_invocable_entity(hash)); + session_entry_point = entry_point; + session_args = args; + } + ExecutableDeployItem::StoredContractByName { + name, + entry_point, + args, + } => { + session = Session::Stored(TransactionInvocationTarget::new_invocable_entity_alias( + name, + )); + session_entry_point = entry_point; + session_args = args; + } + ExecutableDeployItem::StoredVersionedContractByHash { + hash, + version, + entry_point, + args, + } => { + session = Session::Stored(TransactionInvocationTarget::new_package(hash, version)); + session_entry_point = entry_point; + session_args = args; + } + ExecutableDeployItem::StoredVersionedContractByName { + name, + version, + entry_point, + args, + } => { + session = Session::Stored(TransactionInvocationTarget::new_package_alias( + name, version, + )); + session_entry_point = entry_point; + session_args = args; + } + ExecutableDeployItem::Transfer { .. } => { + return Err(NewRequestError::InvalidSessionDeployItem(deploy_hash)); + } + } + Ok(SessionInfo { + session, + entry_point: session_entry_point, + args: session_args, + }) + } +} + +impl TryFrom<(TransactionV1Body, TransactionV1Hash)> for SessionInfo { + type Error = NewRequestError; + + fn try_from( + (txn_v1_body, txn_v1_hash): (TransactionV1Body, TransactionV1Hash), + ) -> Result { + let (args, target, entry_point, _scheduling) = txn_v1_body.destructure(); + + let session: Session; + match target { + TransactionTarget::Native => { + return Err(NewRequestError::InvalidSessionV1Target(txn_v1_hash)) + } + TransactionTarget::Stored { id, .. } => { + session = Session::Stored(id); + } + TransactionTarget::Session { + kind, module_bytes, .. + } => session = Session::ModuleBytes { kind, module_bytes }, + } + + let TransactionEntryPoint::Custom(session_entry_point) = entry_point else { + return Err(NewRequestError::InvalidSessionV1EntryPoint(txn_v1_hash)); + }; + + Ok(SessionInfo { + session, + entry_point: session_entry_point, + args, + }) + } +} + +/// Error returned if constructing a new [`ExecuteRequest`] fails. +#[derive(Copy, Clone, Eq, PartialEq, Error, Serialize, Debug)] +pub enum NewRequestError { + /// The executable deploy item for payment cannot be the transfer variant. + #[error("cannot use transfer variant for payment in deploy {0}")] + InvalidPaymentDeployItem(DeployHash), + /// The executable deploy item for session cannot be the transfer variant. + #[error("cannot use transfer variant for session in deploy {0}")] + InvalidSessionDeployItem(DeployHash), + /// The transaction v1 target for session cannot be the native variant. + #[error("cannot use native variant for session target in transaction v1 {0}")] + InvalidSessionV1Target(TransactionV1Hash), + /// The transaction v1 entry point for session cannot be one of the native variants. + #[error("cannot use native variant for session entry point in transaction v1 {0}")] + InvalidSessionV1EntryPoint(TransactionV1Hash), +} + +/// A request to execute the given transaction. #[derive(Debug)] pub struct ExecuteRequest { - /// State root hash of the global state in which the deploys will be executed. - pub parent_state_hash: Digest, + /// State root hash of the global state in which the transaction will be executed. + pub pre_state_hash: Digest, /// Block time represented as a unix timestamp. - pub block_time: u64, - /// List of deploys that will be executed as part of this request. - pub deploys: Vec, - /// Protocol version used to execute deploys from the list. - pub protocol_version: ProtocolVersion, + pub block_time: BlockTime, + /// The hash identifying the transaction. + pub transaction_hash: TransactionHash, + /// The number of Motes per unit of Gas to be paid for execution. + pub gas_price: u64, + /// The transaction's initiator. + pub initiator_addr: InitiatorAddr, + /// The payment kind. + pub payment: Payment, + /// The entry point to call when executing the payment. + pub payment_entry_point: String, + /// The payment runtime args. + pub payment_args: RuntimeArgs, + /// The session kind. + pub session: Session, + /// The entry point to call when executing the session. + pub session_entry_point: String, + /// The session runtime args. + pub session_args: RuntimeArgs, + /// The account hashes of the signers of the transaction. + pub authorization_keys: BTreeSet, /// The owner of the node that proposed the block containing this request. pub proposer: PublicKey, } impl ExecuteRequest { - /// Creates new execute request. + /// Creates a new execute request. pub fn new( parent_state_hash: Digest, - block_time: u64, - deploys: Vec, - protocol_version: ProtocolVersion, + block_time: BlockTime, + txn: Transaction, proposer: PublicKey, - ) -> Self { - Self { - parent_state_hash, - block_time, - deploys, - protocol_version, - proposer, - } - } - - /// Returns deploys, and overwrites the existing value with empty list. - pub fn take_deploys(&mut self) -> Vec { - mem::take(&mut self.deploys) - } + ) -> Result { + let transaction_hash = txn.hash(); + let gas_price = txn.gas_price(); + let initiator_addr = txn.initiator_addr(); + let authorization_keys = txn.signers(); - /// Returns list of deploys. - pub fn deploys(&self) -> &Vec { - &self.deploys - } -} + let payment_info: PaymentInfo; + let session_info: SessionInfo; + match txn { + Transaction::Deploy(deploy) => { + let (hash, _header, payment, session, _approvals) = deploy.destructure(); + payment_info = PaymentInfo::try_from((payment, hash))?; + session_info = SessionInfo::try_from((session, hash))?; + } + Transaction::V1(v1_txn) => { + let (hash, header, body, _approvals) = v1_txn.destructure(); + match header.payment_amount() { + Some(amount) => { + payment_info = PaymentInfo { + payment: Payment::Standard, + entry_point: DEFAULT_ENTRY_POINT.to_string(), + args: runtime_args! { "amount" => U512::from(amount) }, + }; + } + None => { + // If the payment amount is `None`, the provided session will be invoked + // during the payment and session phases. + payment_info = PaymentInfo { + payment: Payment::UseSession, + entry_point: DEFAULT_ENTRY_POINT.to_string(), + args: RuntimeArgs::new(), + }; + } + }; + session_info = SessionInfo::try_from((body, hash))?; + } + }; -impl Default for ExecuteRequest { - fn default() -> Self { - let proposer_secret_key = - SecretKey::ed25519_from_bytes([0; SecretKey::ED25519_LENGTH]).unwrap(); - let proposer = PublicKey::from(&proposer_secret_key); - Self { - parent_state_hash: Digest::hash([]), - block_time: 0, - deploys: vec![], - protocol_version: Default::default(), + Ok(Self { + pre_state_hash: parent_state_hash, + block_time, + transaction_hash, + gas_price, + initiator_addr, + payment: payment_info.payment, + payment_entry_point: payment_info.entry_point, + payment_args: payment_info.args, + session: session_info.session, + session_entry_point: session_info.entry_point, + session_args: session_info.args, + authorization_keys, proposer, - } + }) } } diff --git a/execution_engine/src/engine_state/execution_kind.rs b/execution_engine/src/engine_state/execution_kind.rs index 2f339c909e..9d4929d740 100644 --- a/execution_engine/src/engine_state/execution_kind.rs +++ b/execution_engine/src/engine_state/execution_kind.rs @@ -1,14 +1,12 @@ //! Units of execution. -use std::{cell::RefCell, rc::Rc}; - use casper_storage::{ global_state::{error::Error as GlobalStateError, state::StateReader}, tracking_copy::{TrackingCopy, TrackingCopyExt}, }; use casper_types::{ - addressable_entity::NamedKeys, bytesrepr::Bytes, AddressableEntityHash, EntityVersionKey, - ExecutableDeployItem, Key, Package, PackageHash, Phase, ProtocolVersion, StoredValue, + addressable_entity::NamedKeys, bytesrepr::Bytes, AddressableEntityHash, EntityVersionKey, Key, + PackageHash, ProtocolVersion, StoredValue, TransactionInvocationTarget, }; use crate::{ @@ -18,105 +16,96 @@ use crate::{ /// The type of execution about to be performed. #[derive(Clone, Debug)] -pub(crate) enum ExecutionKind { - /// Wasm bytes. - Module(Bytes), +pub(crate) enum ExecutionKind<'a> { + /// Standard (non-specialized) Wasm bytes. + Standard(&'a Bytes), + /// Wasm bytes which install a stored entity. + Installer(&'a Bytes), + /// Wasm bytes which upgrade a stored entity. + Upgrader(&'a Bytes), + /// Wasm bytes which don't call any stored entity. + Isolated(&'a Bytes), /// Stored contract. - Contract { + Stored { /// AddressableEntity's hash. entity_hash: AddressableEntityHash, - /// Entry point's name. - entry_point_name: String, + /// Entry point. + entry_point: String, }, } -impl ExecutionKind { - /// Returns a new module variant of `ExecutionKind`. - pub fn new_module(module_bytes: Bytes) -> Self { - ExecutionKind::Module(module_bytes) +impl<'a> ExecutionKind<'a> { + /// Returns a new `Standard` variant of `ExecutionKind`. + pub fn new_standard(module_bytes: &'a Bytes) -> Self { + ExecutionKind::Standard(module_bytes) } - /// Returns a new contract variant of `ExecutionKind`. - pub fn new_addressable_entity( - entity_hash: AddressableEntityHash, - entry_point_name: String, - ) -> Self { - ExecutionKind::Contract { - entity_hash, - entry_point_name, + /// Returns a new `Installer` variant of `ExecutionKind`. + pub fn new_installer(module_bytes: &'a Bytes) -> Self { + ExecutionKind::Installer(module_bytes) + } + + /// Returns a new `Upgrader` variant of `ExecutionKind`. + pub fn new_upgrader(module_bytes: &'a Bytes) -> Self { + ExecutionKind::Upgrader(module_bytes) + } + + /// Returns a new `Isolated` variant of `ExecutionKind`. + pub fn new_isolated(module_bytes: &'a Bytes) -> Self { + ExecutionKind::Isolated(module_bytes) + } + + /// Returns a new `Standard` variant of `ExecutionKind`, returning an error if the module bytes + /// are empty. + pub fn new_for_payment(module_bytes: &'a Bytes) -> Result { + if module_bytes.is_empty() { + return Err(Error::EmptyCustomPaymentModuleBytes); + } + Ok(ExecutionKind::Standard(module_bytes)) + } + + /// Returns a new `ExecutionKind` cloned from `self`, but converting any Wasm bytes variant to + /// `Standard`, and returning an error if they are empty. + pub fn convert_for_payment(&self) -> Result { + match self { + ExecutionKind::Standard(module_bytes) + | ExecutionKind::Installer(module_bytes) + | ExecutionKind::Upgrader(module_bytes) + | ExecutionKind::Isolated(module_bytes) => Self::new_for_payment(module_bytes), + ExecutionKind::Stored { .. } => Ok(self.clone()), } } - /// Returns all the details necessary for execution. - /// - /// This object is generated based on information provided by [`ExecutableDeployItem`]. - pub fn new( - tracking_copy: Rc>>, + /// Returns a new contract variant of `ExecutionKind`. + pub fn new_stored( + tracking_copy: &mut TrackingCopy, + target: TransactionInvocationTarget, + entry_point: String, named_keys: &NamedKeys, - executable_deploy_item: ExecutableDeployItem, - protocol_version: &ProtocolVersion, - phase: Phase, - ) -> Result + protocol_version: ProtocolVersion, + ) -> Result where R: StateReader, { - let package: Package; - - let is_payment_phase = phase == Phase::Payment; - - match executable_deploy_item { - ExecutableDeployItem::Transfer { .. } => { - Err(Error::InvalidDeployItemVariant("Transfer".into())) - } - ExecutableDeployItem::ModuleBytes { module_bytes, .. } - if module_bytes.is_empty() && is_payment_phase => - { - Err(Error::InvalidDeployItemVariant( - "Empty module bytes for custom payment".into(), - )) - } - ExecutableDeployItem::ModuleBytes { module_bytes, .. } => { - Ok(ExecutionKind::new_module(module_bytes)) - } - ExecutableDeployItem::StoredContractByHash { - hash, entry_point, .. - } => Ok(ExecutionKind::new_addressable_entity(hash, entry_point)), - ExecutableDeployItem::StoredContractByName { - name, entry_point, .. - } => { - let entity_key = named_keys.get(&name).cloned().ok_or_else(|| { - Error::Exec(execution::Error::NamedKeyNotFound(name.to_string())) - })?; - - let entity_hash = match entity_key { + let entity_hash = match target { + TransactionInvocationTarget::InvocableEntity(addr) => AddressableEntityHash::new(addr), + TransactionInvocationTarget::InvocableEntityAlias(alias) => { + let entity_key = named_keys + .get(&alias) + .cloned() + .ok_or_else(|| Error::Exec(execution::Error::NamedKeyNotFound(alias)))?; + + match entity_key { Key::Hash(hash) => AddressableEntityHash::new(hash), Key::AddressableEntity(entity_addr) => { AddressableEntityHash::new(entity_addr.value()) } _ => return Err(Error::InvalidKeyVariant), - }; - - Ok(ExecutionKind::new_addressable_entity( - entity_hash, - entry_point, - )) + } } - ExecutableDeployItem::StoredVersionedContractByName { - name, - version, - entry_point, - .. - } => { - let package_key = named_keys.get(&name).cloned().ok_or_else(|| { - Error::Exec(execution::Error::NamedKeyNotFound(name.to_string())) - })?; - - let package_hash = match package_key { - Key::Hash(hash) | Key::Package(hash) => PackageHash::new(hash), - _ => return Err(Error::InvalidKeyVariant), - }; - - package = tracking_copy.borrow_mut().get_package(package_hash)?; + TransactionInvocationTarget::Package { addr, version } => { + let package_hash = PackageHash::from(addr); + let package = tracking_copy.get_package(package_hash)?; let maybe_version_key = version.map(|ver| EntityVersionKey::new(protocol_version.value().major, ver)); @@ -133,25 +122,23 @@ impl ExecutionKind { ))); } - let looked_up_entity_hash: AddressableEntityHash = package + *package .lookup_entity_hash(contract_version_key) .ok_or(Error::Exec(execution::Error::InvalidEntityVersion( contract_version_key, )))? - .to_owned(); - - Ok(ExecutionKind::new_addressable_entity( - looked_up_entity_hash, - entry_point, - )) } - ExecutableDeployItem::StoredVersionedContractByHash { - hash: package_hash, - version, - entry_point, - .. - } => { - package = tracking_copy.borrow_mut().get_package(package_hash)?; + TransactionInvocationTarget::PackageAlias { alias, version } => { + let package_key = named_keys.get(&alias).cloned().ok_or_else(|| { + Error::Exec(execution::Error::NamedKeyNotFound(alias.to_string())) + })?; + + let package_hash = match package_key { + Key::Hash(hash) | Key::Package(hash) => PackageHash::new(hash), + _ => return Err(Error::InvalidKeyVariant), + }; + + let package = tracking_copy.get_package(package_hash)?; let maybe_version_key = version.map(|ver| EntityVersionKey::new(protocol_version.value().major, ver)); @@ -168,17 +155,16 @@ impl ExecutionKind { ))); } - let looked_up_entity_hash = *package + *package .lookup_entity_hash(contract_version_key) .ok_or(Error::Exec(execution::Error::InvalidEntityVersion( contract_version_key, - )))?; - - Ok(ExecutionKind::new_addressable_entity( - looked_up_entity_hash, - entry_point, - )) + )))? } - } + }; + Ok(ExecutionKind::Stored { + entity_hash, + entry_point, + }) } } diff --git a/execution_engine/src/engine_state/execution_result.rs b/execution_engine/src/engine_state/execution_result.rs index 7e62f90489..51dd2ca11c 100644 --- a/execution_engine/src/engine_state/execution_result.rs +++ b/execution_engine/src/engine_state/execution_result.rs @@ -1,7 +1,5 @@ //! Outcome of an `ExecutionRequest`. -use std::collections::VecDeque; - use casper_storage::data_access_layer::TransferResult; use casper_types::{ bytesrepr::FromBytes, @@ -10,7 +8,7 @@ use casper_types::{ CLTyped, CLValue, Gas, Key, Motes, StoredValue, TransferAddr, }; -use super::Error; +use super::error; use crate::execution::Error as ExecError; /// Represents the result of an execution specified by @@ -20,11 +18,11 @@ pub enum ExecutionResult { /// An error condition that happened during execution Failure { /// Error causing this `Failure` variant. - error: Error, + error: error::Error, /// List of transfers that happened during execution up to the point of the failure. transfers: Vec, /// Gas consumed up to the point of the failure. - cost: Gas, + gas: Gas, /// Execution effects. effects: Effects, /// Messages emitted during execution. @@ -34,8 +32,8 @@ pub enum ExecutionResult { Success { /// List of transfers. transfers: Vec, - /// Gas cost. - cost: Gas, + /// Gas consumed. + gas: Gas, /// Execution effects. effects: Effects, /// Messages emitted during execution. @@ -43,9 +41,6 @@ pub enum ExecutionResult { }, } -/// A type alias that represents multiple execution results. -pub type ExecutionResults = VecDeque; - /// Indicates the outcome of a transfer payment check. pub enum ForcedTransferResult { /// Payment code ran out of gas during execution @@ -60,11 +55,11 @@ impl ExecutionResult { /// Constructs [ExecutionResult::Failure] that has 0 cost and no effects. /// This is the case for failures that we can't (or don't want to) charge /// for, like `PreprocessingError` or `InvalidNonce`. - pub fn precondition_failure(error: Error) -> ExecutionResult { + pub fn precondition_failure(error: error::Error) -> ExecutionResult { ExecutionResult::Failure { error, transfers: Vec::default(), - cost: Gas::default(), + gas: Gas::zero(), effects: Effects::new(), messages: Vec::default(), } @@ -92,18 +87,17 @@ impl ExecutionResult { /// effects, and has a gas cost of 0. pub fn has_precondition_failure(&self) -> bool { match self { - ExecutionResult::Failure { cost, effects, .. } => { - cost.value() == 0.into() && effects.is_empty() + ExecutionResult::Failure { gas, effects, .. } => { + *gas == Gas::zero() && effects.is_empty() } ExecutionResult::Success { .. } => false, } } - /// Returns gas cost of execution regardless of variant. - pub fn cost(&self) -> Gas { + /// Returns gas used during execution regardless of variant. + pub fn gas(&self) -> Gas { match self { - ExecutionResult::Failure { cost, .. } => *cost, - ExecutionResult::Success { cost, .. } => *cost, + ExecutionResult::Failure { gas, .. } | ExecutionResult::Success { gas, .. } => *gas, } } @@ -124,11 +118,10 @@ impl ExecutionResult { } } - /// Returns a new execution result with updated gas cost. + /// Returns a new execution result with updated gas. /// - /// This method preserves the [`ExecutionResult`] variant and updates the cost field - /// only. - pub fn with_cost(self, cost: Gas) -> Self { + /// This method preserves the [`ExecutionResult`] variant and updates the gas field only. + pub fn with_gas(self, gas: Gas) -> Self { match self { ExecutionResult::Failure { error, @@ -139,7 +132,7 @@ impl ExecutionResult { } => ExecutionResult::Failure { error, transfers, - cost, + gas, effects, messages, }, @@ -150,7 +143,7 @@ impl ExecutionResult { .. } => ExecutionResult::Success { transfers, - cost, + gas, effects, messages, }, @@ -165,25 +158,25 @@ impl ExecutionResult { match self { ExecutionResult::Failure { error, - cost, + gas, effects, messages, .. } => ExecutionResult::Failure { error, transfers, - cost, + gas, effects, messages, }, ExecutionResult::Success { - cost, + gas, effects, messages, .. } => ExecutionResult::Success { transfers, - cost, + gas, effects, messages, }, @@ -199,24 +192,24 @@ impl ExecutionResult { ExecutionResult::Failure { error, transfers, - cost, + gas, effects: _, messages, } => ExecutionResult::Failure { error, transfers, - cost, + gas, effects, messages, }, ExecutionResult::Success { transfers, - cost, + gas, effects: _, messages, } => ExecutionResult::Success { transfers, - cost, + gas, effects, messages, }, @@ -225,19 +218,18 @@ impl ExecutionResult { /// Returns error value, if possible. /// - /// Returns a reference to a wrapped [`super::Error`] - /// instance if the object is a failure variant. - pub fn as_error(&self) -> Option<&Error> { + /// Returns a reference to a wrapped [`error::Error`] instance if the object is a failure + /// variant. + pub fn as_error(&self) -> Option<&error::Error> { match self { ExecutionResult::Failure { error, .. } => Some(error), ExecutionResult::Success { .. } => None, } } - /// Consumes [`ExecutionResult`] instance and optionally returns - /// [`super::Error`] instance for + /// Consumes [`ExecutionResult`] instance and optionally returns [`error::Error`] instance for /// [`ExecutionResult::Failure`] variant. - pub fn take_error(self) -> Option { + pub fn take_error(self) -> Option { match self { ExecutionResult::Failure { error, .. } => Some(error), ExecutionResult::Success { .. } => None, @@ -258,7 +250,7 @@ impl ExecutionResult { payment_purse_balance: Motes, gas_price: u64, ) -> Option { - let payment_result_cost = match Motes::from_gas(self.cost(), gas_price) { + let payment_result_cost = match Motes::from_gas(self.gas(), gas_price) { Some(cost) => cost, None => return Some(ForcedTransferResult::GasConversionOverflow), }; @@ -290,16 +282,16 @@ impl ExecutionResult { /// The effects that are produced as part of this process would subract `max_payment_cost` from /// account's main purse, and add `max_payment_cost` to proposer account's balance. pub fn new_payment_code_error( - error: Error, + error: error::Error, max_payment_cost: Motes, account_main_purse_balance: Motes, - gas_cost: Gas, + gas: Gas, account_main_purse_balance_key: Key, proposer_main_purse_balance_key: Key, - ) -> Result { + ) -> Result { let new_balance = account_main_purse_balance .checked_sub(max_payment_cost) - .ok_or(Error::InsufficientPayment)?; + .ok_or(error::Error::InsufficientPayment)?; let new_balance_value = StoredValue::CLValue(CLValue::from_t(new_balance.value()).map_err(ExecError::from)?); let mut effects = Effects::new(); @@ -316,7 +308,7 @@ impl ExecutionResult { error, effects, transfers, - cost: gas_cost, + gas, messages: Vec::default(), }) } @@ -333,7 +325,7 @@ impl ExecutionResult { /// A temporary measure to keep things functioning mid-refactor. #[allow(clippy::result_unit_err)] - pub fn from_transfer_result(transfer_result: TransferResult, cost: Gas) -> Result { + pub fn from_transfer_result(transfer_result: TransferResult, gas: Gas) -> Result { match transfer_result { TransferResult::RootNotFound => { Err(()) @@ -345,16 +337,16 @@ impl ExecutionResult { } => { Ok(ExecutionResult::Success { transfers, - cost, + gas, effects, messages: Messages::default(), }) } TransferResult::Failure(te) => { Ok(ExecutionResult::Failure { - error: Error::Transfer(te), + error: error::Error::Transfer(te), transfers: vec![], - cost, + gas, effects: Effects::default(), // currently not returning effects on failure messages: Messages::default(), }) @@ -364,6 +356,7 @@ impl ExecutionResult { } /// A versioned execution result and the messages produced by that execution. +#[derive(Debug)] pub struct ExecutionResultAndMessages { /// Execution result pub execution_result: TypesExecutionResult, @@ -376,28 +369,28 @@ impl From for ExecutionResultAndMessages { match execution_result { ExecutionResult::Success { transfers, - cost, + gas, effects, messages, } => ExecutionResultAndMessages { execution_result: TypesExecutionResult::Success { effects, transfers, - cost: cost.value(), + gas, }, messages, }, ExecutionResult::Failure { error, transfers, - cost, + gas, effects, messages, } => ExecutionResultAndMessages { execution_result: TypesExecutionResult::Failure { effects, transfers, - cost: cost.value(), + gas, error_message: error.to_string(), }, messages, @@ -460,22 +453,22 @@ impl ExecutionResultBuilder { /// /// Takes a payment execution result, and a session execution result and returns a sum. If /// either a payment or session code is not specified then a 0 is used. - pub fn total_cost(&self) -> Gas { - let payment_cost = self + pub fn gas_used(&self) -> Gas { + let payment_gas = self .payment_execution_result .as_ref() - .map(ExecutionResult::cost) + .map(ExecutionResult::gas) .unwrap_or_default(); - let session_cost = self + let session_gas = self .session_execution_result .as_ref() - .map(ExecutionResult::cost) + .map(ExecutionResult::gas) .unwrap_or_default(); // TODO: Make sure this code isn't in production, as, even though it's highly unlikely // to happen, an integer overflow would be silently ignored in release builds. // NOTE: This code should have been removed in the fix of #1968, where arithmetic // operations on the Gas type were disabled. - payment_cost + session_cost + payment_gas + session_gas } /// Returns transfers from a session's execution result. @@ -492,9 +485,9 @@ impl ExecutionResultBuilder { /// Builds a final [`ExecutionResult`] based on session result, payment result and a /// finalization result. pub fn build(self) -> Result { - let mut error: Option = None; + let mut error: Option = None; let mut transfers = self.transfers(); - let cost = self.total_cost(); + let gas = self.gas_used(); let (mut all_effects, mut all_messages) = match self.payment_execution_result { Some(result @ ExecutionResult::Failure { .. }) => return Ok(result), @@ -511,7 +504,7 @@ impl ExecutionResultBuilder { error: session_error, transfers: session_transfers, effects: _, - cost: _, + gas: _, messages, }) => { error = Some(session_error); @@ -530,7 +523,9 @@ impl ExecutionResultBuilder { match self.finalize_execution_result { Some(ExecutionResult::Failure { .. }) => { // payment_code_spec_5_a: Finalization Error should only ever be raised here - return Ok(ExecutionResult::precondition_failure(Error::Finalization)); + return Ok(ExecutionResult::precondition_failure( + error::Error::Finalization, + )); } Some(ExecutionResult::Success { effects, messages, .. @@ -544,14 +539,14 @@ impl ExecutionResultBuilder { match error { None => Ok(ExecutionResult::Success { transfers, - cost, + gas, effects: all_effects, messages: all_messages, }), Some(error) => Ok(ExecutionResult::Failure { error, transfers, - cost, + gas, effects: all_effects, messages: all_messages, }), diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index 9d00e2dec9..cebc6f4db3 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -2,6 +2,7 @@ pub mod deploy_item; pub mod engine_config; mod error; +/// Module containing the [`ExecuteRequest`] and associated items. pub mod execute_request; pub(crate) mod execution_kind; pub mod execution_result; @@ -25,10 +26,9 @@ use casper_storage::{ balance::BalanceResult, get_bids::{BidsRequest, BidsResult}, query::{QueryRequest, QueryResult}, - transfer::TransferConfig, + transfer::{TransferConfig, TransferRequest}, DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, FlushRequest, FlushResult, - GenesisRequest, GenesisResult, ProtocolUpgradeRequest, ProtocolUpgradeResult, - TransferRequest, TrieRequest, + GenesisRequest, GenesisResult, ProtocolUpgradeRequest, ProtocolUpgradeResult, TrieRequest, }, global_state::{ self, @@ -56,9 +56,10 @@ use casper_types::{ handle_payment::{self, ACCUMULATION_PURSE_KEY}, AUCTION, HANDLE_PAYMENT, MINT, }, - AddressableEntity, AddressableEntityHash, BlockTime, DeployHash, DeployInfo, Digest, - EntityAddr, ExecutableDeployItem, FeeHandling, Gas, Key, KeyTag, Motes, Phase, ProtocolVersion, - PublicKey, RuntimeArgs, StoredValue, SystemEntityRegistry, URef, U512, + AddressableEntity, AddressableEntityHash, BlockTime, Digest, EntityAddr, FeeHandling, Gas, Key, + KeyTag, Motes, Phase, ProtocolVersion, PublicKey, RuntimeArgs, StoredValue, + SystemEntityRegistry, TransactionHash, TransactionInfo, TransactionSessionKind, + TransactionV1Hash, URef, U512, }; pub use self::{ @@ -68,7 +69,9 @@ pub use self::{ DEFAULT_MAX_RUNTIME_CALL_STACK_HEIGHT, }, error::Error, - execute_request::ExecuteRequest, + execute_request::{ + ExecuteRequest, NewRequestError, Payment, PaymentInfo, Session, SessionInfo, + }, execution::Error as ExecError, execution_result::{ExecutionResult, ForcedTransferResult}, prune::{PruneConfig, PruneResult}, @@ -76,7 +79,7 @@ pub use self::{ }; use crate::{ - engine_state::{execution_kind::ExecutionKind, execution_result::ExecutionResults}, + engine_state::execution_kind::ExecutionKind, execution::{self, DirectSystemContractCall, Executor}, runtime::RuntimeStack, }; @@ -307,49 +310,6 @@ where self.state.query(query_request) } - /// Runs a deploy execution request. - /// - /// For each deploy stored in the request it will execute it. - /// - /// Currently a special shortcut is taken to distinguish a native transfer, from a deploy. - /// - /// Return execution results which contains results from each deploy ran. - pub fn run_execute(&self, mut exec_request: ExecuteRequest) -> Result { - let executor = Executor::new(self.config().clone()); - - let deploys = exec_request.take_deploys(); - let mut results = ExecutionResults::with_capacity(deploys.len()); - - for deploy_item in deploys { - let result = match deploy_item.session { - ExecutableDeployItem::Transfer { .. } => self.transfer( - &executor, - exec_request.protocol_version, - exec_request.parent_state_hash, - BlockTime::new(exec_request.block_time), - deploy_item, - exec_request.proposer.clone(), - ), - _ => self.deploy( - &executor, - exec_request.protocol_version, - exec_request.parent_state_hash, - BlockTime::new(exec_request.block_time), - deploy_item, - exec_request.proposer.clone(), - ), - }; - match result { - Ok(result) => results.push_back(result), - Err(error) => { - return Err(error); - } - }; - } - - Ok(results) - } - fn get_named_keys( &self, entity_addr: EntityAddr, @@ -378,7 +338,7 @@ where Ok(BalanceResult::Success { motes, proof }) } - /// Executes a native transfer. + /// Executes a transfer. /// /// Native transfers do not involve WASM at all, and also skip executing payment code. /// Therefore this is the fastest and cheapest way to transfer tokens from account to account. @@ -419,48 +379,57 @@ where .map_err(|_| Error::RootNotFound(prestate_hash)) } - /// Executes a deploy. + /// Executes a transaction. /// - /// A deploy execution consists of running the payment code, which is expected to deposit funds - /// into the payment purse, and then running the session code with a specific gas limit. For - /// running payment code, we lock [`MAX_PAYMENT`] amount of motes from the user as collateral. - /// If both the payment code and the session code execute successfully, a fraction of the - /// unspent collateral will be transferred back to the proposer of the deploy, as specified - /// in the request. + /// A transaction execution consists of running the payment code, which is expected to deposit + /// funds into the payment purse, and then running the session code with a specific gas limit. + /// For running payment code, we lock [`MAX_PAYMENT`] amount of motes from the user as + /// collateral. If both the payment code and the session code execute successfully, a fraction + /// of the unspent collateral will be transferred back to the proposer of the transaction, as + /// specified in the request. /// /// Returns [`ExecutionResult`], or an error condition. - #[allow(clippy::too_many_arguments)] - pub fn deploy( + pub fn execute_transaction( &self, - executor: &Executor, - protocol_version: ProtocolVersion, - prestate_hash: Digest, - blocktime: BlockTime, - deploy_item: DeployItem, - proposer: PublicKey, + ExecuteRequest { + pre_state_hash, + block_time, + transaction_hash, + gas_price, + initiator_addr, + payment, + payment_entry_point, + payment_args, + session, + session_entry_point, + session_args, + authorization_keys, + proposer, + }: ExecuteRequest, ) -> Result { // spec: https://casperlabs.atlassian.net/wiki/spaces/EN/pages/123404576/Payment+code+execution+specification + let executor = Executor::new(self.config().clone()); + let protocol_version = self.config.protocol_version(); // Create tracking copy (which functions as a deploy context) // validation_spec_2: prestate_hash check // do this second; as there is no reason to proceed if the prestate hash is invalid - let tracking_copy = match self.tracking_copy(prestate_hash) { + let tracking_copy = match self.tracking_copy(pre_state_hash) { Err(gse) => return Ok(ExecutionResult::precondition_failure(Error::Storage(gse))), - Ok(None) => return Err(Error::RootNotFound(prestate_hash)), + Ok(None) => return Err(Error::RootNotFound(pre_state_hash)), Ok(Some(tracking_copy)) => Rc::new(RefCell::new(tracking_copy)), }; // Get addr bytes from `address` (which is actually a Key) // validation_spec_3: account validity - let authorization_keys = deploy_item.authorization_keys; - let account_hash = deploy_item.address; + let account_hash = initiator_addr.account_hash(); - if let Err(e) = tracking_copy + if let Err(error) = tracking_copy .borrow_mut() .migrate_account(account_hash, protocol_version) { - return Ok(ExecutionResult::precondition_failure(e.into())); + return Ok(ExecutionResult::precondition_failure(error.into())); } // Get account from tracking copy @@ -475,13 +444,13 @@ where &self.config().administrative_accounts, ) { Ok((addressable_entity, entity_hash)) => (addressable_entity, entity_hash), - Err(e) => return Ok(ExecutionResult::precondition_failure(e.into())), + Err(error) => return Ok(ExecutionResult::precondition_failure(error.into())), } }; - let entity_kind = entity.entity_kind(); + let entity_kind = entity.kind(); - let entity_addr = EntityAddr::new_with_tag(entity_kind, entity_hash.value()); + let entity_addr = EntityAddr::new_of_kind(entity_kind, entity_hash.value()); let entity_named_keys = match self.get_named_keys(entity_addr, Rc::clone(&tracking_copy)) { Ok(named_keys) => named_keys, @@ -490,27 +459,38 @@ where } }; - let payment = deploy_item.payment; - let session = deploy_item.session; - - let deploy_hash = deploy_item.deploy_hash; - - let session_args = session.args().clone(); - // Create session code `A` from provided session bytes // validation_spec_1: valid wasm bytes // we do this upfront as there is no reason to continue if session logic is invalid - let session_execution_kind = match ExecutionKind::new( - Rc::clone(&tracking_copy), - &entity_named_keys, - session, - &protocol_version, - Phase::Session, - ) { - Ok(execution_kind) => execution_kind, - Err(error) => { - return Ok(ExecutionResult::precondition_failure(error)); - } + let session_execution_kind = match &session { + Session::Stored(invocation_target) => match ExecutionKind::new_stored( + &mut *tracking_copy.borrow_mut(), + invocation_target.clone(), + session_entry_point, + &entity_named_keys, + protocol_version, + ) { + Ok(execution_kind) => execution_kind, + Err(error) => { + return Ok(ExecutionResult::precondition_failure(error)); + } + }, + Session::ModuleBytes { + kind: TransactionSessionKind::Standard, + module_bytes, + } => ExecutionKind::new_standard(module_bytes), + Session::ModuleBytes { + kind: TransactionSessionKind::Installer, + module_bytes, + } => ExecutionKind::new_installer(module_bytes), + Session::ModuleBytes { + kind: TransactionSessionKind::Upgrader, + module_bytes, + } => ExecutionKind::new_upgrader(module_bytes), + Session::ModuleBytes { + kind: TransactionSessionKind::Isolated, + module_bytes, + } => ExecutionKind::new_isolated(module_bytes), }; // Get account main purse balance key @@ -559,17 +539,15 @@ where // Get handle payment system contract details // payment_code_spec_6: system contract validity - let system_contract_registry = tracking_copy.borrow_mut().get_system_entity_registry()?; + let system_entity_registry = tracking_copy.borrow_mut().get_system_entity_registry()?; - let handle_payment_contract_hash = system_contract_registry - .get(HANDLE_PAYMENT) - .ok_or_else(|| { + let handle_payment_contract_hash = + system_entity_registry.get(HANDLE_PAYMENT).ok_or_else(|| { error!("Missing system handle payment contract hash"); Error::MissingSystemContractHash(HANDLE_PAYMENT.to_string()) })?; - let handle_payment_addr = - EntityAddr::new_system_entity_addr(handle_payment_contract_hash.value()); + let handle_payment_addr = EntityAddr::new_system(handle_payment_contract_hash.value()); let handle_payment_named_keys = match self.get_named_keys(handle_payment_addr, Rc::clone(&tracking_copy)) { @@ -581,10 +559,9 @@ where // Get payment purse Key from handle payment contract // payment_code_spec_6: system contract validity - let payment_purse_key = - match handle_payment_named_keys.get(handle_payment::PAYMENT_PURSE_KEY) { - Some(key) => *key, - None => return Ok(ExecutionResult::precondition_failure(Error::Deploy)), + let Some(payment_purse_key) = + handle_payment_named_keys.get(handle_payment::PAYMENT_PURSE_KEY).copied() else { + return Ok(ExecutionResult::precondition_failure(Error::Deploy)); }; let payment_purse_uref = payment_purse_key @@ -595,7 +572,7 @@ where let mut execution_result_builder = execution_result::ExecutionResultBuilder::new(); let rewards_target_purse = - match self.get_rewards_purse(protocol_version, proposer, prestate_hash) { + match self.get_rewards_purse(protocol_version, proposer, pre_state_hash) { Ok(target_purse) => target_purse, Err(error) => return Ok(ExecutionResult::precondition_failure(error)), }; @@ -615,86 +592,97 @@ where }; // Execute provided payment code + // + // payment_code_spec_1: init pay environment w/ gas limit == (max_payment_cost / + // gas_price) + let Some(payment_gas_limit) = Gas::from_motes(max_payment_cost, gas_price) else { + return Ok(ExecutionResult::precondition_failure(Error::GasConversionOverflow)); + }; let payment_result = { - // payment_code_spec_1: init pay environment w/ gas limit == (max_payment_cost / - // gas_price) - let payment_gas_limit = match Gas::from_motes(max_payment_cost, deploy_item.gas_price) { - Some(gas) => gas, - None => { - return Ok(ExecutionResult::precondition_failure( - Error::GasConversionOverflow, - )) + let maybe_custom_payment = match &payment { + Payment::Standard => None, + Payment::Stored(invocation_target) => { + match ExecutionKind::new_stored( + &mut *tracking_copy.borrow_mut(), + invocation_target.clone(), + payment_entry_point, + &entity_named_keys, + protocol_version, + ) { + Ok(execution_kind) => Some(execution_kind), + Err(error) => { + return Ok(ExecutionResult::precondition_failure(error)); + } + } + } + Payment::ModuleBytes(module_bytes) => { + match ExecutionKind::new_for_payment(module_bytes) { + Ok(execution_kind) => Some(execution_kind), + Err(error) => { + return Ok(ExecutionResult::precondition_failure(error)); + } + } } + Payment::UseSession => match session_execution_kind.convert_for_payment() { + Ok(execution_kind) => Some(execution_kind), + Err(error) => { + return Ok(ExecutionResult::precondition_failure(error)); + } + }, }; - // Create payment code module from bytes - // validation_spec_1: valid wasm bytes - let phase = Phase::Payment; - - let payment_stack = RuntimeStack::from_account_hash( - deploy_item.address, - self.config.max_runtime_call_stack_height() as usize, - ); - - // payment_code_spec_2: execute payment code - let payment_access_rights = - entity.extract_access_rights(entity_hash, &entity_named_keys); + if let Some(custom_payment) = maybe_custom_payment { + // Create payment code module from bytes + // validation_spec_1: valid wasm bytes + let payment_stack = RuntimeStack::from_account_hash( + account_hash, + self.config.max_runtime_call_stack_height() as usize, + ); - let mut payment_named_keys = entity_named_keys.clone(); + // payment_code_spec_2: execute payment code + let payment_access_rights = + entity.extract_access_rights(entity_hash, &entity_named_keys); - let payment_args = payment.args().clone(); + let mut payment_named_keys = entity_named_keys.clone(); - if payment.is_standard_payment(phase) { - // Todo potentially could be moved to Executor::Exec - match executor.exec_standard_payment( + executor.exec( + custom_payment, payment_args, + entity_hash, &entity, entity_kind, + &mut payment_named_keys, + payment_access_rights, authorization_keys.clone(), account_hash, - blocktime, - deploy_hash, + block_time, + transaction_hash, payment_gas_limit, protocol_version, Rc::clone(&tracking_copy), - self.config.max_runtime_call_stack_height() as usize, - ) { - Ok(payment_result) => payment_result, - Err(error) => { - return Ok(ExecutionResult::precondition_failure(error)); - } - } + Phase::Payment, + payment_stack, + ) } else { - let payment_execution_kind = match ExecutionKind::new( - Rc::clone(&tracking_copy), - &entity_named_keys, - payment, - &protocol_version, - phase, - ) { - Ok(execution_kind) => execution_kind, - Err(error) => { - return Ok(ExecutionResult::precondition_failure(error)); - } - }; - executor.exec( - payment_execution_kind, + // Todo potentially could be moved to Executor::Exec + match executor.exec_standard_payment( payment_args, - entity_hash, &entity, entity_kind, - &mut payment_named_keys, - payment_access_rights, authorization_keys.clone(), account_hash, - blocktime, - deploy_hash, + block_time, + transaction_hash, payment_gas_limit, protocol_version, Rc::clone(&tracking_copy), - phase, - payment_stack, - ) + self.config.max_runtime_call_stack_height() as usize, + ) { + Ok(payment_result) => payment_result, + Err(error) => { + return Ok(ExecutionResult::precondition_failure(error)); + } + } } }; log_execution_result("payment result", &payment_result); @@ -710,7 +698,7 @@ where error, max_payment_cost, account_main_purse_balance, - payment_result.cost(), + payment_result.gas(), entity_main_purse_key, rewards_target_purse_balance_key, ) { @@ -719,23 +707,20 @@ where } } - let payment_result_cost = payment_result.cost(); // payment_code_spec_3: fork based upon payment purse balance and cost of // payment code execution // Get handle payment system contract details // payment_code_spec_6: system contract validity - let system_contract_registry = tracking_copy.borrow_mut().get_system_entity_registry()?; + let system_entity_registry = tracking_copy.borrow_mut().get_system_entity_registry()?; - let handle_payment_contract_hash = system_contract_registry - .get(HANDLE_PAYMENT) - .ok_or_else(|| { + let handle_payment_contract_hash = + system_entity_registry.get(HANDLE_PAYMENT).ok_or_else(|| { error!("Missing system handle payment contract hash"); Error::MissingSystemContractHash(HANDLE_PAYMENT.to_string()) })?; - let handle_payment_addr = - EntityAddr::new_system_entity_addr(handle_payment_contract_hash.value()); + let handle_payment_addr = EntityAddr::new_system(handle_payment_contract_hash.value()); let handle_payment_named_keys = match self.get_named_keys(handle_payment_addr, Rc::clone(&tracking_copy)) { @@ -774,7 +759,7 @@ where }; if let Some(forced_transfer) = - payment_result.check_forced_transfer(payment_purse_balance, deploy_item.gas_price) + payment_result.check_forced_transfer(payment_purse_balance, gas_price) { // Get rewards purse balance key // payment_code_spec_6: system contract validity @@ -786,20 +771,11 @@ where .unwrap_or(Error::InsufficientPayment), }; - let gas_cost = match Gas::from_motes(max_payment_cost, deploy_item.gas_price) { - Some(gas) => gas, - None => { - return Ok(ExecutionResult::precondition_failure( - Error::GasConversionOverflow, - )) - } - }; - match ExecutionResult::new_payment_code_error( error, max_payment_cost, account_main_purse_balance, - gas_cost, + payment_gas_limit, entity_main_purse_key, rewards_target_purse_balance_key, ) { @@ -809,6 +785,7 @@ where }; // Transfer the contents of the rewards purse to block proposer + let payment_result_gas = payment_result.gas(); execution_result_builder.set_payment_execution_result(payment_result); // Begin session logic handling @@ -816,7 +793,7 @@ where let session_tracking_copy = Rc::new(RefCell::new(post_payment_tracking_copy.fork())); let session_stack = RuntimeStack::from_account_hash( - deploy_item.address, + account_hash, self.config.max_runtime_call_stack_height() as usize, ); @@ -830,17 +807,10 @@ where // session_code_spec_1: gas limit = ((balance of handle payment payment purse) / // gas_price) // - (gas spent during payment execution) - let session_gas_limit: Gas = - match Gas::from_motes(payment_purse_balance, deploy_item.gas_price) - .and_then(|gas| gas.checked_sub(payment_result_cost)) - { - Some(gas) => gas, - None => { - return Ok(ExecutionResult::precondition_failure( - Error::GasConversionOverflow, - )) - } - }; + let Some(session_gas_limit) = Gas::from_motes(payment_purse_balance, gas_price) + .and_then(|gas| gas.checked_sub(payment_result_gas)) else { + return Ok(ExecutionResult::precondition_failure(Error::GasConversionOverflow)); + }; executor.exec( session_execution_kind, @@ -852,8 +822,8 @@ where session_access_rights, authorization_keys.clone(), account_hash, - blocktime, - deploy_hash, + block_time, + transaction_hash, session_gas_limit, protocol_version, Rc::clone(&session_tracking_copy), @@ -863,26 +833,26 @@ where }; log_execution_result("session result", &session_result); - // Create + persist deploy info. + // Create + persist transaction info. { - let transfers = session_result.transfers(); - let cost = payment_result_cost.value() + session_result.cost().value(); - let deploy_info = DeployInfo::new( - deploy_hash, + let transfers = session_result.transfers().clone(); + let gas = payment_result_gas + session_result.gas(); + let txn_info = TransactionInfo::new( + transaction_hash, transfers, - account_hash, + initiator_addr, entity.main_purse(), - cost, + gas, ); session_tracking_copy.borrow_mut().write( - Key::DeployInfo(deploy_hash), - StoredValue::DeployInfo(deploy_info), + Key::TransactionInfo(transaction_hash), + StoredValue::TransactionInfo(txn_info), ); } // Session execution was zero cost or provided wasm was malformed. // Check if the payment purse can cover the minimum floor for session execution. - if (session_result.cost().is_zero() && payment_purse_balance < max_payment_cost) + if (session_result.gas().is_zero() && payment_purse_balance < max_payment_cost) || should_charge_for_errors_in_wasm(&session_result) { // When session code structure is valid but still has 0 cost we should propagate the @@ -896,7 +866,7 @@ where error, max_payment_cost, account_main_purse_balance, - session_result.cost(), + session_result.gas(), entity_main_purse_key, rewards_target_purse_balance_key, ) { @@ -905,7 +875,7 @@ where } } - let post_session_rc = if session_result.is_failure() { + let post_session_tc = if session_result.is_failure() { // If session code fails we do not include its effects, // so we start again from the post-payment state. Rc::new(RefCell::new(post_payment_tracking_copy.fork())) @@ -920,21 +890,19 @@ where // payment_code_spec_5: run finalize process let finalize_result: ExecutionResult = { - let post_session_tc = post_session_rc.borrow(); + let post_session_tc = post_session_tc.borrow(); let finalization_tc = Rc::new(RefCell::new(post_session_tc.fork())); let handle_payment_args = { - //((gas spent during payment code execution) + (gas spent during session code execution)) * gas_price - let finalize_cost_motes = match Motes::from_gas( - execution_result_builder.total_cost(), - deploy_item.gas_price, - ) { - Some(motes) => motes, - None => { - return Ok(ExecutionResult::precondition_failure( - Error::GasConversionOverflow, - )) - } + // ((gas spent during payment code execution) + (gas spent during session code + // execution)) * gas_price + let Some(finalize_cost_motes) = Motes::from_gas( + execution_result_builder.gas_used(), + gas_price, + ) else { + return Ok(ExecutionResult::precondition_failure( + Error::GasConversionOverflow, + )) }; let maybe_runtime_args = RuntimeArgs::try_new(|args| { @@ -954,12 +922,11 @@ where // The Handle Payment keys may have changed because of effects during payment and/or // session, so we need to look them up again from the tracking copy - let system_contract_registry = + let system_entity_registry = finalization_tc.borrow_mut().get_system_entity_registry()?; - let handle_payment_contract_hash = system_contract_registry - .get(HANDLE_PAYMENT) - .ok_or_else(|| { + let handle_payment_contract_hash = + system_entity_registry.get(HANDLE_PAYMENT).ok_or_else(|| { error!("Missing system handle payment contract hash"); Error::MissingSystemContractHash(HANDLE_PAYMENT.to_string()) })?; @@ -972,8 +939,7 @@ where Err(error) => return Ok(ExecutionResult::precondition_failure(error.into())), }; - let handle_payment_addr = - EntityAddr::new_system_entity_addr(handle_payment_contract_hash.value()); + let handle_payment_addr = EntityAddr::new_system(handle_payment_contract_hash.value()); let handle_payment_named_keys = match finalization_tc .borrow_mut() @@ -1000,8 +966,8 @@ where EntityKind::Account(system_account_hash), authorization_keys, system_account_hash, - blocktime, - deploy_hash, + block_time, + transaction_hash, gas_limit, protocol_version, finalization_tc, @@ -1110,15 +1076,15 @@ where ) -> EraValidatorsResult { let state_root_hash = get_era_validators_request.state_hash(); - let system_contract_registry = match self.get_system_contract_registry(state_root_hash) { - Ok(system_contract_registry) => system_contract_registry, + let system_entity_registry = match self.get_system_entity_registry(state_root_hash) { + Ok(system_entity_registry) => system_entity_registry, Err(error) => { error!(%state_root_hash, %error, "auction not found"); return EraValidatorsResult::AuctionNotFound; } }; - let query_request = match system_contract_registry.get(AUCTION).copied() { + let query_request = match system_entity_registry.get(AUCTION).copied() { Some(auction_hash) => QueryRequest::new( state_root_hash, Key::addressable_entity_key(EntityKindTag::System, auction_hash), @@ -1233,11 +1199,11 @@ where let gas_limit = Gas::new(U512::from(std::u64::MAX)); - let deploy_hash = { + let txn_hash = { // seeds address generator w/ era_end_timestamp_millis let mut bytes = time.into_bytes()?; bytes.append(&mut next_block_height.into_bytes()?); - DeployHash::new(Digest::hash(&bytes)) + TransactionHash::V1(TransactionV1Hash::new(Digest::hash(&bytes))) }; let system_account_hash = PublicKey::System.to_account_hash(); @@ -1253,7 +1219,7 @@ where authorization_keys.clone(), system_account_hash, BlockTime::default(), - deploy_hash, + txn_hash, gas_limit, protocol_version, Rc::clone(&tracking_copy), @@ -1282,7 +1248,7 @@ where authorization_keys, system_account_hash, BlockTime::default(), - deploy_hash, + txn_hash, gas_limit, protocol_version, Rc::clone(&tracking_copy), @@ -1334,11 +1300,11 @@ where }; let gas_limit = Gas::new(U512::from(std::u64::MAX)); - let deploy_hash = { + let txn_hash = { // seeds address generator w/ era_end_timestamp_millis let mut bytes = step_request.era_end_timestamp_millis.into_bytes()?; bytes.append(&mut step_request.next_era_id.into_bytes()?); - DeployHash::new(Digest::hash(&bytes)) + TransactionHash::V1(TransactionV1Hash::new(Digest::hash(&bytes))) }; let slashed_validators: Vec = step_request.slashed_validators(); @@ -1363,7 +1329,7 @@ where authorization_keys.clone(), system_account_hash, BlockTime::default(), - deploy_hash, + txn_hash, gas_limit, step_request.protocol_version, Rc::clone(&tracking_copy), @@ -1404,7 +1370,7 @@ where authorization_keys, system_account_hash, BlockTime::default(), - deploy_hash, + txn_hash, gas_limit, step_request.protocol_version, Rc::clone(&tracking_copy), @@ -1491,8 +1457,8 @@ where Ok(BalanceResult::Success { motes, proof }) } - /// Obtains an instance of a system contract registry for a given state root hash. - pub fn get_system_contract_registry( + /// Obtains an instance of a system entity registry for a given state root hash. + pub fn get_system_entity_registry( &self, state_root_hash: Digest, ) -> Result { @@ -1504,15 +1470,15 @@ where .borrow_mut() .get_system_entity_registry() .map_err(|error| { - warn!(%error, "Failed to retrieve system contract registry"); - Error::MissingSystemContractRegistry + warn!(%error, "Failed to retrieve system entity registry"); + Error::MissingSystemEntityRegistry }); result } /// Returns mint system contract hash. pub fn get_system_mint_hash(&self, state_hash: Digest) -> Result { - let registry = self.get_system_contract_registry(state_hash)?; + let registry = self.get_system_entity_registry(state_hash)?; let mint_hash = registry.get(MINT).ok_or_else(|| { error!("Missing system mint contract hash"); Error::MissingSystemContractHash(MINT.to_string()) @@ -1525,7 +1491,7 @@ where &self, state_hash: Digest, ) -> Result { - let registry = self.get_system_contract_registry(state_hash)?; + let registry = self.get_system_entity_registry(state_hash)?; let auction_hash = registry.get(AUCTION).ok_or_else(|| { error!("Missing system auction contract hash"); Error::MissingSystemContractHash(AUCTION.to_string()) @@ -1538,7 +1504,7 @@ where &self, state_hash: Digest, ) -> Result { - let registry = self.get_system_contract_registry(state_hash)?; + let registry = self.get_system_entity_registry(state_hash)?; let handle_payment = registry.get(HANDLE_PAYMENT).ok_or_else(|| { error!("Missing system handle payment contract hash"); Error::MissingSystemContractHash(HANDLE_PAYMENT.to_string()) @@ -1557,12 +1523,12 @@ fn log_execution_result(preamble: &'static str, result: &ExecutionResult) { match result { ExecutionResult::Success { transfers, - cost, + gas, effects, messages, } => { debug!( - %cost, + %gas, transfer_count = %transfers.len(), transforms_count = %effects.len(), messages_count = %messages.len(), @@ -1573,13 +1539,13 @@ fn log_execution_result(preamble: &'static str, result: &ExecutionResult) { ExecutionResult::Failure { error, transfers, - cost, + gas, effects, messages, } => { debug!( %error, - %cost, + %gas, transfer_count = %transfers.len(), transforms_count = %effects.len(), messages_count = %messages.len(), @@ -1595,7 +1561,7 @@ fn should_charge_for_errors_in_wasm(execution_result: &ExecutionResult) -> bool ExecutionResult::Failure { error, transfers: _, - cost: _, + gas: _, effects: _, messages: _, } => match error { @@ -1643,7 +1609,7 @@ fn should_charge_for_errors_in_wasm(execution_result: &ExecutionResult) -> bool | ExecError::InvalidEntity(_) | ExecError::MissingArgument { .. } | ExecError::DictionaryItemKeyExceedsLength - | ExecError::MissingSystemContractRegistry + | ExecError::MissingSystemEntityRegistry | ExecError::MissingSystemContractHash(_) | ExecError::RuntimeStackOverflow | ExecError::ValueTooLarge @@ -1655,11 +1621,10 @@ fn should_charge_for_errors_in_wasm(execution_result: &ExecutionResult) -> bool | ExecError::Transform(_) | ExecError::InvalidEntryPointType | ExecError::InvalidMessageTopicOperation - | ExecError::InvalidUtf8Encoding(_) => false, - ExecError::DisabledUnrestrictedTransfers => false, + | ExecError::InvalidUtf8Encoding(_) + | ExecError::DisabledUnrestrictedTransfers => false, }, - Error::WasmPreprocessing(_) => true, - Error::WasmSerialization(_) => true, + Error::WasmPreprocessing(_) | Error::WasmSerialization(_) => true, Error::RootNotFound(_) | Error::InvalidProtocolVersion(_) | Error::Genesis(_) @@ -1676,8 +1641,9 @@ fn should_charge_for_errors_in_wasm(execution_result: &ExecutionResult) -> bool | Error::InvalidKeyVariant | Error::ProtocolUpgrade(_) | Error::InvalidDeployItemVariant(_) + | Error::EmptyCustomPaymentModuleBytes | Error::CommitError(_) - | Error::MissingSystemContractRegistry + | Error::MissingSystemEntityRegistry | Error::MissingSystemContractHash(_) | Error::MissingChecksumRegistry | Error::RuntimeStackOverflow diff --git a/execution_engine/src/execution/error.rs b/execution_engine/src/execution/error.rs index 61e913ea86..2c64c2f4dd 100644 --- a/execution_engine/src/execution/error.rs +++ b/execution_engine/src/execution/error.rs @@ -164,9 +164,9 @@ pub enum Error { /// Error writing a dictionary item key which exceeded maximum allowed length. #[error("Dictionary item key exceeded maximum length")] DictionaryItemKeyExceedsLength, - /// Missing system contract registry. - #[error("Missing system contract registry")] - MissingSystemContractRegistry, + /// Missing system entity registry. + #[error("Missing system entity registry")] + MissingSystemEntityRegistry, /// Missing system contract hash. #[error("Missing system contract hash: {0}")] MissingSystemContractHash(String), diff --git a/execution_engine/src/execution/executor.rs b/execution_engine/src/execution/executor.rs index 4c03b68b73..0aac111b59 100644 --- a/execution_engine/src/execution/executor.rs +++ b/execution_engine/src/execution/executor.rs @@ -12,8 +12,8 @@ use casper_types::{ bytesrepr::FromBytes, system::{auction, handle_payment, mint, AUCTION, HANDLE_PAYMENT, MINT}, AddressableEntity, AddressableEntityHash, ApiError, BlockTime, CLTyped, ContextAccessRights, - DeployHash, EntityAddr, EntryPointType, Gas, Key, Phase, ProtocolVersion, RuntimeArgs, - StoredValue, Tagged, URef, U512, + EntityAddr, EntryPointType, Gas, Key, Phase, ProtocolVersion, RuntimeArgs, StoredValue, Tagged, + TransactionHash, URef, U512, }; use crate::{ @@ -59,7 +59,7 @@ impl Executor { authorization_keys: BTreeSet, account_hash: AccountHash, blocktime: BlockTime, - deploy_hash: DeployHash, + txn_hash: TransactionHash, gas_limit: Gas, protocol_version: ProtocolVersion, tracking_copy: Rc>>, @@ -77,7 +77,11 @@ impl Executor { }; let address_generator = { - let generator = AddressGenerator::new(deploy_hash.as_ref(), phase); + let hash_slice = match &txn_hash { + TransactionHash::Deploy(hash) => hash.as_ref(), + TransactionHash::V1(hash) => hash.as_ref(), + }; + let generator = AddressGenerator::new(hash_slice, phase); Rc::new(RefCell::new(generator)) }; @@ -95,7 +99,7 @@ impl Executor { tracking_copy, blocktime, protocol_version, - deploy_hash, + txn_hash, phase, args.clone(), gas_limit, @@ -106,17 +110,20 @@ impl Executor { let mut runtime = Runtime::new(context); let result = match execution_kind { - ExecutionKind::Module(module_bytes) => { - runtime.execute_module_bytes(&module_bytes, stack) + ExecutionKind::Standard(module_bytes) + | ExecutionKind::Installer(module_bytes) + | ExecutionKind::Upgrader(module_bytes) + | ExecutionKind::Isolated(module_bytes) => { + runtime.execute_module_bytes(module_bytes, stack) } - ExecutionKind::Contract { - entity_hash: contract_hash, - entry_point_name, + ExecutionKind::Stored { + entity_hash, + entry_point, } => { // These args are passed through here as they are required to construct the new // `Runtime` during the contract's execution (i.e. inside // `Runtime::execute_contract`). - runtime.call_contract_with_stack(contract_hash, &entry_point_name, args, stack) + runtime.call_contract_with_stack(entity_hash, &entry_point, args, stack) } }; @@ -124,14 +131,14 @@ impl Executor { Ok(_) => ExecutionResult::Success { effects: runtime.context().effects(), transfers: runtime.context().transfers().to_owned(), - cost: runtime.context().gas_counter(), + gas: runtime.context().gas_counter(), messages: runtime.context().messages(), }, Err(error) => ExecutionResult::Failure { error: error.into(), effects: runtime.context().effects(), transfers: runtime.context().transfers().to_owned(), - cost: runtime.context().gas_counter(), + gas: runtime.context().gas_counter(), messages: runtime.context().messages(), }, } @@ -149,7 +156,7 @@ impl Executor { authorization_keys: BTreeSet, account_hash: AccountHash, blocktime: BlockTime, - deploy_hash: DeployHash, + txn_hash: TransactionHash, gas_limit: Gas, protocol_version: ProtocolVersion, tracking_copy: Rc>>, @@ -162,14 +169,18 @@ impl Executor { T: FromBytes + CLTyped, { let address_generator = { - let generator = AddressGenerator::new(deploy_hash.as_ref(), phase); + let hash_slice = match &txn_hash { + TransactionHash::Deploy(hash) => hash.as_ref(), + TransactionHash::V1(hash) => hash.as_ref(), + }; + let generator = AddressGenerator::new(hash_slice, phase); Rc::new(RefCell::new(generator)) }; - // Today lack of existence of the system contract registry and lack of entry + // Today lack of existence of the system entity registry and lack of entry // for the minimum defined system contracts (mint, auction, handle_payment) // should cause the EE to panic. Do not remove the panics. - let system_contract_registry = tracking_copy + let system_entity_registry = tracking_copy .borrow_mut() .get_system_entity_registry() .unwrap_or_else(|error| panic!("Could not retrieve system contracts: {:?}", error)); @@ -185,13 +196,13 @@ impl Executor { DirectSystemContractCall::Slash | DirectSystemContractCall::RunAuction | DirectSystemContractCall::DistributeRewards => { - let auction_hash = system_contract_registry + let auction_hash = system_entity_registry .get(AUCTION) .expect("should have auction hash"); *auction_hash } DirectSystemContractCall::Transfer => { - let mint_hash = system_contract_registry + let mint_hash = system_entity_registry .get(MINT) .expect("should have mint hash"); *mint_hash @@ -199,7 +210,7 @@ impl Executor { DirectSystemContractCall::FinalizePayment | DirectSystemContractCall::GetPaymentPurse | DirectSystemContractCall::DistributeAccumulatedFees => { - let handle_payment_hash = system_contract_registry + let handle_payment_hash = system_entity_registry .get(HANDLE_PAYMENT) .expect("should have handle payment"); *handle_payment_hash @@ -214,7 +225,7 @@ impl Executor { Err(error) => return (None, ExecutionResult::precondition_failure(error.into())), }; - let entity_addr = EntityAddr::new_with_tag(entity_kind, entity_hash.value()); + let entity_addr = EntityAddr::new_of_kind(entity_kind, entity_hash.value()); let mut named_keys = match tracking_copy.borrow_mut().get_named_keys(entity_addr) { Ok(named_key) => named_key, @@ -235,7 +246,7 @@ impl Executor { tracking_copy, blocktime, protocol_version, - deploy_hash, + txn_hash, phase, runtime_args.clone(), gas_limit, @@ -258,7 +269,7 @@ impl Executor { Ok(ret) => ExecutionResult::Success { effects: runtime.context().effects(), transfers: runtime.context().transfers().to_owned(), - cost: runtime.context().gas_counter(), + gas: runtime.context().gas_counter(), messages: runtime.context().messages(), } .take_with_ret(ret), @@ -266,7 +277,7 @@ impl Executor { effects, error: Error::CLValue(error).into(), transfers: runtime.context().transfers().to_owned(), - cost: runtime.context().gas_counter(), + gas: runtime.context().gas_counter(), messages, } .take_without_ret(), @@ -275,7 +286,7 @@ impl Executor { effects, error: error.into(), transfers: runtime.context().transfers().to_owned(), - cost: runtime.context().gas_counter(), + gas: runtime.context().gas_counter(), messages, } .take_without_ret(), @@ -297,7 +308,7 @@ impl Executor { tracking_copy: Rc>>, blocktime: BlockTime, protocol_version: ProtocolVersion, - deploy_hash: DeployHash, + txn_hash: TransactionHash, phase: Phase, runtime_args: RuntimeArgs, gas_limit: Gas, @@ -323,7 +334,7 @@ impl Executor { self.config.clone(), blocktime, protocol_version, - deploy_hash, + txn_hash, phase, runtime_args, gas_limit, @@ -344,7 +355,7 @@ impl Executor { authorization_keys: BTreeSet, account_hash: AccountHash, blocktime: BlockTime, - deploy_hash: DeployHash, + txn_hash: TransactionHash, payment_gas_limit: Gas, protocol_version: ProtocolVersion, tracking_copy: Rc>>, @@ -369,7 +380,7 @@ impl Executor { authorization_keys.clone(), account_hash, blocktime, - deploy_hash, + txn_hash, payment_gas_limit, protocol_version, Rc::clone(&tracking_copy), @@ -413,7 +424,7 @@ impl Executor { authorization_keys, account_hash, blocktime, - deploy_hash, + txn_hash, payment_gas_limit, protocol_version, Rc::clone(&tracking_copy), @@ -447,7 +458,7 @@ impl Executor { authorization_keys: BTreeSet, account_hash: AccountHash, blocktime: BlockTime, - deploy_hash: DeployHash, + txn_hash: TransactionHash, payment_gas_limit: Gas, protocol_version: ProtocolVersion, tracking_copy: Rc>>, @@ -465,7 +476,7 @@ impl Executor { authorization_keys, account_hash, blocktime, - deploy_hash, + txn_hash, payment_gas_limit, protocol_version, Rc::clone(&tracking_copy), @@ -484,7 +495,7 @@ impl Executor { authorization_keys: BTreeSet, account_hash: AccountHash, blocktime: BlockTime, - deploy_hash: DeployHash, + txn_hash: TransactionHash, gas_limit: Gas, protocol_version: ProtocolVersion, tracking_copy: Rc>>, @@ -503,7 +514,7 @@ impl Executor { authorization_keys, account_hash, blocktime, - deploy_hash, + txn_hash, gas_limit, protocol_version, Rc::clone(&tracking_copy), diff --git a/execution_engine/src/runtime/externals.rs b/execution_engine/src/runtime/externals.rs index 1d9c9f7b70..e58504c7c9 100644 --- a/execution_engine/src/runtime/externals.rs +++ b/execution_engine/src/runtime/externals.rs @@ -10,11 +10,10 @@ use casper_types::{ bytesrepr::{self, ToBytes}, contract_messages::MessageTopicOperation, crypto, - package::PackageStatus, system::auction::EraInfo, AddressableEntityHash, ApiError, EntityVersion, EraId, Gas, Group, HostFunction, - HostFunctionCost, Key, PackageHash, StoredValue, URef, DEFAULT_HOST_FUNCTION_NEW_DICTIONARY, - U512, UREF_SERIALIZED_LENGTH, + HostFunctionCost, Key, PackageHash, PackageStatus, StoredValue, URef, + DEFAULT_HOST_FUNCTION_NEW_DICTIONARY, U512, UREF_SERIALIZED_LENGTH, }; use super::{args::Args, Error, Runtime}; @@ -192,7 +191,7 @@ where let (gas_arg,): (u32,) = Args::parse(args)?; // Gas is special cased internal host function and for accounting purposes it isn't // represented in protocol data. - self.gas(Gas::new(gas_arg.into()))?; + self.gas(Gas::new(gas_arg))?; Ok(None) } diff --git a/execution_engine/src/runtime/mint_internal.rs b/execution_engine/src/runtime/mint_internal.rs index 89ad583457..2885e15b21 100644 --- a/execution_engine/src/runtime/mint_internal.rs +++ b/execution_engine/src/runtime/mint_internal.rs @@ -72,9 +72,9 @@ where } fn get_system_entity_registry(&self) -> Result { - self.context.system_contract_registry().map_err(|err| { - error!(%err, "unable to obtain system contract registry during transfer"); - ProviderError::SystemContractRegistry + self.context.system_entity_registry().map_err(|err| { + error!(%err, "unable to obtain system entity registry during transfer"); + ProviderError::SystemEntityRegistry }) } diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index 0dd33d8f34..2caa4dc011 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -42,7 +42,6 @@ use casper_types::{ }, contracts::ContractPackage, crypto, - package::PackageStatus, system::{ self, auction::{self, EraInfo}, @@ -50,10 +49,10 @@ use casper_types::{ STANDARD_PAYMENT, }, AccessRights, ApiError, ByteCode, ByteCodeAddr, ByteCodeHash, ByteCodeKind, CLTyped, CLValue, - ContextAccessRights, ContractWasm, DeployHash, EntityAddr, EntityKind, EntityVersion, - EntityVersionKey, EntityVersions, Gas, GrantedAccess, Group, Groups, HostFunction, - HostFunctionCost, Key, NamedArg, Package, PackageHash, Phase, PublicKey, RuntimeArgs, - StoredValue, Tagged, Transfer, TransferResult, TransferredTo, URef, + ContextAccessRights, ContractWasm, EntityAddr, EntityKind, EntityVersion, EntityVersionKey, + EntityVersions, Gas, GrantedAccess, Group, Groups, HostFunction, HostFunctionCost, + InitiatorAddr, Key, NamedArg, Package, PackageHash, PackageStatus, Phase, PublicKey, + RuntimeArgs, StoredValue, Tagged, Transfer, TransferResult, TransferredTo, URef, DICTIONARY_ITEM_KEY_MAX_LENGTH, U512, }; @@ -565,7 +564,7 @@ where let gas_counter = self.gas_counter(); let mint_hash = self.context.get_system_contract(MINT)?; - let mint_addr = EntityAddr::new_system_entity_addr(mint_hash.value()); + let mint_addr = EntityAddr::new_system(mint_hash.value()); let mint_named_keys = self .context @@ -1244,7 +1243,7 @@ where } }; - if let EntityKind::Account(_) = entity.entity_kind() { + if let EntityKind::Account(_) = entity.kind() { return Err(Error::InvalidContext); } @@ -1365,7 +1364,7 @@ where all_urefs }; - let entity_addr = EntityAddr::new_with_tag(entity.entity_kind(), entity_hash.value()); + let entity_addr = EntityAddr::new_of_kind(entity.kind(), entity_hash.value()); let entity_named_keys = self .context @@ -1387,7 +1386,7 @@ where stack }; - if let EntityKind::System(system_contract_type) = entity.entity_kind() { + if let EntityKind::System(system_contract_type) = entity.kind() { let entry_point_name = entry_point.name(); match system_contract_type { @@ -1423,7 +1422,7 @@ where let module: Module = { let byte_code_addr = entity.byte_code_addr(); - let byte_code_key = match entity.entity_kind() { + let byte_code_key = match entity.kind() { EntityKind::System(_) | EntityKind::Account(_) => { Key::ByteCode(ByteCodeAddr::Empty) } @@ -1441,7 +1440,7 @@ where casper_wasm::deserialize_buffer(byte_code.bytes())? }; - let entity_tag = entity.entity_kind().tag(); + let entity_tag = entity.kind().tag(); let mut named_keys = entity_named_keys; @@ -1768,13 +1767,13 @@ where byte_code, )?; - let entity_kind = updated_session_entity.entity_kind(); + let entity_kind = updated_session_entity.kind(); if entity_kind != EntityKind::SmartContract { return Err(Error::InvalidContext); } - let entity_addr = EntityAddr::new_contract_entity_addr(entity_hash.value()); + let entity_addr = EntityAddr::new_smart_contract(entity_hash.value()); self.context .metered_write_gs_unsafe(Key::AddressableEntity(entity_addr), updated_session_entity)?; @@ -1830,7 +1829,7 @@ where byte_code, )?; - let entity_addr = EntityAddr::new_contract_entity_addr(entity_hash); + let entity_addr = EntityAddr::new_smart_contract(entity_hash); let entity_key = Key::AddressableEntity(entity_addr); @@ -2056,10 +2055,11 @@ where let transfer_addr = self.context.new_transfer_addr()?; let transfer = { - let deploy_hash: DeployHash = self.context.get_deploy_hash(); - let from: AccountHash = self.context.get_caller(); - let fee: U512 = U512::zero(); // TODO - Transfer::new(deploy_hash, from, maybe_to, source, target, amount, fee, id) + // TODO - update once decision is made on recording transfers. + let txn_hash = self.context.get_transaction_hash(); + let from = InitiatorAddr::AccountHash(self.context.get_caller()); + let fee = Gas::zero(); // TODO + Transfer::new(txn_hash, from, maybe_to, source, target, amount, fee, id) }; { let transfers = self.context.transfers_mut(); @@ -3363,7 +3363,7 @@ where AssociatedKeys::default() }; - let contract_addr = EntityAddr::new_contract_entity_addr(contract_hash.value()); + let contract_addr = EntityAddr::new_smart_contract(contract_hash.value()); self.context .write_named_keys(contract_addr, contract.named_keys().clone())?; diff --git a/execution_engine/src/runtime_context/mod.rs b/execution_engine/src/runtime_context/mod.rs index 8dfbe0379c..1690952cc5 100644 --- a/execution_engine/src/runtime_context/mod.rs +++ b/execution_engine/src/runtime_context/mod.rs @@ -33,10 +33,10 @@ use casper_types::{ handle_stored_dictionary_value, system::auction::EraInfo, AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, CLType, CLValue, - CLValueDictionary, ContextAccessRights, DeployHash, EntityAddr, EntryPointType, Gas, - GrantedAccess, Key, KeyTag, Package, PackageHash, Phase, ProtocolVersion, PublicKey, - RuntimeArgs, StoredValue, StoredValueTypeMismatch, SystemEntityRegistry, Transfer, - TransferAddr, URef, URefAddr, DICTIONARY_ITEM_KEY_MAX_LENGTH, KEY_HASH_LENGTH, U512, + CLValueDictionary, ContextAccessRights, EntityAddr, EntryPointType, Gas, GrantedAccess, Key, + KeyTag, Package, PackageHash, Phase, ProtocolVersion, PublicKey, RuntimeArgs, StoredValue, + StoredValueTypeMismatch, SystemEntityRegistry, TransactionHash, Transfer, TransferAddr, URef, + URefAddr, DICTIONARY_ITEM_KEY_MAX_LENGTH, KEY_HASH_LENGTH, U512, }; use crate::{engine_state::EngineConfig, execution::Error}; @@ -54,7 +54,7 @@ pub struct RuntimeContext<'a, R> { args: RuntimeArgs, authorization_keys: BTreeSet, blocktime: BlockTime, - deploy_hash: DeployHash, + transaction_hash: TransactionHash, gas_limit: Gas, gas_counter: Gas, address_generator: Rc>, @@ -96,9 +96,9 @@ where engine_config: EngineConfig, blocktime: BlockTime, protocol_version: ProtocolVersion, - deploy_hash: DeployHash, + transaction_hash: TransactionHash, phase: Phase, - runtime_args: RuntimeArgs, + args: RuntimeArgs, gas_limit: Gas, gas_counter: Gas, transfers: Vec, @@ -116,13 +116,13 @@ where entry_point_type, named_keys, access_rights, - args: runtime_args, + args, entity, entity_key, authorization_keys, account_hash, blocktime, - deploy_hash, + transaction_hash, gas_limit, gas_counter, address_generator, @@ -157,7 +157,7 @@ where let blocktime = self.blocktime; let protocol_version = self.protocol_version; - let deploy_hash = self.deploy_hash; + let transaction_hash = self.transaction_hash; let phase = self.phase; let gas_limit = self.gas_limit; @@ -177,7 +177,7 @@ where authorization_keys, account_hash, blocktime, - deploy_hash, + transaction_hash, gas_limit, gas_counter, address_generator, @@ -264,9 +264,9 @@ where self.blocktime } - /// Returns the deploy hash. - pub fn get_deploy_hash(&self) -> DeployHash { - self.deploy_hash + /// Returns the transaction hash. + pub fn get_transaction_hash(&self) -> TransactionHash { + self.transaction_hash } /// Extends access rights with a new map. @@ -690,6 +690,7 @@ where self.validate_cl_value(named_key_value.get_key_as_cl_value())?; self.validate_cl_value(named_key_value.get_name_as_cl_value()) } + StoredValue::TransactionInfo(_) => Ok(()), } } @@ -770,10 +771,11 @@ where | Key::ChecksumRegistry | Key::BidAddr(_) | Key::Package(_) - | Key::AddressableEntity(..) - | Key::ByteCode(..) + | Key::AddressableEntity(_) + | Key::ByteCode(_) | Key::Message(_) - | Key::NamedKey(_) => true, + | Key::NamedKey(_) + | Key::TransactionInfo(_) => true, } } @@ -809,7 +811,8 @@ where | Key::BidAddr(_) | Key::Package(_) | Key::ByteCode(..) - | Key::Message(_) => false, + | Key::Message(_) + | Key::TransactionInfo(_) => false, } } @@ -842,7 +845,8 @@ where | Key::Package(_) | Key::AddressableEntity(..) | Key::ByteCode(..) - | Key::Message(_) => false, + | Key::Message(_) + | Key::TransactionInfo(_) => false, } } @@ -879,7 +883,7 @@ where contract_hash: &AddressableEntityHash, ) -> Result { Ok(self - .system_contract_registry()? + .system_entity_registry()? .has_contract_hash(contract_hash)) } @@ -1357,7 +1361,7 @@ where /// Gets system contract by name. pub(crate) fn get_system_contract(&self, name: &str) -> Result { - let registry = self.system_contract_registry()?; + let registry = self.system_entity_registry()?; let hash = registry.get(name).ok_or_else(|| { error!("Missing system contract hash: {}", name); Error::MissingSystemContractHash(name.to_string()) @@ -1373,13 +1377,13 @@ where )) } - /// Returns system contract registry by querying the global state. - pub fn system_contract_registry(&self) -> Result { + /// Returns system entity registry by querying the global state. + pub fn system_entity_registry(&self) -> Result { self.tracking_copy .borrow_mut() .get_system_entity_registry() .map_err(|err| { - error!("Missing system contract registry"); + error!("Missing system entity registry"); Error::TrackingCopy(err) }) } diff --git a/execution_engine/src/runtime_context/tests.rs b/execution_engine/src/runtime_context/tests.rs index e25b1d9cae..cdaa963e6e 100644 --- a/execution_engine/src/runtime_context/tests.rs +++ b/execution_engine/src/runtime_context/tests.rs @@ -18,16 +18,17 @@ use casper_types::{ execution::TransformKind, system::{AUCTION, HANDLE_PAYMENT, MINT, STANDARD_PAYMENT}, AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, ByteCodeHash, CLValue, - ContextAccessRights, DeployHash, EntityAddr, EntityKind, EntryPointType, EntryPoints, Gas, Key, + ContextAccessRights, EntityAddr, EntityKind, EntryPointType, EntryPoints, Gas, Key, PackageHash, Phase, ProtocolVersion, PublicKey, RuntimeArgs, SecretKey, StoredValue, - SystemEntityRegistry, Tagged, URef, KEY_HASH_LENGTH, U256, U512, + SystemEntityRegistry, Tagged, TransactionHash, TransactionV1Hash, URef, KEY_HASH_LENGTH, U256, + U512, }; use tempfile::TempDir; use super::{Error, RuntimeContext}; use crate::engine_state::EngineConfig; -const DEPLOY_HASH: [u8; 32] = [1u8; 32]; +const TXN_HASH_RAW: [u8; 32] = [1u8; 32]; const PHASE: Phase = Phase::Session; const GAS_LIMIT: u64 = 500_000_000_000_000u64; @@ -154,7 +155,7 @@ fn new_runtime_context<'a>( TEST_ENGINE_CONFIG.clone(), BlockTime::new(0), ProtocolVersion::V1_0_0, - DeployHash::from_raw([1u8; 32]), + TransactionHash::V1(TransactionV1Hash::from_raw([1u8; 32])), Phase::Session, RuntimeArgs::new(), Gas::new(U512::from(GAS_LIMIT)), @@ -233,7 +234,7 @@ fn last_transform_kind_on_addressable_entity( #[test] fn use_uref_valid() { // Test fixture - let mut rng = AddressGenerator::new(&DEPLOY_HASH, PHASE); + let mut rng = AddressGenerator::new(&TXN_HASH_RAW, PHASE); let uref_as_key = create_uref_as_key(&mut rng, AccessRights::READ_WRITE); let mut named_keys = NamedKeys::new(); named_keys.insert(String::new(), uref_as_key); @@ -249,7 +250,7 @@ fn use_uref_valid() { #[test] fn use_uref_forged() { // Test fixture - let mut rng = AddressGenerator::new(&DEPLOY_HASH, PHASE); + let mut rng = AddressGenerator::new(&TXN_HASH_RAW, PHASE); let uref = create_uref_as_key(&mut rng, AccessRights::READ_WRITE); let named_keys = NamedKeys::new(); // named_keys.insert(String::new(), Key::from(uref)); @@ -297,7 +298,7 @@ fn entity_key_readable_valid() { fn account_key_addable_returns_type_mismatch() { // Account key is not addable anymore as we do not store an account underneath they key // but instead there is a CLValue which acts as an indirection to the corresponding entity. - let mut rng = AddressGenerator::new(&DEPLOY_HASH, PHASE); + let mut rng = AddressGenerator::new(&TXN_HASH_RAW, PHASE); let uref_as_key = create_uref_as_key(&mut rng, AccessRights::READ); let mut named_keys = NamedKeys::new(); named_keys.insert(String::new(), uref_as_key); @@ -364,7 +365,7 @@ fn contract_key_addable_valid() { let entity_hash = AddressableEntityHash::new([1u8; 32]); let (_account_key, entity_key, entity) = new_addressable_entity(account_hash, entity_hash); let authorization_keys = BTreeSet::from_iter(vec![account_hash]); - let mut address_generator = AddressGenerator::new(&DEPLOY_HASH, PHASE); + let mut address_generator = AddressGenerator::new(&TXN_HASH_RAW, PHASE); let mut rng = rand::thread_rng(); let contract_key = random_contract_key(&mut rng); @@ -418,7 +419,7 @@ fn contract_key_addable_valid() { EngineConfig::default(), BlockTime::new(0), ProtocolVersion::V1_0_0, - DeployHash::from_raw(DEPLOY_HASH), + TransactionHash::V1(TransactionV1Hash::from_raw(TXN_HASH_RAW)), PHASE, RuntimeArgs::new(), Gas::new(U512::from(GAS_LIMIT)), @@ -439,7 +440,7 @@ fn contract_key_addable_invalid() { let entity_hash = AddressableEntityHash::new([1u8; 32]); let (_, entity_key, entity) = new_addressable_entity(account_hash, entity_hash); let authorization_keys = BTreeSet::from_iter(vec![account_hash]); - let mut address_generator = AddressGenerator::new(&DEPLOY_HASH, PHASE); + let mut address_generator = AddressGenerator::new(&TXN_HASH_RAW, PHASE); let mut rng = rand::thread_rng(); let contract_key = random_contract_key(&mut rng); @@ -476,7 +477,7 @@ fn contract_key_addable_invalid() { EngineConfig::default(), BlockTime::new(0), ProtocolVersion::V1_0_0, - DeployHash::from_raw(DEPLOY_HASH), + TransactionHash::V1(TransactionV1Hash::from_raw(TXN_HASH_RAW)), PHASE, RuntimeArgs::new(), Gas::new(U512::from(GAS_LIMIT)), @@ -493,7 +494,7 @@ fn contract_key_addable_invalid() { #[test] fn uref_key_readable_valid() { - let mut rng = AddressGenerator::new(&DEPLOY_HASH, PHASE); + let mut rng = AddressGenerator::new(&TXN_HASH_RAW, PHASE); let uref_key = create_uref_as_key(&mut rng, AccessRights::READ); let mut named_keys = NamedKeys::new(); @@ -506,7 +507,7 @@ fn uref_key_readable_valid() { #[test] fn uref_key_readable_invalid() { - let mut rng = AddressGenerator::new(&DEPLOY_HASH, PHASE); + let mut rng = AddressGenerator::new(&TXN_HASH_RAW, PHASE); let uref_key = create_uref_as_key(&mut rng, AccessRights::WRITE); let mut named_keys = NamedKeys::new(); @@ -519,7 +520,7 @@ fn uref_key_readable_invalid() { #[test] fn uref_key_writeable_valid() { - let mut rng = AddressGenerator::new(&DEPLOY_HASH, PHASE); + let mut rng = AddressGenerator::new(&TXN_HASH_RAW, PHASE); let uref_key = create_uref_as_key(&mut rng, AccessRights::WRITE); let mut named_keys = NamedKeys::new(); @@ -536,7 +537,7 @@ fn uref_key_writeable_valid() { #[test] fn uref_key_writeable_invalid() { - let mut rng = AddressGenerator::new(&DEPLOY_HASH, PHASE); + let mut rng = AddressGenerator::new(&TXN_HASH_RAW, PHASE); let uref_key = create_uref_as_key(&mut rng, AccessRights::READ); let mut named_keys = NamedKeys::new(); @@ -553,7 +554,7 @@ fn uref_key_writeable_invalid() { #[test] fn uref_key_addable_valid() { - let mut rng = AddressGenerator::new(&DEPLOY_HASH, PHASE); + let mut rng = AddressGenerator::new(&TXN_HASH_RAW, PHASE); let uref_key = create_uref_as_key(&mut rng, AccessRights::ADD_WRITE); let mut named_keys = NamedKeys::new(); @@ -569,7 +570,7 @@ fn uref_key_addable_valid() { #[test] fn uref_key_addable_invalid() { - let mut rng = AddressGenerator::new(&DEPLOY_HASH, PHASE); + let mut rng = AddressGenerator::new(&TXN_HASH_RAW, PHASE); let uref_key = create_uref_as_key(&mut rng, AccessRights::WRITE); let mut named_keys = NamedKeys::new(); @@ -978,7 +979,7 @@ fn validate_valid_purse_of_an_account() { #[test] fn should_meter_for_gas_storage_write() { // Test fixture - let mut rng = AddressGenerator::new(&DEPLOY_HASH, PHASE); + let mut rng = AddressGenerator::new(&TXN_HASH_RAW, PHASE); let uref_as_key = create_uref_as_key(&mut rng, AccessRights::READ_WRITE); let mut named_keys = NamedKeys::new(); @@ -1013,7 +1014,7 @@ fn should_meter_for_gas_storage_write() { #[test] fn should_meter_for_gas_storage_add() { // Test fixture - let mut rng = AddressGenerator::new(&DEPLOY_HASH, PHASE); + let mut rng = AddressGenerator::new(&TXN_HASH_RAW, PHASE); let uref_as_key = create_uref_as_key(&mut rng, AccessRights::ADD_WRITE); let mut named_keys = NamedKeys::new(); diff --git a/execution_engine_testing/test_support/src/auction.rs b/execution_engine_testing/test_support/src/auction.rs deleted file mode 100644 index 99ffdd20ef..0000000000 --- a/execution_engine_testing/test_support/src/auction.rs +++ /dev/null @@ -1,386 +0,0 @@ -use std::{collections::HashSet, convert::TryFrom, io::Write, time::Instant}; - -use lmdb::{Cursor, Transaction}; -use rand::Rng; -use tempfile::TempDir; - -use casper_execution_engine::engine_state::{EngineState, ExecuteRequest}; -use casper_storage::{ - data_access_layer::GenesisRequest, - global_state::{ - state::{CommitProvider, StateProvider}, - trie::{Pointer, Trie}, - }, -}; -use casper_types::{ - account::AccountHash, - bytesrepr::{self}, - runtime_args, - system::auction, - ChainspecRegistry, Digest, GenesisAccount, GenesisConfigBuilder, GenesisValidator, Key, Motes, - ProtocolVersion, PublicKey, SecretKey, StoredValue, DEFAULT_REFUND_HANDLING, U512, -}; - -use crate::{ - transfer, DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, StepRequestBuilder, - DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_ACCOUNT_PUBLIC_KEY, - DEFAULT_AUCTION_DELAY, DEFAULT_FEE_HANDLING, DEFAULT_GENESIS_CONFIG_HASH, - DEFAULT_GENESIS_TIMESTAMP_MILLIS, DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, - DEFAULT_PROPOSER_PUBLIC_KEY, DEFAULT_PROTOCOL_VERSION, DEFAULT_ROUND_SEIGNIORAGE_RATE, - DEFAULT_SYSTEM_CONFIG, DEFAULT_UNBONDING_DELAY, DEFAULT_WASM_CONFIG, SYSTEM_ADDR, -}; - -const ARG_AMOUNT: &str = "amount"; -const ARG_TARGET: &str = "target"; -const ARG_ID: &str = "id"; - -const DELEGATION_RATE: u8 = 1; -const ID_NONE: Option = None; - -/// Initial balance for delegators in our test. -pub const DELEGATOR_INITIAL_BALANCE: u64 = 500 * 1_000_000_000u64; - -const VALIDATOR_BID_AMOUNT: u64 = 100; - -/// Amount of time to step foward between runs of the auction in our tests. -pub const TIMESTAMP_INCREMENT_MILLIS: u64 = 30_000; - -const TEST_DELEGATOR_INITIAL_ACCOUNT_BALANCE: u64 = 1_000_000 * 1_000_000_000; - -/// Run a block with transfers and optionally run step. -#[allow(clippy::too_many_arguments)] -pub fn run_blocks_with_transfers_and_step( - transfer_count: usize, - purse_count: usize, - use_scratch: bool, - run_auction: bool, - block_count: usize, - delegator_count: usize, - validator_count: usize, - mut report_writer: impl Write, -) { - let data_dir = TempDir::new().expect("should create temp dir"); - let mut builder = LmdbWasmTestBuilder::new(data_dir.as_ref()); - let delegator_keys = generate_public_keys(delegator_count); - let validator_keys = generate_public_keys(validator_count); - let mut necessary_tries = HashSet::new(); - - run_genesis_and_create_initial_accounts( - &mut builder, - &validator_keys, - delegator_keys - .iter() - .map(|public_key| public_key.to_account_hash()) - .collect::>(), - U512::from(TEST_DELEGATOR_INITIAL_ACCOUNT_BALANCE), - ); - let contract_hash = builder.get_auction_contract_hash(); - let mut next_validator_iter = validator_keys.iter().cycle(); - - for delegator_public_key in delegator_keys { - let delegation_amount = U512::from(2000 * 1_000_000_000u64); - let delegator_account_hash = delegator_public_key.to_account_hash(); - let next_validator_key = next_validator_iter - .next() - .expect("should produce values forever"); - let delegate = create_delegate_request( - delegator_public_key, - next_validator_key.clone(), - delegation_amount, - delegator_account_hash, - contract_hash, - ); - builder.exec(delegate); - builder.expect_success(); - builder.commit(); - builder.clear_results(); - } - - let purse_amount = U512::from(1_000_000_000u64); - - let purses = transfer::create_test_purses( - &mut builder, - *DEFAULT_ACCOUNT_ADDR, - purse_count as u64, - purse_amount, - ); - - let exec_requests = transfer::create_multiple_native_transfers_to_purses( - *DEFAULT_ACCOUNT_ADDR, - transfer_count, - &purses, - ); - - let mut total_transfers = 0; - { - let engine_state = builder.get_engine_state(); - let lmdb_env = engine_state.get_state().state().environment().env(); - let db = engine_state.get_state().state().trie_store().get_db(); - - let txn = lmdb_env.begin_ro_txn().unwrap(); - let mut cursor = txn.open_ro_cursor(db).unwrap(); - - let existing_keys = cursor - .iter() - .map(Result::unwrap) - .map(|(key, _)| Digest::try_from(key).expect("should be a digest")); - necessary_tries.extend(existing_keys); - } - writeln!( - report_writer, - "height,db-size,transfers,time_ms,necessary_tries,total_tries" - ) - .unwrap(); - // simulating a block boundary here. - for current_block in 0..block_count { - let start = Instant::now(); - total_transfers += exec_requests.len(); - - transfer::transfer_to_account_multiple_native_transfers( - &mut builder, - &exec_requests, - use_scratch, - ); - let transfer_root = builder.get_post_state_hash(); - let maybe_auction_root = if run_auction { - if use_scratch { - step_and_run_auction(&mut builder); - } else { - builder.advance_era(); - builder.commit(); - } - Some(builder.get_post_state_hash()) - } else { - None - }; - let exec_time = start.elapsed(); - find_necessary_tries( - builder.get_engine_state(), - &mut necessary_tries, - transfer_root, - ); - - if let Some(auction_root) = maybe_auction_root { - find_necessary_tries( - builder.get_engine_state(), - &mut necessary_tries, - auction_root, - ); - } - - let total_tries = { - let engine_state = builder.get_engine_state(); - let lmdb_env = engine_state.get_state().state().environment().env(); - let db = engine_state.get_state().state().trie_store().get_db(); - let txn = lmdb_env.begin_ro_txn().unwrap(); - let mut cursor = txn.open_ro_cursor(db).unwrap(); - cursor.iter().count() - }; - - if use_scratch { - // This assertion is only valid with the scratch trie. - assert_eq!( - necessary_tries.len(), - total_tries, - "should not create unnecessary tries" - ); - } - - writeln!( - report_writer, - "{},{},{},{},{},{}", - current_block, - builder.lmdb_on_disk_size().unwrap(), - total_transfers, - exec_time.as_millis() as usize, - necessary_tries.len(), - total_tries, - ) - .unwrap(); - report_writer.flush().unwrap(); - } -} - -// find all necessary tries - hoist to FN -fn find_necessary_tries( - engine_state: &EngineState, - necessary_tries: &mut HashSet, - state_root: Digest, -) where - S: StateProvider + CommitProvider, -{ - let mut queue = Vec::new(); - queue.push(state_root); - - while let Some(root) = queue.pop() { - if necessary_tries.contains(&root) { - continue; - } - necessary_tries.insert(root); - - let trie_bytes = engine_state - .get_trie_full(root) - .unwrap() - .expect("trie should exist") - .into_inner(); - - if let Some(0) = trie_bytes.first() { - continue; - } - - let trie: Trie = - bytesrepr::deserialize(trie_bytes.inner_bytes().to_owned()) - .expect("unable to deserialize"); - - match trie { - Trie::Leaf { .. } => continue, - Trie::Node { pointer_block } => queue.extend(pointer_block.as_indexed_pointers().map( - |(_idx, ptr)| match ptr { - Pointer::LeafPointer(digest) | Pointer::NodePointer(digest) => digest, - }, - )), - Trie::Extension { affix: _, pointer } => match pointer { - Pointer::LeafPointer(digest) | Pointer::NodePointer(digest) => queue.push(digest), - }, - } - } -} - -/// Runs genesis, creates system, validator and delegator accounts, and funds the system account and -/// delegator accounts. -pub fn run_genesis_and_create_initial_accounts( - builder: &mut LmdbWasmTestBuilder, - validator_keys: &[PublicKey], - delegator_accounts: Vec, - delegator_initial_balance: U512, -) { - let mut genesis_accounts = vec![ - GenesisAccount::account( - DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), - Motes::new(U512::from(u128::MAX)), - None, - ), - GenesisAccount::account( - DEFAULT_PROPOSER_PUBLIC_KEY.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), - None, - ), - ]; - for validator in validator_keys { - genesis_accounts.push(GenesisAccount::account( - validator.clone(), - Motes::new(U512::from(DEFAULT_ACCOUNT_INITIAL_BALANCE)), - Some(GenesisValidator::new( - Motes::new(U512::from(VALIDATOR_BID_AMOUNT)), - DELEGATION_RATE, - )), - )) - } - let run_genesis_request = - create_run_genesis_request(validator_keys.len() as u32 + 2, genesis_accounts); - builder.run_genesis(run_genesis_request); - - // Setup the system account with enough cspr - let transfer = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - ARG_TARGET => *SYSTEM_ADDR, - ARG_AMOUNT => U512::from(10_000 * 1_000_000_000u64), - ARG_ID => ID_NONE, - }, - ) - .build(); - builder.exec(transfer); - builder.expect_success().commit(); - - for (_i, delegator_account) in delegator_accounts.iter().enumerate() { - let transfer = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - ARG_TARGET => *delegator_account, - ARG_AMOUNT => delegator_initial_balance, - ARG_ID => ID_NONE, - }, - ) - .build(); - builder.exec(transfer); - builder.expect_success().commit(); - } -} - -fn create_run_genesis_request( - validator_slots: u32, - genesis_accounts: Vec, -) -> GenesisRequest { - let genesis_config = GenesisConfigBuilder::default() - .with_accounts(genesis_accounts) - .with_wasm_config(*DEFAULT_WASM_CONFIG) - .with_system_config(*DEFAULT_SYSTEM_CONFIG) - .with_validator_slots(validator_slots) - .with_auction_delay(DEFAULT_AUCTION_DELAY) - .with_locked_funds_period_millis(DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS) - .with_round_seigniorage_rate(DEFAULT_ROUND_SEIGNIORAGE_RATE) - .with_unbonding_delay(DEFAULT_UNBONDING_DELAY) - .with_genesis_timestamp_millis(DEFAULT_GENESIS_TIMESTAMP_MILLIS) - .with_refund_handling(DEFAULT_REFUND_HANDLING) - .with_fee_handling(DEFAULT_FEE_HANDLING) - .build(); - - GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, - genesis_config, - ChainspecRegistry::new_with_genesis(&[], &[]), - ) -} - -/// Creates a delegation request. -pub fn create_delegate_request( - delegator_public_key: PublicKey, - next_validator_key: PublicKey, - delegation_amount: U512, - delegator_account_hash: AccountHash, - contract_hash: casper_types::AddressableEntityHash, -) -> ExecuteRequest { - let entry_point = auction::METHOD_DELEGATE; - let args = runtime_args! { - auction::ARG_DELEGATOR => delegator_public_key, - auction::ARG_VALIDATOR => next_validator_key, - auction::ARG_AMOUNT => delegation_amount, - }; - let mut rng = rand::thread_rng(); - let deploy_hash = rng.gen(); - let deploy = DeployItemBuilder::new() - .with_address(delegator_account_hash) - .with_stored_session_hash(contract_hash, entry_point, args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => U512::from(2_500_000_000_u64) }) - .with_authorization_keys(&[delegator_account_hash]) - .with_deploy_hash(deploy_hash) - .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() -} - -/// Generate `key_count` public keys. -pub fn generate_public_keys(key_count: usize) -> Vec { - let mut ret = Vec::with_capacity(key_count); - for _ in 0..key_count { - let bytes: [u8; SecretKey::ED25519_LENGTH] = rand::random(); - let secret_key = SecretKey::ed25519_from_bytes(bytes).unwrap(); - let public_key = PublicKey::from(&secret_key); - ret.push(public_key); - } - ret -} - -/// Build a step request and run the auction. -pub fn step_and_run_auction(builder: &mut LmdbWasmTestBuilder) { - let step_request_builder = StepRequestBuilder::new() - .with_parent_state_hash(builder.get_post_state_hash()) - .with_protocol_version(ProtocolVersion::V1_0_0); - - let step_request = step_request_builder - .with_next_era_id(builder.get_era().successor()) - .build(); - builder.step_with_scratch(step_request); - builder.write_scratch_to_db(); -} diff --git a/execution_engine_testing/test_support/src/deploy_item_builder.rs b/execution_engine_testing/test_support/src/deploy_item_builder.rs index 258094afd2..48b6fba79e 100644 --- a/execution_engine_testing/test_support/src/deploy_item_builder.rs +++ b/execution_engine_testing/test_support/src/deploy_item_builder.rs @@ -4,8 +4,8 @@ use rand::Rng; use casper_execution_engine::engine_state::deploy_item::DeployItem; use casper_types::{ - account::AccountHash, AddressableEntityHash, DeployHash, EntityVersion, ExecutableDeployItem, - HashAddr, PackageHash, RuntimeArgs, + account::AccountHash, bytesrepr::Bytes, AddressableEntityHash, DeployHash, EntityVersion, + ExecutableDeployItem, HashAddr, PackageHash, RuntimeArgs, }; use crate::{utils, DEFAULT_GAS_PRICE}; @@ -38,7 +38,11 @@ impl DeployItemBuilder { } /// Sets the payment bytes for the deploy. - pub fn with_payment_bytes(mut self, module_bytes: Vec, args: RuntimeArgs) -> Self { + pub fn with_payment_bytes>( + mut self, + module_bytes: T, + args: RuntimeArgs, + ) -> Self { self.deploy_item.payment_code = Some(ExecutableDeployItem::ModuleBytes { module_bytes: module_bytes.into(), args, @@ -53,7 +57,7 @@ impl DeployItemBuilder { /// Sets the payment bytes of a deploy by reading a file and passing [`RuntimeArgs`]. pub fn with_payment_code>(self, file_name: T, args: RuntimeArgs) -> Self { - let module_bytes = utils::read_wasm_file_bytes(file_name); + let module_bytes = utils::read_wasm_file(file_name); self.with_payment_bytes(module_bytes, args) } @@ -120,7 +124,11 @@ impl DeployItemBuilder { } /// Sets the session bytes for the deploy. - pub fn with_session_bytes(mut self, module_bytes: Vec, args: RuntimeArgs) -> Self { + pub fn with_session_bytes>( + mut self, + module_bytes: T, + args: RuntimeArgs, + ) -> Self { self.deploy_item.session_code = Some(ExecutableDeployItem::ModuleBytes { module_bytes: module_bytes.into(), args, @@ -130,7 +138,7 @@ impl DeployItemBuilder { /// Sets the session code for the deploy using a wasm file. pub fn with_session_code>(self, file_name: T, args: RuntimeArgs) -> Self { - let module_bytes = utils::read_wasm_file_bytes(file_name); + let module_bytes = utils::read_wasm_file(file_name); self.with_session_bytes(module_bytes, args) } diff --git a/execution_engine_testing/test_support/src/execute_request_builder.rs b/execution_engine_testing/test_support/src/execute_request_builder.rs index 3dfd210c5a..d38bccfe69 100644 --- a/execution_engine_testing/test_support/src/execute_request_builder.rs +++ b/execution_engine_testing/test_support/src/execute_request_builder.rs @@ -1,158 +1,170 @@ -use std::convert::TryInto; - -use rand::Rng; +use std::{collections::BTreeSet, convert::TryFrom, iter}; use casper_execution_engine::engine_state::{ - deploy_item::DeployItem, execute_request::ExecuteRequest, + deploy_item::DeployItem, execute_request::ExecuteRequest, Payment, PaymentInfo, Session, + SessionInfo, }; use casper_types::{ - account::AccountHash, runtime_args, AddressableEntityHash, EntityVersion, PackageHash, - ProtocolVersion, RuntimeArgs, + account::AccountHash, runtime_args, AddressableEntityHash, BlockTime, DeployHash, Digest, + EntityVersion, InitiatorAddr, PackageHash, PublicKey, RuntimeArgs, TransactionHash, + TransactionV1Hash, }; -use crate::{DeployItemBuilder, DEFAULT_BLOCK_TIME, DEFAULT_PAYMENT, DEFAULT_PROPOSER_PUBLIC_KEY}; - -const ARG_AMOUNT: &str = "amount"; +use crate::{ + DeployItemBuilder, ARG_AMOUNT, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, + DEFAULT_BLOCK_TIME, DEFAULT_GAS_PRICE, DEFAULT_PAYMENT, DEFAULT_PROPOSER_PUBLIC_KEY, +}; /// Builds an [`ExecuteRequest`]. #[derive(Debug)] pub struct ExecuteRequestBuilder { - execute_request: ExecuteRequest, + pre_state_hash: Digest, + block_time: BlockTime, + transaction_hash: TransactionHash, + gas_price: u64, + initiator_addr: InitiatorAddr, + payment: Payment, + payment_entry_point: String, + payment_args: RuntimeArgs, + session: Option, + session_entry_point: String, + session_args: RuntimeArgs, + authorization_keys: BTreeSet, + proposer: PublicKey, +} + +impl Default for ExecuteRequestBuilder { + fn default() -> Self { + ExecuteRequestBuilder { + pre_state_hash: Self::DEFAULT_PRE_STATE_HASH, + block_time: BlockTime::new(DEFAULT_BLOCK_TIME), + transaction_hash: Self::DEFAULT_TRANSACTION_HASH, + gas_price: DEFAULT_GAS_PRICE, + initiator_addr: InitiatorAddr::PublicKey(DEFAULT_ACCOUNT_PUBLIC_KEY.clone()), + payment: Self::DEFAULT_PAYMENT, + payment_entry_point: Self::DEFAULT_PAYMENT_ENTRY_POINT.to_string(), + payment_args: runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }, + session: None, + session_entry_point: Self::DEFAULT_SESSION_ENTRY_POINT.to_string(), + session_args: RuntimeArgs::new(), + authorization_keys: iter::once(*DEFAULT_ACCOUNT_ADDR).collect(), + proposer: DEFAULT_PROPOSER_PUBLIC_KEY.clone(), + } + } } impl ExecuteRequestBuilder { - /// Returns an [`ExecuteRequestBuilder`]. + /// The default value used for `ExecuteRequest::pre_state_hash`. + pub const DEFAULT_PRE_STATE_HASH: Digest = Digest::from_raw([1; 32]); + /// The default value used for `ExecuteRequest::transaction_hash`. + pub const DEFAULT_TRANSACTION_HASH: TransactionHash = + TransactionHash::V1(TransactionV1Hash::from_raw([2; 32])); + /// The default value used for `ExecuteRequest::payment`. + pub const DEFAULT_PAYMENT: Payment = Payment::Standard; + /// The default value used for `ExecuteRequest::payment_entry_point`. + pub const DEFAULT_PAYMENT_ENTRY_POINT: &'static str = "call"; + /// The default value used for `ExecuteRequest::session_entry_point`. + pub const DEFAULT_SESSION_ENTRY_POINT: &'static str = "call"; + /// The default value used in `ExecuteRequest::authorization_keys`. + pub const DEFAULT_AUTHORIZATION_KEY: AccountHash = AccountHash::new([3; 32]); + + /// Returns a new `ExecuteRequestBuilder` with default values. pub fn new() -> Self { - Default::default() + Self::default() } - /// Takes a [`DeployItem`] and returns an [`ExecuteRequestBuilder`]. + /// Converts a `DeployItem` into an `ExecuteRequestBuilder`. pub fn from_deploy_item(deploy_item: DeployItem) -> Self { - ExecuteRequestBuilder::new().push_deploy(deploy_item) - } - - /// Adds a [`DeployItem`] to the [`ExecuteRequest`]. - pub fn push_deploy(mut self, deploy: DeployItem) -> Self { - self.execute_request.deploys.push(deploy); - self - } - - /// Sets the parent state hash of the [`ExecuteRequest`]. - pub fn with_pre_state_hash(mut self, pre_state_hash: &[u8]) -> Self { - self.execute_request.parent_state_hash = pre_state_hash.try_into().unwrap(); - self - } - - /// Sets the block time of the [`ExecuteRequest`]. - pub fn with_block_time(mut self, block_time: u64) -> Self { - self.execute_request.block_time = block_time; - self - } - - /// Sets the protocol version of the [`ExecuteRequest`]. - pub fn with_protocol_version(mut self, protocol_version: ProtocolVersion) -> Self { - self.execute_request.protocol_version = protocol_version; - self - } - - /// Sets the proposer used by the [`ExecuteRequest`]. - pub fn with_proposer(mut self, proposer: casper_types::PublicKey) -> Self { - self.execute_request.proposer = proposer; - self - } - - /// Consumes self and returns an [`ExecuteRequest`]. - pub fn build(self) -> ExecuteRequest { - self.execute_request - } - - /// Returns an [`ExecuteRequest`] with standard dependencies. + let session_info = + SessionInfo::try_from((deploy_item.session, DeployHash::default())).unwrap(); + let payment_info = + PaymentInfo::try_from((deploy_item.payment, DeployHash::default())).unwrap(); + + ExecuteRequestBuilder { + transaction_hash: TransactionHash::Deploy(deploy_item.deploy_hash), + gas_price: deploy_item.gas_price, + initiator_addr: InitiatorAddr::AccountHash(deploy_item.address), + payment: payment_info.payment, + payment_entry_point: payment_info.entry_point, + payment_args: payment_info.args, + session: Some(session_info.session), + session_entry_point: session_info.entry_point, + session_args: session_info.args, + authorization_keys: deploy_item.authorization_keys, + ..Self::default() + } + } + + /// Returns an [`ExecuteRequest`] derived from a deploy with standard dependencies. pub fn standard( account_hash: AccountHash, session_file: &str, session_args: RuntimeArgs, ) -> Self { - let mut rng = rand::thread_rng(); - let deploy_hash: [u8; 32] = rng.gen(); - - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(session_file, session_args) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }) .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) .build(); - - ExecuteRequestBuilder::new().push_deploy(deploy) + Self::from_deploy_item(deploy_item) } - /// Returns an [`ExecuteRequest`] from a module bytes. + /// Returns an [`ExecuteRequest`] derived from a deploy with session module bytes. pub fn module_bytes( account_hash: AccountHash, module_bytes: Vec, session_args: RuntimeArgs, ) -> Self { - let mut rng = rand::thread_rng(); - let deploy_hash: [u8; 32] = rng.gen(); - - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_bytes(module_bytes, session_args) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }) .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) .build(); - - ExecuteRequestBuilder::new().push_deploy(deploy) + Self::from_deploy_item(deploy_item) } - /// Returns an [`ExecuteRequest`] that will call a stored contract by hash. + /// Returns an [`ExecuteRequest`] derived from a deploy with a session item that will call a + /// stored contract by hash. pub fn contract_call_by_hash( sender: AccountHash, contract_hash: AddressableEntityHash, entry_point: &str, args: RuntimeArgs, ) -> Self { - let mut rng = rand::thread_rng(); - let deploy_hash = rng.gen(); - - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_hash(contract_hash, entry_point, args) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) .build(); - - ExecuteRequestBuilder::new().push_deploy(deploy) + Self::from_deploy_item(deploy_item) } - /// Returns an [`ExecuteRequest`] that will call a stored contract by named key. + /// Returns an [`ExecuteRequest`] derived from a deploy with a session item that will call a + /// stored contract by name. pub fn contract_call_by_name( sender: AccountHash, contract_name: &str, entry_point: &str, args: RuntimeArgs, ) -> Self { - let mut rng = rand::thread_rng(); - let deploy_hash = rng.gen(); - - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_named_key(contract_name, entry_point, args) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) .build(); - - ExecuteRequestBuilder::new().push_deploy(deploy) + Self::from_deploy_item(deploy_item) } - /// Returns an [`ExecuteRequest`] that will call a versioned stored contract by hash. + /// Returns an [`ExecuteRequest`] derived from a deploy with a session item that will call a + /// versioned stored contract by hash. pub fn versioned_contract_call_by_hash( sender: AccountHash, contract_package_hash: PackageHash, @@ -160,10 +172,7 @@ impl ExecuteRequestBuilder { entry_point_name: &str, args: RuntimeArgs, ) -> Self { - let mut rng = rand::thread_rng(); - let deploy_hash = rng.gen(); - - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_versioned_contract_by_hash( contract_package_hash.value(), @@ -173,13 +182,12 @@ impl ExecuteRequestBuilder { ) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) .build(); - - ExecuteRequestBuilder::new().push_deploy(deploy) + Self::from_deploy_item(deploy_item) } - /// Calls a versioned contract from contract package hash key_name + /// Returns an [`ExecuteRequest`] derived from a deploy with a session item that will call a + /// versioned stored contract by name. pub fn versioned_contract_call_by_name( sender: AccountHash, contract_name: &str, @@ -187,69 +195,58 @@ impl ExecuteRequestBuilder { entry_point_name: &str, args: RuntimeArgs, ) -> Self { - let mut rng = rand::thread_rng(); - let deploy_hash = rng.gen(); - - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_versioned_contract_by_name(contract_name, version, entry_point_name, args) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) .build(); - - ExecuteRequestBuilder::new().push_deploy(deploy) + Self::from_deploy_item(deploy_item) } - /// Returns an [`ExecuteRequest`] for a native transfer. - pub fn transfer(sender: AccountHash, transfer_args: RuntimeArgs) -> Self { - let mut rng = rand::thread_rng(); - let deploy_hash = rng.gen(); - - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(transfer_args) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item) + /// Sets the block time of the [`ExecuteRequest`]. + pub fn with_block_time(mut self, block_time: u64) -> Self { + self.block_time = BlockTime::new(block_time); + self } - /// Returns an [`ExecuteRequest`] with standard dependencies and a specified set of - /// associated keys. - pub fn with_authorization_keys( - account_hash: AccountHash, - session_file: &str, - session_args: RuntimeArgs, - authorization_keys: &[AccountHash], - ) -> Self { - let mut rng = rand::thread_rng(); - let deploy_hash: [u8; 32] = rng.gen(); + /// Sets the proposer used by the [`ExecuteRequest`]. + pub fn with_proposer(mut self, proposer: PublicKey) -> Self { + self.proposer = proposer; + self + } - let deploy = DeployItemBuilder::new() - .with_address(account_hash) - .with_session_code(session_file, session_args) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => *DEFAULT_PAYMENT - }) - .with_authorization_keys(authorization_keys) - .with_deploy_hash(deploy_hash) - .build(); + /// Sets the authorization keys used by the [`ExecuteRequest`]. + pub fn with_authorization_keys(mut self, authorization_keys: BTreeSet) -> Self { + self.authorization_keys = authorization_keys; + self + } - ExecuteRequestBuilder::new().push_deploy(deploy) + /// Consumes self and returns an [`ExecuteRequest`]. + pub fn build(self) -> ExecuteRequest { + ExecuteRequest { + pre_state_hash: self.pre_state_hash, + block_time: self.block_time, + transaction_hash: self.transaction_hash, + gas_price: self.gas_price, + initiator_addr: self.initiator_addr, + payment: self.payment, + payment_entry_point: self.payment_entry_point, + payment_args: self.payment_args, + session: self + .session + .expect("builder must have been provided with a valid session item"), + session_entry_point: self.session_entry_point, + session_args: self.session_args, + authorization_keys: self.authorization_keys, + proposer: self.proposer, + } } -} -impl Default for ExecuteRequestBuilder { - fn default() -> Self { - let execute_request = ExecuteRequest { - block_time: DEFAULT_BLOCK_TIME, - protocol_version: ProtocolVersion::V1_0_0, - proposer: DEFAULT_PROPOSER_PUBLIC_KEY.clone(), - ..Default::default() - }; - ExecuteRequestBuilder { execute_request } + /// Returns an [`ExecuteRequest`] for a native transfer. + pub fn transfer(_sender: AccountHash, _transfer_args: RuntimeArgs) -> Self { + todo!( + "this should not be a part of Self - should maybe have an ExecuteNativeRequestBuilder" + ); } } diff --git a/execution_engine_testing/test_support/src/lib.rs b/execution_engine_testing/test_support/src/lib.rs index 6f1eb33b5e..e2cefdc695 100644 --- a/execution_engine_testing/test_support/src/lib.rs +++ b/execution_engine_testing/test_support/src/lib.rs @@ -9,18 +9,14 @@ #![warn(missing_docs)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] -/// Utility methods for running the auction in a test or bench context. -pub mod auction; mod chainspec_config; mod deploy_item_builder; mod execute_request_builder; mod step_request_builder; - -/// Utilities for running transfers in a test or bench context. -pub mod transfer; mod upgrade_request_builder; pub mod utils; mod wasm_test_builder; +// mod execute_request_builder; use num_rational::Ratio; use once_cell::sync::Lazy; @@ -28,14 +24,14 @@ use once_cell::sync::Lazy; #[doc(inline)] #[allow(deprecated)] pub use casper_execution_engine::engine_state::engine_config::{ - DEFAULT_MAX_ASSOCIATED_KEYS, DEFAULT_MAX_RUNTIME_CALL_STACK_HEIGHT, + DEFAULT_FEE_HANDLING, DEFAULT_MAX_ASSOCIATED_KEYS, DEFAULT_MAX_RUNTIME_CALL_STACK_HEIGHT, DEFAULT_MAX_STORED_VALUE_SIZE, DEFAULT_MINIMUM_DELEGATION_AMOUNT, }; use casper_storage::data_access_layer::GenesisRequest; use casper_types::{ account::AccountHash, ChainspecRegistry, Digest, GenesisAccount, GenesisConfig, GenesisConfigBuilder, Motes, ProtocolVersion, PublicKey, SecretKey, SystemConfig, WasmConfig, - DEFAULT_FEE_HANDLING, DEFAULT_REFUND_HANDLING, U512, + DEFAULT_REFUND_HANDLING, U512, }; pub use chainspec_config::ChainspecConfig; diff --git a/execution_engine_testing/test_support/src/transfer.rs b/execution_engine_testing/test_support/src/transfer.rs deleted file mode 100644 index 189c9544b3..0000000000 --- a/execution_engine_testing/test_support/src/transfer.rs +++ /dev/null @@ -1,281 +0,0 @@ -use casper_execution_engine::engine_state::ExecuteRequest; -use casper_types::{account::AccountHash, runtime_args, Key, URef, U512}; - -use crate::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, -}; - -const CONTRACT_CREATE_ACCOUNTS: &str = "create_accounts.wasm"; -const CONTRACT_CREATE_PURSES: &str = "create_purses.wasm"; -const CONTRACT_TRANSFER_TO_EXISTING_ACCOUNT: &str = "transfer_to_existing_account.wasm"; -const CONTRACT_TRANSFER_TO_PURSE: &str = "transfer_to_purse.wasm"; - -/// Size of batch used in multiple execs benchmark, and multiple deploys per exec cases. -pub const TRANSFER_BATCH_SIZE: u64 = 3; - -/// Test target address. -pub const TARGET_ADDR: AccountHash = AccountHash::new([127; 32]); - -const ARG_AMOUNT: &str = "amount"; -const ARG_ID: &str = "id"; -const ARG_ACCOUNTS: &str = "accounts"; -const ARG_SEED_AMOUNT: &str = "seed_amount"; -const ARG_TOTAL_PURSES: &str = "total_purses"; -const ARG_TARGET: &str = "target"; -const ARG_TARGET_PURSE: &str = "target_purse"; - -/// Test value for number of deploys to generate for a block. -pub const BLOCK_TRANSFER_COUNT: usize = 2500; - -/// Converts an integer into an array of type [u8; 32] by converting integer -/// into its big endian representation and embedding it at the end of the -/// range. -fn make_deploy_hash(i: u64) -> [u8; 32] { - let mut result = [128; 32]; - result[32 - 8..].copy_from_slice(&i.to_be_bytes()); - result -} - -/// Create initial accounts and run genesis. -pub fn create_initial_accounts_and_run_genesis( - builder: &mut LmdbWasmTestBuilder, - accounts: Vec, - amount: U512, -) { - let exec_request = create_accounts_request(accounts, amount); - builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) - .exec(exec_request) - .expect_success() - .commit(); -} - -/// Creates a request that will call the create_accounts.wasm and create test accounts using the -/// default account for the initial transfer. -pub fn create_accounts_request(source_accounts: Vec, amount: U512) -> ExecuteRequest { - ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_CREATE_ACCOUNTS, - runtime_args! { ARG_ACCOUNTS => source_accounts, ARG_SEED_AMOUNT => amount }, - ) - .build() -} - -/// Create a number of test purses with an initial balance. -pub fn create_test_purses( - builder: &mut LmdbWasmTestBuilder, - source: AccountHash, - total_purses: u64, - purse_amount: U512, -) -> Vec { - let exec_request = ExecuteRequestBuilder::standard( - source, - CONTRACT_CREATE_PURSES, - runtime_args! { - ARG_AMOUNT => U512::from(total_purses) * purse_amount, - ARG_TOTAL_PURSES => total_purses, - ARG_SEED_AMOUNT => purse_amount - }, - ) - .build(); - - builder.exec(exec_request).expect_success().commit(); - - // Return creates purses for given account by filtering named keys - let named_keys = builder.get_named_keys_by_account_hash(source); - - (0..total_purses) - .map(|index| { - let purse_lookup_key = format!("purse:{}", index); - let purse_uref = named_keys - .get(&purse_lookup_key) - .and_then(Key::as_uref) - .unwrap_or_else(|| panic!("should get named key {} as uref", purse_lookup_key)); - *purse_uref - }) - .collect() -} - -/// Uses multiple exec requests with a single deploy to transfer tokens. Executes all transfers in -/// batch determined by value of TRANSFER_BATCH_SIZE. -pub fn transfer_to_account_multiple_execs( - builder: &mut LmdbWasmTestBuilder, - account: AccountHash, - should_commit: bool, -) { - let amount = U512::one(); - - for _ in 0..TRANSFER_BATCH_SIZE { - let exec_request = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_TRANSFER_TO_EXISTING_ACCOUNT, - runtime_args! { - ARG_TARGET => account, - ARG_AMOUNT => amount, - }, - ) - .build(); - - let builder = builder.exec(exec_request).expect_success(); - if should_commit { - builder.commit(); - } - } -} - -/// Executes multiple deploys per single exec with based on TRANSFER_BATCH_SIZE. -pub fn transfer_to_account_multiple_deploys( - builder: &mut LmdbWasmTestBuilder, - account: AccountHash, - should_commit: bool, -) { - let mut exec_builder = ExecuteRequestBuilder::new(); - - for i in 0..TRANSFER_BATCH_SIZE { - let deploy = DeployItemBuilder::default() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }) - .with_session_code( - CONTRACT_TRANSFER_TO_EXISTING_ACCOUNT, - runtime_args! { - ARG_TARGET => account, - ARG_AMOUNT => U512::one(), - }, - ) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash(make_deploy_hash(i)) // deploy_hash - .build(); - exec_builder = exec_builder.push_deploy(deploy); - } - - let exec_request = exec_builder.build(); - - let builder = builder.exec(exec_request).expect_success(); - if should_commit { - builder.commit(); - } -} - -/// Uses multiple exec requests with a single deploy to transfer tokens from purse to purse. -/// Executes all transfers in batch determined by value of TRANSFER_BATCH_SIZE. -pub fn transfer_to_purse_multiple_execs( - builder: &mut LmdbWasmTestBuilder, - purse: URef, - should_commit: bool, -) { - let amount = U512::one(); - - for _ in 0..TRANSFER_BATCH_SIZE { - let exec_request = ExecuteRequestBuilder::standard( - TARGET_ADDR, - CONTRACT_TRANSFER_TO_PURSE, - runtime_args! { ARG_TARGET_PURSE => purse, ARG_AMOUNT => amount }, - ) - .build(); - - let builder = builder.exec(exec_request).expect_success(); - if should_commit { - builder.commit(); - } - } -} - -/// Executes multiple deploys per single exec with based on TRANSFER_BATCH_SIZE. -pub fn transfer_to_purse_multiple_deploys( - builder: &mut LmdbWasmTestBuilder, - purse: URef, - should_commit: bool, -) { - let mut exec_builder = ExecuteRequestBuilder::new(); - - for i in 0..TRANSFER_BATCH_SIZE { - let deploy = DeployItemBuilder::default() - .with_address(TARGET_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_session_code( - CONTRACT_TRANSFER_TO_PURSE, - runtime_args! { ARG_TARGET_PURSE => purse, ARG_AMOUNT => U512::one() }, - ) - .with_authorization_keys(&[TARGET_ADDR]) - .with_deploy_hash(make_deploy_hash(i)) // deploy_hash - .build(); - exec_builder = exec_builder.push_deploy(deploy); - } - - let exec_request = exec_builder.build(); - - let builder = builder.exec(exec_request).expect_success(); - if should_commit { - builder.commit(); - } -} - -/// This test simulates flushing at the end of a block. -pub fn transfer_to_account_multiple_native_transfers( - builder: &mut LmdbWasmTestBuilder, - execute_requests: &[ExecuteRequest], - use_scratch: bool, -) { - for exec_request in execute_requests { - let request = ExecuteRequest::new( - exec_request.parent_state_hash, - exec_request.block_time, - exec_request.deploys.clone(), - exec_request.protocol_version, - exec_request.proposer.clone(), - ); - if use_scratch { - builder.scratch_exec_and_commit(request).expect_success(); - } else { - builder.exec(request).expect_success(); - builder.commit(); - } - } - if use_scratch { - builder.write_scratch_to_db(); - } - // flush to disk only after entire block (simulates manual_sync_enabled=true config entry) - builder.flush_environment(); - - // WasmTestBuilder holds on to all execution results. This needs to be cleared to reduce - // overhead in this test - it will likely OOM without. - builder.clear_results(); -} - -/// Generate many native transfers from target_account. -pub fn create_multiple_native_transfers_to_purses( - source_account: AccountHash, - transfer_count: usize, - purses: &[URef], -) -> Vec { - let mut purse_index = 0usize; - let mut exec_requests = Vec::with_capacity(transfer_count); - for _ in 0..transfer_count { - let account = { - let account = purses[purse_index]; - if purse_index == purses.len() - 1 { - purse_index = 0; - } else { - purse_index += 1; - } - account - }; - let mut exec_builder = ExecuteRequestBuilder::new(); - let runtime_args = runtime_args! { - ARG_TARGET => account, - ARG_AMOUNT => U512::one(), - ARG_ID => >::None - }; - let native_transfer = DeployItemBuilder::new() - .with_address(source_account) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(runtime_args) - .with_authorization_keys(&[source_account]) - .build(); - exec_builder = exec_builder.push_deploy(native_transfer); - let exec_request = exec_builder.build(); - exec_requests.push(exec_request); - } - exec_requests -} diff --git a/execution_engine_testing/test_support/src/utils.rs b/execution_engine_testing/test_support/src/utils.rs index e8316cab9f..c1c8aaca1c 100644 --- a/execution_engine_testing/test_support/src/utils.rs +++ b/execution_engine_testing/test_support/src/utils.rs @@ -3,23 +3,21 @@ use std::{ env, fs, path::{Path, PathBuf}, - rc::Rc, }; use once_cell::sync::Lazy; -use casper_execution_engine::engine_state::{execution_result::ExecutionResult, Error}; -use casper_storage::data_access_layer::GenesisRequest; -use casper_types::{ - Gas, GenesisAccount, GenesisConfig, GenesisConfigBuilder, DEFAULT_FEE_HANDLING, - DEFAULT_REFUND_HANDLING, +use casper_execution_engine::engine_state::{ + engine_config::DEFAULT_FEE_HANDLING, execution_result::ExecutionResult, Error, }; +use casper_storage::data_access_layer::GenesisRequest; +use casper_types::{bytesrepr::Bytes, GenesisAccount, GenesisConfig, GenesisConfigBuilder}; use super::{DEFAULT_ROUND_SEIGNIORAGE_RATE, DEFAULT_SYSTEM_CONFIG, DEFAULT_UNBONDING_DELAY}; use crate::{ DEFAULT_AUCTION_DELAY, DEFAULT_CHAINSPEC_REGISTRY, DEFAULT_GENESIS_CONFIG_HASH, DEFAULT_GENESIS_TIMESTAMP_MILLIS, DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, DEFAULT_PROTOCOL_VERSION, - DEFAULT_VALIDATOR_SLOTS, DEFAULT_WASM_CONFIG, + DEFAULT_REFUND_HANDLING, DEFAULT_VALIDATOR_SLOTS, DEFAULT_WASM_CONFIG, }; static RUST_WORKSPACE_PATH: Lazy = Lazy::new(|| { @@ -97,7 +95,7 @@ fn get_compiled_wasm_paths() -> Vec { } /// Reads a given compiled contract file based on path -pub fn read_wasm_file_bytes>(contract_file: T) -> Vec { +pub fn read_wasm_file>(contract_file: T) -> Bytes { let mut attempted_paths = vec![]; if contract_file.as_ref().is_relative() { @@ -106,7 +104,7 @@ pub fn read_wasm_file_bytes>(contract_file: T) -> Vec { let mut filename = wasm_path.clone(); filename.push(contract_file.as_ref()); if let Ok(wasm_bytes) = fs::read(&filename) { - return wasm_bytes; + return Bytes::from(wasm_bytes); } attempted_paths.push(filename); } @@ -114,7 +112,7 @@ pub fn read_wasm_file_bytes>(contract_file: T) -> Vec { // Try just opening in case the arg is a valid path relative to current working dir, or is a // valid absolute path. if let Ok(wasm_bytes) = fs::read(contract_file.as_ref()) { - return wasm_bytes; + return Bytes::from(wasm_bytes); } attempted_paths.push(contract_file.as_ref().to_owned()); @@ -166,51 +164,15 @@ pub fn create_run_genesis_request(accounts: Vec) -> GenesisReque ) } -/// Returns a `Vec` representing gas consts for an [`ExecutionResult`]. -pub fn get_exec_costs, I: IntoIterator>( - exec_response: I, -) -> Vec { - exec_response - .into_iter() - .map(|res| res.as_ref().cost()) - .collect() -} - -/// Returns the success result of the `ExecutionResult`. -/// # Panics -/// Panics if `response` is `None`. -pub fn get_success_result(response: &[Rc]) -> &ExecutionResult { - response.get(0).expect("should have a result") -} - /// Returns an error if the `ExecutionResult` has an error. +/// /// # Panics -/// Panics if the result is `None`. -/// Panics if the result does not have a precondition failure. -/// Panics if result.as_error() is `None`. -pub fn get_precondition_failure(response: &[Rc]) -> &Error { - let result = response.get(0).expect("should have a result"); +/// * Panics if the result does not have a precondition failure. +/// * Panics if result.as_error() is `None`. +pub fn get_precondition_failure(exec_result: &ExecutionResult) -> &Error { assert!( - result.has_precondition_failure(), + exec_result.has_precondition_failure(), "should be a precondition failure" ); - result.as_error().expect("should have an error") -} - -/// Returns a `String` concatenated from all of the error messages from the `ExecutionResult`. -pub fn get_error_message, I: IntoIterator>( - execution_result: I, -) -> String { - let errors = execution_result - .into_iter() - .enumerate() - .filter_map(|(i, result)| { - if let ExecutionResult::Failure { error, .. } = result.as_ref() { - Some(format!("{}: {:?}", i, error)) - } else { - None - } - }) - .collect::>(); - errors.join("\n") + exec_result.as_error().expect("should have an error") } diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index 31039a190e..b80ebc237b 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -46,24 +46,24 @@ use casper_types::{ runtime_args, system::{ auction::{ - BidKind, EraValidators, UnbondingPurse, UnbondingPurses, ValidatorWeights, - WithdrawPurses, ARG_ERA_END_TIMESTAMP_MILLIS, ARG_EVICTED_VALIDATORS, - AUCTION_DELAY_KEY, ERA_ID_KEY, METHOD_RUN_AUCTION, UNBONDING_DELAY_KEY, + BidKind, EraValidators, UnbondingPurses, ValidatorWeights, WithdrawPurses, + ARG_ERA_END_TIMESTAMP_MILLIS, ARG_EVICTED_VALIDATORS, AUCTION_DELAY_KEY, ERA_ID_KEY, + METHOD_RUN_AUCTION, UNBONDING_DELAY_KEY, }, mint::{ROUND_SEIGNIORAGE_RATE_KEY, TOTAL_SUPPLY_KEY}, AUCTION, HANDLE_PAYMENT, MINT, STANDARD_PAYMENT, }, AddressableEntity, AddressableEntityHash, AuctionCosts, ByteCode, ByteCodeAddr, ByteCodeHash, - CLTyped, CLValue, Contract, DeployHash, DeployInfo, Digest, EntityAddr, EraId, Gas, - HandlePaymentCosts, Key, KeyTag, MintCosts, Motes, Package, PackageHash, ProtocolUpgradeConfig, - ProtocolVersion, PublicKey, RefundHandling, StoredValue, SystemEntityRegistry, Transfer, + CLTyped, CLValue, Contract, Digest, EntityAddr, EraId, Gas, HandlePaymentCosts, Key, KeyTag, + MintCosts, Motes, Package, PackageHash, ProtocolUpgradeConfig, ProtocolVersion, PublicKey, + RefundHandling, StoredValue, SystemEntityRegistry, TransactionHash, TransactionInfo, Transfer, TransferAddr, URef, OS_PAGE_SIZE, U512, }; use tempfile::TempDir; use crate::{ chainspec_config::{ChainspecConfig, PRODUCTION_PATH}, - utils, ExecuteRequestBuilder, StepRequestBuilder, DEFAULT_GAS_PRICE, DEFAULT_PROPOSER_ADDR, + ExecuteRequestBuilder, StepRequestBuilder, DEFAULT_GAS_PRICE, DEFAULT_PROPOSER_ADDR, DEFAULT_PROTOCOL_VERSION, SYSTEM_ADDR, }; @@ -114,10 +114,8 @@ pub type LmdbWasmTestBuilder = WasmTestBuilder> /// Builder for simple WASM test pub struct WasmTestBuilder { - /// [`EngineState`] is wrapped in [`Rc`] to work around a missing [`Clone`] implementation. engine_state: Rc>, - /// [`ExecutionResult`] is wrapped in [`Rc`] to work around a missing [`Clone`] implementation. - exec_results: Vec>>, + exec_results: Vec, upgrade_results: Vec, prune_results: Vec>, genesis_hash: Option, @@ -144,8 +142,6 @@ impl Default for LmdbWasmTestBuilder { } } -// TODO: Deriving `Clone` for `WasmTestBuilder` doesn't work correctly (unsure why), so -// implemented by hand here. Try to derive in the future with a different compiler version. impl Clone for WasmTestBuilder { fn clone(&self) -> Self { WasmTestBuilder { @@ -508,26 +504,22 @@ impl LmdbWasmTestBuilder { // Scratch still requires that one deploy be executed and committed at a time. let exec_request = { let hash = self.post_state_hash.expect("expected post_state_hash"); - exec_request.parent_state_hash = hash; + exec_request.pre_state_hash = hash; exec_request }; - let mut exec_results = Vec::new(); // First execute the request against our scratch global state. - let maybe_exec_results = cached_state.run_execute(exec_request); - for execution_result in maybe_exec_results.unwrap() { - let _post_state_hash = cached_state - .commit_effects( - self.post_state_hash.expect("requires a post_state_hash"), - execution_result.effects().clone(), - ) - .expect("should commit"); + let execution_result = cached_state.execute_transaction(exec_request).unwrap(); + let _post_state_hash = cached_state + .commit_effects( + self.post_state_hash.expect("requires a post_state_hash"), + execution_result.effects().clone(), + ) + .expect("should commit"); - // Save transforms and execution results for WasmTestBuilder. - self.effects.push(execution_result.effects().clone()); - exec_results.push(Rc::new(execution_result)) - } - self.exec_results.push(exec_results); + // Save transforms and execution results for WasmTestBuilder. + self.effects.push(execution_result.effects().clone()); + self.exec_results.push(execution_result); self } @@ -588,15 +580,15 @@ where self } - fn query_system_contract_registry( + fn query_system_entity_registry( &self, post_state_hash: Option, ) -> Option { match self.query(post_state_hash, Key::SystemEntityRegistry, &[]) { Ok(StoredValue::CLValue(cl_registry)) => { - let system_contract_registry = + let system_entity_registry = CLValue::into_t::(cl_registry).unwrap(); - Some(system_contract_registry) + Some(system_entity_registry) } Ok(_) => None, Err(_) => None, @@ -633,7 +625,7 @@ where ) -> Result { let entity_addr = self .get_entity_hash_by_account_hash(account_hash) - .map(|entity_hash| EntityAddr::new_account_entity_addr(entity_hash.value())) + .map(|entity_hash| EntityAddr::new_account(entity_hash.value())) .expect("must get EntityAddr"); self.query_named_key(maybe_post_state, entity_addr, name) } @@ -757,26 +749,11 @@ where /// Runs an [`ExecuteRequest`]. pub fn exec(&mut self, mut exec_request: ExecuteRequest) -> &mut Self { - let exec_request = { - let hash = self.post_state_hash.expect("expected post_state_hash"); - exec_request.parent_state_hash = hash; - exec_request - }; - - let maybe_exec_results = self.engine_state.run_execute(exec_request); - assert!(maybe_exec_results.is_ok()); - // Parse deploy results - let execution_results = maybe_exec_results.as_ref().unwrap(); + exec_request.pre_state_hash = self.post_state_hash.expect("expected post_state_hash"); + let execution_result = self.engine_state.execute_transaction(exec_request).unwrap(); // Cache transformations - self.effects - .extend(execution_results.iter().map(|res| res.effects().clone())); - self.exec_results.push( - maybe_exec_results - .unwrap() - .into_iter() - .map(Rc::new) - .collect(), - ); + self.effects.push(execution_result.effects().clone()); + self.exec_results.push(execution_result); self } @@ -902,14 +879,9 @@ where /// Expects a successful run #[track_caller] pub fn expect_success(&mut self) -> &mut Self { - // Check first result, as only first result is interesting for a simple test - let exec_results = self + let exec_result = self .get_last_exec_result() - .expect("Expected to be called after run()"); - let exec_result = exec_results - .get(0) - .expect("Unable to get first deploy result"); - + .expect("Expected to be called after exec()"); if exec_result.is_failure() { panic!( "Expected successful execution result, but instead got: {:#?}", @@ -921,44 +893,46 @@ where /// Expects a failed run pub fn expect_failure(&mut self) -> &mut Self { - // Check first result, as only first result is interesting for a simple test - let exec_results = self + let exec_result = self .get_last_exec_result() - .expect("Expected to be called after run()"); - let exec_result = exec_results - .get(0) - .expect("Unable to get first deploy result"); - + .expect("Expected to be called after exec()"); if exec_result.is_success() { panic!( "Expected failed execution result, but instead got: {:?}", exec_result, ); } - self } - /// Returns `true` if the las exec had an error, otherwise returns false. + /// Returns `true` if the last exec had an error, otherwise returns false. + #[track_caller] pub fn is_error(&self) -> bool { self.get_last_exec_result() - .expect("Expected to be called after run()") - .get(0) - .expect("Unable to get first execution result") + .expect("Expected to be called after exec()") .is_failure() } - /// Returns an `Option` if the last exec had an error. + /// Returns an `engine_state::Error` if the last exec had an error, otherwise `None`. + #[track_caller] pub fn get_error(&self) -> Option { self.get_last_exec_result() - .expect("Expected to be called after run()") - .get(0) - .expect("Unable to get first deploy result") + .expect("Expected to be called after exec()") .as_error() .cloned() } + /// Returns the error message of the last exec. + #[track_caller] + pub fn get_error_message(&self) -> Option { + self.get_last_exec_result() + .expect("Expected to be called after exec()") + .as_error() + .map(Error::to_string) + } + /// Gets `Effects` of all previous runs. + #[track_caller] pub fn get_effects(&self) -> Vec { self.effects.clone() } @@ -991,7 +965,7 @@ where } fn get_system_entity_hash(&self, contract_name: &str) -> Option { - self.query_system_contract_registry(self.post_state_hash)? + self.query_system_entity_registry(self.post_state_hash)? .get(contract_name) .copied() } @@ -1027,17 +1001,13 @@ where } /// Returns the last results execs. - pub fn get_last_exec_result(&self) -> Option>> { - let exec_results = self.exec_results.last()?; - - Some(exec_results.iter().map(Rc::clone).collect()) + pub fn get_last_exec_result(&self) -> Option { + self.exec_results.last().cloned() } /// Returns the owned results of a specific exec. - pub fn get_exec_result_owned(&self, index: usize) -> Option>> { - let exec_results = self.exec_results.get(index)?; - - Some(exec_results.iter().map(Rc::clone).collect()) + pub fn get_exec_result_owned(&self, index: usize) -> Option { + self.exec_results.get(index).cloned() } /// Returns a count of exec results. @@ -1260,43 +1230,30 @@ where } } - /// Queries for deploy info by `DeployHash`. - pub fn get_deploy_info(&self, deploy_hash: DeployHash) -> Option { - let deploy_info_value: StoredValue = self - .query(None, Key::DeployInfo(deploy_hash), &[]) - .expect("should have deploy info value"); + /// Queries for transaction info by `TransactionHash`. + pub fn get_transaction_info(&self, txn_hash: TransactionHash) -> Option { + let txn_info_value: StoredValue = self + .query(None, Key::TransactionInfo(txn_hash), &[]) + .expect("should have transaction info value"); - if let StoredValue::DeployInfo(deploy_info) = deploy_info_value { - Some(deploy_info) + if let StoredValue::TransactionInfo(txn_info) = txn_info_value { + Some(txn_info) } else { None } } - /// Returns a `Vec` representing execution consts. - pub fn exec_costs(&self, index: usize) -> Vec { - let exec_results = self - .get_exec_result_owned(index) - .expect("should have exec response"); - utils::get_exec_costs(exec_results) + /// Returns execution cost. + pub fn exec_cost(&self, index: usize) -> Gas { + self.exec_results + .get(index) + .map(ExecutionResult::gas) + .unwrap() } /// Returns the `Gas` cost of the last exec. pub fn last_exec_gas_cost(&self) -> Gas { - let exec_results = self - .get_last_exec_result() - .expect("Expected to be called after run()"); - let exec_result = exec_results.get(0).expect("should have result"); - exec_result.cost() - } - - /// Returns the result of the last exec. - pub fn last_exec_result(&self) -> &ExecutionResult { - let exec_results = self - .exec_results - .last() - .expect("Expected to be called after run()"); - exec_results.get(0).expect("should have result").as_ref() + self.exec_results.last().map(ExecutionResult::gas).unwrap() } /// Assert that last error is the expected one. @@ -1310,12 +1267,6 @@ where } } - /// Returns the error message of the last exec. - pub fn exec_error_message(&self, index: usize) -> Option { - let response = self.get_exec_result_owned(index)?; - Some(utils::get_error_message(response)) - } - /// Gets [`EraValidators`]. pub fn get_era_validators(&mut self) -> EraValidators { let state_hash = self.get_post_state_hash(); @@ -1349,7 +1300,7 @@ where let entity_hash = self .get_entity_hash_by_account_hash(account_hash) .expect("must have entity hash"); - let entity_addr = EntityAddr::new_account_entity_addr(entity_hash.value()); + let entity_addr = EntityAddr::new_account(entity_hash.value()); self.get_named_keys(entity_addr) } @@ -1358,7 +1309,7 @@ where &self, contract_hash: AddressableEntityHash, ) -> NamedKeys { - let entity_addr = EntityAddr::new_contract_entity_addr(contract_hash.value()); + let entity_addr = EntityAddr::new_smart_contract(contract_hash.value()); self.get_named_keys(entity_addr) } @@ -1652,40 +1603,6 @@ where self } - /// Returns the results of all execs. - #[deprecated( - since = "2.3.0", - note = "use `get_last_exec_results` or `get_exec_result_owned` instead" - )] - pub fn get_exec_results(&self) -> &Vec>> { - &self.exec_results - } - - /// Returns the results of a specific exec. - #[deprecated(since = "2.3.0", note = "use `get_exec_result_owned` instead")] - pub fn get_exec_result(&self, index: usize) -> Option<&Vec>> { - self.exec_results.get(index) - } - - /// Gets [`UnbondingPurses`]. - #[deprecated(since = "2.3.0", note = "use `get_withdraw_purses` instead")] - pub fn get_withdraws(&mut self) -> UnbondingPurses { - let withdraw_purses = self.get_withdraw_purses(); - let unbonding_purses: UnbondingPurses = withdraw_purses - .iter() - .map(|(key, withdraw_purse)| { - ( - key.to_owned(), - withdraw_purse - .iter() - .map(|withdraw_purse| withdraw_purse.to_owned().into()) - .collect::>(), - ) - }) - .collect::>>(); - unbonding_purses - } - /// Calculates refunded amount from a last execution request. pub fn calculate_refund_amount(&self, payment_amount: U512) -> U512 { let gas_amount = Motes::from_gas(self.last_exec_gas_cost(), DEFAULT_GAS_PRICE) diff --git a/execution_engine_testing/tests/Cargo.toml b/execution_engine_testing/tests/Cargo.toml index 571f288262..6ad9f66d14 100644 --- a/execution_engine_testing/tests/Cargo.toml +++ b/execution_engine_testing/tests/Cargo.toml @@ -39,18 +39,3 @@ wat = "1.0.47" [features] use-as-wasm = ["casper-engine-test-support/use-as-wasm"] fixture-generators = [] - -[lib] -bench = false - -[[bench]] -name = "transfer_bench" -harness = false - -[[bench]] -name = "auction_bench" -harness = false - -[[bin]] -name = "disk_use" -path = "bin/disk_use.rs" diff --git a/execution_engine_testing/tests/benches/auction_bench.rs b/execution_engine_testing/tests/benches/auction_bench.rs deleted file mode 100644 index 26297a5623..0000000000 --- a/execution_engine_testing/tests/benches/auction_bench.rs +++ /dev/null @@ -1,264 +0,0 @@ -use std::{path::Path, time::Duration}; - -use casper_execution_engine::engine_state::{EngineConfig, ExecuteRequest}; -use criterion::{ - criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion, Throughput, -}; -use rand::Rng; -use tempfile::TempDir; - -use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, StepRequestBuilder, - DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_ACCOUNT_PUBLIC_KEY, - DEFAULT_AUCTION_DELAY, DEFAULT_CHAINSPEC_REGISTRY, DEFAULT_GENESIS_CONFIG_HASH, - DEFAULT_GENESIS_TIMESTAMP_MILLIS, DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, - DEFAULT_MINIMUM_DELEGATION_AMOUNT, DEFAULT_PROPOSER_PUBLIC_KEY, DEFAULT_PROTOCOL_VERSION, - DEFAULT_ROUND_SEIGNIORAGE_RATE, DEFAULT_SYSTEM_CONFIG, DEFAULT_UNBONDING_DELAY, - DEFAULT_WASM_CONFIG, MINIMUM_ACCOUNT_CREATION_BALANCE, SYSTEM_ADDR, -}; -use casper_storage::data_access_layer::GenesisRequest; -use casper_types::{ - account::AccountHash, - runtime_args, - system::auction::{self}, - GenesisAccount, GenesisConfigBuilder, GenesisValidator, Motes, ProtocolVersion, PublicKey, - SecretKey, DEFAULT_DELEGATE_COST, U512, -}; - -const ARG_AMOUNT: &str = "amount"; -const ARG_TARGET: &str = "target"; -const ARG_ID: &str = "id"; - -const DELEGATION_AMOUNT: u64 = DEFAULT_MINIMUM_DELEGATION_AMOUNT; -const DELEGATION_RATE: u8 = 1; -const DELEGATOR_INITIAL_BALANCE: u64 = MINIMUM_ACCOUNT_CREATION_BALANCE; - -const VALIDATOR_BID_AMOUNT: u64 = 100; -const TIMESTAMP_INCREMENT_MILLIS: u64 = 30_000; - -/// Runs genesis, creates system, validator and delegator accounts, and funds the system account and -/// delegator accounts. -fn run_genesis_and_create_initial_accounts( - data_dir: &Path, - validator_keys: &[PublicKey], - delegator_accounts: Vec, -) -> LmdbWasmTestBuilder { - let engine_config = EngineConfig::default(); - let mut builder = LmdbWasmTestBuilder::new_with_config(data_dir, engine_config); - - let mut genesis_accounts = vec![ - GenesisAccount::account( - DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), - Motes::new(U512::MAX / u64::MAX), // enough motes - None, - ), - GenesisAccount::account( - DEFAULT_PROPOSER_PUBLIC_KEY.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), - None, - ), - ]; - for validator in validator_keys { - genesis_accounts.push(GenesisAccount::account( - validator.clone(), - Motes::new(U512::from(DEFAULT_ACCOUNT_INITIAL_BALANCE)), - Some(GenesisValidator::new( - Motes::new(U512::from(VALIDATOR_BID_AMOUNT)), - DELEGATION_RATE, - )), - )) - } - let run_genesis_request = - create_run_genesis_request(validator_keys.len() as u32 + 2, genesis_accounts); - builder.run_genesis(run_genesis_request); - - // Setup the system account with enough cspr - let transfer = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - ARG_TARGET => *SYSTEM_ADDR, - ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE, - ARG_ID => >::None, - }, - ) - .build(); - builder.exec(transfer); - builder.expect_success().commit(); - - for delegator_account in delegator_accounts { - let transfer = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - ARG_TARGET => delegator_account, - ARG_AMOUNT => DELEGATOR_INITIAL_BALANCE, - ARG_ID => >::None, - }, - ) - .build(); - builder.exec(transfer); - builder.expect_success().commit(); - } - builder -} - -fn create_run_genesis_request( - validator_slots: u32, - genesis_accounts: Vec, -) -> GenesisRequest { - let exec_config = { - GenesisConfigBuilder::new() - .with_accounts(genesis_accounts) - .with_wasm_config(*DEFAULT_WASM_CONFIG) - .with_system_config(*DEFAULT_SYSTEM_CONFIG) - .with_validator_slots(validator_slots) - .with_auction_delay(DEFAULT_AUCTION_DELAY) - .with_locked_funds_period_millis(DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS) - .with_round_seigniorage_rate(DEFAULT_ROUND_SEIGNIORAGE_RATE) - .with_unbonding_delay(DEFAULT_UNBONDING_DELAY) - .with_genesis_timestamp_millis(DEFAULT_GENESIS_TIMESTAMP_MILLIS) - .build() - }; - GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, - exec_config, - DEFAULT_CHAINSPEC_REGISTRY.clone(), - ) -} - -fn setup_bench_run_auction( - group: &mut BenchmarkGroup, - validator_count: usize, - delegator_count: usize, -) { - // Setup delegator public keys - let delegator_keys = generate_public_keys(delegator_count); - let validator_keys = generate_public_keys(validator_count); - - let data_dir = TempDir::new().expect("should create temp dir"); - let mut builder = run_genesis_and_create_initial_accounts( - data_dir.path(), - &validator_keys, - delegator_keys - .iter() - .map(|pk| pk.to_account_hash()) - .collect::>(), - ); - - let contract_hash = builder.get_auction_contract_hash(); - let mut next_validator_iter = validator_keys.iter().cycle(); - for delegator_public_key in delegator_keys { - let balance = builder - .get_public_key_balance_result(delegator_public_key.clone()) - .motes() - .cloned() - .unwrap(); - - assert_eq!(U512::from(DELEGATOR_INITIAL_BALANCE), balance); - - let delegation_amount = U512::from(DELEGATION_AMOUNT); - let delegator_account_hash = delegator_public_key.to_account_hash(); - let next_validator_key = next_validator_iter - .next() - .expect("should produce values forever"); - let delegate = create_delegate_request( - delegator_public_key, - next_validator_key.clone(), - delegation_amount, - delegator_account_hash, - contract_hash, - ); - builder.exec(delegate); - builder.expect_success(); - builder.commit(); - builder.clear_results(); - } - - let mut era_end_timestamp = TIMESTAMP_INCREMENT_MILLIS; - - group.bench_function( - format!( - "run_auction/validators/{}/delegators/{}", - validator_count, delegator_count - ), - |b| { - b.iter(|| { - era_end_timestamp += TIMESTAMP_INCREMENT_MILLIS; - step_and_run_auction(&mut builder) - }) - }, - ); -} - -fn create_delegate_request( - delegator_public_key: PublicKey, - next_validator_key: PublicKey, - delegation_amount: U512, - delegator_account_hash: AccountHash, - contract_hash: casper_types::AddressableEntityHash, -) -> ExecuteRequest { - let entry_point = auction::METHOD_DELEGATE; - let args = runtime_args! { - auction::ARG_DELEGATOR => delegator_public_key, - auction::ARG_VALIDATOR => next_validator_key, - auction::ARG_AMOUNT => delegation_amount, - }; - let mut rng = rand::thread_rng(); - let deploy_hash = rng.gen(); - let deploy = DeployItemBuilder::new() - .with_address(delegator_account_hash) - .with_stored_session_hash(contract_hash, entry_point, args) - .with_empty_payment_bytes( - runtime_args! { ARG_AMOUNT => U512::from(DEFAULT_DELEGATE_COST), }, - ) - .with_authorization_keys(&[delegator_account_hash]) - .with_deploy_hash(deploy_hash) - .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() -} - -fn generate_public_keys(key_count: usize) -> Vec { - let mut ret = Vec::with_capacity(key_count); - for _ in 0..key_count { - let bytes: [u8; SecretKey::ED25519_LENGTH] = rand::random(); - let secret_key = SecretKey::ed25519_from_bytes(bytes).unwrap(); - let public_key = PublicKey::from(&secret_key); - ret.push(public_key); - } - ret -} - -fn step_and_run_auction(builder: &mut LmdbWasmTestBuilder) { - let step_request_builder = StepRequestBuilder::new() - .with_parent_state_hash(builder.get_post_state_hash()) - .with_protocol_version(ProtocolVersion::V1_0_0); - - let step_request = step_request_builder - .with_next_era_id(builder.get_era() + 1) - .build(); - builder.step(step_request).expect("should step"); -} - -pub fn auction_bench(c: &mut Criterion) { - let mut group = c.benchmark_group("auction_bench_group"); - - /// Total number of validators, total number of delegators. Delegators will be spread - /// round-robin over the validators. - const VALIDATOR_DELEGATOR_COUNTS: [(usize, usize); 4] = - [(100, 8000), (150, 8000), (100, 10000), (150, 10000)]; - for (validator_count, delegator_count) in VALIDATOR_DELEGATOR_COUNTS { - group.sample_size(10); - group.measurement_time(Duration::from_secs(30)); - group.throughput(Throughput::Elements(1)); - println!( - "Starting bench of {} validators and {} delegators", - validator_count, delegator_count - ); - setup_bench_run_auction(&mut group, validator_count, delegator_count); - println!("Ended bench"); - } - group.finish(); -} - -criterion_group!(benches, auction_bench); -criterion_main!(benches); diff --git a/execution_engine_testing/tests/benches/transfer_bench.rs b/execution_engine_testing/tests/benches/transfer_bench.rs deleted file mode 100644 index 70ae70aeb7..0000000000 --- a/execution_engine_testing/tests/benches/transfer_bench.rs +++ /dev/null @@ -1,469 +0,0 @@ -use std::{path::Path, time::Duration}; - -use criterion::{ - criterion_group, criterion_main, - measurement::{Measurement, WallTime}, - BenchmarkGroup, Criterion, Throughput, -}; -use tempfile::TempDir; - -use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, -}; -use casper_execution_engine::engine_state::{EngineConfig, ExecuteRequest}; -use casper_types::{account::AccountHash, runtime_args, Key, URef, U512}; - -const CONTRACT_CREATE_ACCOUNTS: &str = "create_accounts.wasm"; -const CONTRACT_CREATE_PURSES: &str = "create_purses.wasm"; -const CONTRACT_TRANSFER_TO_EXISTING_ACCOUNT: &str = "transfer_to_existing_account.wasm"; -const CONTRACT_TRANSFER_TO_PURSE: &str = "transfer_to_purse.wasm"; - -/// Size of batch used in multiple execs benchmark, and multiple deploys per exec cases. -const TRANSFER_BATCH_SIZE: u64 = 3; -const TARGET_ADDR: AccountHash = AccountHash::new([127; 32]); -const ARG_AMOUNT: &str = "amount"; -const ARG_ID: &str = "id"; -const ARG_ACCOUNTS: &str = "accounts"; -const ARG_TOTAL_PURSES: &str = "total_purses"; -const ARG_TARGET: &str = "target"; -const ARG_TARGET_PURSE: &str = "target_purse"; - -const BLOCK_TRANSFER_COUNT: usize = 2500; - -/// Converts an integer into an array of type [u8; 32] by converting integer -/// into its big endian representation and embedding it at the end of the -/// range. -fn make_deploy_hash(i: u64) -> [u8; 32] { - let mut result = [128; 32]; - result[32 - 8..].copy_from_slice(&i.to_be_bytes()); - result -} - -fn bootstrap(data_dir: &Path, accounts: Vec, amount: U512) -> LmdbWasmTestBuilder { - let seed_amount = amount * accounts.len(); - let exec_request = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_CREATE_ACCOUNTS, - runtime_args! { ARG_ACCOUNTS => accounts, ARG_AMOUNT => seed_amount }, - ) - .build(); - - let engine_config = EngineConfig::default(); - - let mut builder = LmdbWasmTestBuilder::new_with_config(data_dir, engine_config); - - builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) - .exec(exec_request) - .expect_success() - .commit(); - - builder -} - -fn create_purses( - builder: &mut LmdbWasmTestBuilder, - source: AccountHash, - total_purses: u64, - purse_amount: U512, -) -> Vec { - let seed_amount = purse_amount * total_purses; - let exec_request = ExecuteRequestBuilder::standard( - source, - CONTRACT_CREATE_PURSES, - runtime_args! { ARG_TOTAL_PURSES => total_purses, ARG_AMOUNT => seed_amount }, - ) - .build(); - - builder.exec(exec_request).expect_success().commit(); - - // Return creates purses for given account by filtering named key. - let named_keys = builder.get_named_keys_by_account_hash(source); - - (0..total_purses) - .map(|index| { - let purse_lookup_key = format!("purse:{}", index); - let purse_uref = named_keys - .get(&purse_lookup_key) - .and_then(Key::as_uref) - .unwrap_or_else(|| panic!("should get named key {} as uref", purse_lookup_key)); - *purse_uref - }) - .collect() -} - -/// Uses multiple exec requests with a single deploy to transfer tokens. Executes all transfers in -/// batch determined by value of TRANSFER_BATCH_SIZE. -fn transfer_to_account_multiple_execs( - builder: &mut LmdbWasmTestBuilder, - account: AccountHash, - should_commit: bool, -) { - let amount = U512::one(); - - for _ in 0..TRANSFER_BATCH_SIZE { - let exec_request = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_TRANSFER_TO_EXISTING_ACCOUNT, - runtime_args! { - ARG_TARGET => account, - ARG_AMOUNT => amount, - }, - ) - .build(); - - let builder = builder.exec(exec_request).expect_success(); - if should_commit { - builder.commit(); - } - } -} - -/// Executes multiple deploys per single exec with based on TRANSFER_BATCH_SIZE. -fn transfer_to_account_multiple_deploys( - builder: &mut LmdbWasmTestBuilder, - account: AccountHash, - should_commit: bool, -) { - let mut exec_builder = ExecuteRequestBuilder::new(); - - for i in 0..TRANSFER_BATCH_SIZE { - let deploy = DeployItemBuilder::default() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }) - .with_session_code( - CONTRACT_TRANSFER_TO_EXISTING_ACCOUNT, - runtime_args! { - ARG_TARGET => account, - ARG_AMOUNT => U512::one(), - }, - ) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash(make_deploy_hash(i)) // deploy_hash - .build(); - exec_builder = exec_builder.push_deploy(deploy); - } - - let exec_request = exec_builder.build(); - - let builder = builder.exec(exec_request).expect_success(); - if should_commit { - builder.commit(); - } -} - -/// Uses multiple exec requests with a single deploy to transfer tokens from purse to purse. -/// Executes all transfers in batch determined by value of TRANSFER_BATCH_SIZE. -fn transfer_to_purse_multiple_execs( - builder: &mut LmdbWasmTestBuilder, - purse: URef, - should_commit: bool, -) { - let amount = U512::one(); - - for _ in 0..TRANSFER_BATCH_SIZE { - let exec_request = ExecuteRequestBuilder::standard( - TARGET_ADDR, - CONTRACT_TRANSFER_TO_PURSE, - runtime_args! { ARG_TARGET_PURSE => purse, ARG_AMOUNT => amount }, - ) - .build(); - - let builder = builder.exec(exec_request).expect_success(); - if should_commit { - builder.commit(); - } - } -} - -/// Executes multiple deploys per single exec with based on TRANSFER_BATCH_SIZE. -fn transfer_to_purse_multiple_deploys( - builder: &mut LmdbWasmTestBuilder, - purse: URef, - should_commit: bool, -) { - let mut exec_builder = ExecuteRequestBuilder::new(); - - for i in 0..TRANSFER_BATCH_SIZE { - let deploy = DeployItemBuilder::default() - .with_address(TARGET_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_session_code( - CONTRACT_TRANSFER_TO_PURSE, - runtime_args! { ARG_TARGET_PURSE => purse, ARG_AMOUNT => U512::one() }, - ) - .with_authorization_keys(&[TARGET_ADDR]) - .with_deploy_hash(make_deploy_hash(i)) // deploy_hash - .build(); - exec_builder = exec_builder.push_deploy(deploy); - } - - let exec_request = exec_builder.build(); - - let builder = builder.exec(exec_request).expect_success(); - if should_commit { - builder.commit(); - } -} - -pub fn transfer_to_existing_accounts(group: &mut BenchmarkGroup, should_commit: bool) { - let target_account = TARGET_ADDR; - let bootstrap_accounts = vec![target_account]; - - let data_dir = TempDir::new().expect("should create temp dir"); - let mut builder = bootstrap(data_dir.path(), bootstrap_accounts.clone(), U512::one()); - - group.bench_function( - format!( - "transfer_to_existing_account_multiple_execs/{}/{}", - TRANSFER_BATCH_SIZE, should_commit - ), - |b| { - b.iter(|| { - // Execute multiple deploys with multiple exec requests - transfer_to_account_multiple_execs(&mut builder, target_account, should_commit) - }) - }, - ); - - let data_dir = TempDir::new().expect("should create temp dir"); - let mut builder = bootstrap(data_dir.path(), bootstrap_accounts, U512::one()); - - group.bench_function( - format!( - "transfer_to_existing_account_multiple_deploys_per_exec/{}/{}", - TRANSFER_BATCH_SIZE, should_commit - ), - |b| { - b.iter(|| { - // Execute multiple deploys with a single exec request - transfer_to_account_multiple_deploys(&mut builder, target_account, should_commit) - }) - }, - ); -} - -// Generate multiple purses as well as transfer requests between them with the specified count. -pub fn multiple_native_transfers( - group: &mut BenchmarkGroup, - transfer_count: usize, - purse_count: usize, - use_scratch: bool, -) where - M: Measurement, -{ - let target_account = TARGET_ADDR; - let bootstrap_accounts = vec![target_account]; - - let data_dir = TempDir::new().expect("should create temp dir"); - let mut builder = bootstrap( - data_dir.path(), - bootstrap_accounts, - U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - ); - - let purse_amount = U512::one(); - let purses = create_purses( - &mut builder, - target_account, - purse_count as u64, - purse_amount, - ); - - let mut purse_index = 0usize; - let mut exec_requests = Vec::with_capacity(transfer_count); - for _ in 0..transfer_count { - let account = { - let account = purses[purse_index]; - if purse_index == purses.len() - 1 { - purse_index = 0; - } else { - purse_index += 1; - } - account - }; - let mut exec_builder = ExecuteRequestBuilder::new(); - let runtime_args = runtime_args! { - ARG_TARGET => account, - ARG_AMOUNT => U512::one(), - ARG_ID => >::None - }; - let native_transfer = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(runtime_args) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .build(); - exec_builder = exec_builder.push_deploy(native_transfer); - let exec_request = exec_builder.build(); - exec_requests.push(exec_request); - } - - let criterion_metric_name = std::any::type_name::(); - - group.bench_function( - format!( - "type:{}/transfers:{}/purses:{}/metric:{}", - if use_scratch { "scratch" } else { "lmdb" }, - transfer_count, - purse_count, - criterion_metric_name, - ), - |b| { - b.iter(|| { - transfer_to_account_multiple_native_transfers( - &mut builder, - &exec_requests, - use_scratch, - ) - }) - }, - ); -} - -/// This test simulates flushing at the end of a block. -fn transfer_to_account_multiple_native_transfers( - builder: &mut LmdbWasmTestBuilder, - execute_requests: &[ExecuteRequest], - use_scratch: bool, -) { - for exec_request in execute_requests { - let request = ExecuteRequest::new( - exec_request.parent_state_hash, - exec_request.block_time, - exec_request.deploys.clone(), - exec_request.protocol_version, - exec_request.proposer.clone(), - ); - if use_scratch { - builder.scratch_exec_and_commit(request).expect_success(); - } else { - builder.exec(request).expect_success(); - builder.commit(); - } - } - if use_scratch { - builder.write_scratch_to_db(); - } - // flush to disk only after entire block (simulates manual_sync_enabled=true config entry) - builder.flush_environment(); - - // WasmTestBuilder holds on to all execution results. This needs to be cleared to reduce - // overhead in this test - it will likely OOM without. - builder.clear_results(); -} - -pub fn transfer_to_existing_purses(group: &mut BenchmarkGroup, should_commit: bool) { - let target_account = TARGET_ADDR; - let bootstrap_accounts = vec![target_account]; - - let data_dir = TempDir::new().expect("should create temp dir"); - let mut builder = bootstrap( - data_dir.path(), - bootstrap_accounts.clone(), - U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE) * 10, - ); - - let purse_amount = U512::one(); - let purses = create_purses(&mut builder, target_account, 1, purse_amount); - - group.bench_function( - format!( - "transfer_to_purse_multiple_execs/{}/{}", - TRANSFER_BATCH_SIZE, should_commit - ), - |b| { - let target_purse = purses[0]; - b.iter(|| { - // Execute multiple deploys with multiple exec request - transfer_to_purse_multiple_execs(&mut builder, target_purse, should_commit) - }) - }, - ); - - let data_dir = TempDir::new().expect("should create temp dir"); - let mut builder = bootstrap( - data_dir.path(), - bootstrap_accounts, - U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE) * 10, - ); - let purses = create_purses(&mut builder, TARGET_ADDR, 1, U512::one()); - - group.bench_function( - format!( - "transfer_to_purse_multiple_deploys_per_exec/{}/{}", - TRANSFER_BATCH_SIZE, should_commit - ), - |b| { - let target_purse = purses[0]; - b.iter(|| { - // Execute multiple deploys with a single exec request - transfer_to_purse_multiple_deploys(&mut builder, target_purse, should_commit) - }) - }, - ); -} - -pub fn native_transfer_bench(c: &mut Criterion) -where - M: Measurement, -{ - let mut group: BenchmarkGroup<'_, M> = c.benchmark_group("tps_native"); - - // Minimum number of samples and measurement times to decrease the total time of this benchmark. - // This may or may not decrease the quality of the numbers. - group.sample_size(10); - group.measurement_time(Duration::from_secs(60)); - - // Measure by elements where one element per second is one transaction per second - group.throughput(Throughput::Elements(BLOCK_TRANSFER_COUNT as u64)); - - for purse_count in [50, 100] { - for transfer_count in [500, 1500, 2500usize] { - // baseline, one deploy per exec request - multiple_native_transfers(&mut group, transfer_count, purse_count, true); - multiple_native_transfers(&mut group, transfer_count, purse_count, false); - } - } - - group.finish(); -} - -pub fn transfer_bench(c: &mut Criterion) { - let mut group = c.benchmark_group("tps"); - - // Minimum number of samples and measurement times to decrease the total time of this benchmark. - // This may or may not decrease the quality of the numbers. - group.sample_size(10); - group.measurement_time(Duration::from_secs(10)); - - // Measure by elements where one element per second is one transaction per second - group.throughput(Throughput::Elements(TRANSFER_BATCH_SIZE)); - - // Transfers to existing accounts, no commits - transfer_to_existing_accounts(&mut group, false); - - // Transfers to existing purses, no commits - transfer_to_existing_purses(&mut group, false); - - // Transfers to existing accounts, with commits - transfer_to_existing_accounts(&mut group, true); - - // Transfers to existing purses, with commits - transfer_to_existing_purses(&mut group, true); - - group.finish(); -} - -criterion_group!( - name = native_transfer_benches; - config = Criterion::default().with_measurement(WallTime); - targets = native_transfer_bench -); -criterion_group!( - name = benches; - config = Criterion::default().with_measurement(WallTime); - targets = transfer_bench -); -criterion_main!(benches, native_transfer_benches); diff --git a/execution_engine_testing/tests/bin/README.md b/execution_engine_testing/tests/bin/README.md deleted file mode 100644 index 6f3b75454f..0000000000 --- a/execution_engine_testing/tests/bin/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# `disk_use` binary - -A binary that will construct global state and profile the disk use of various operations. It's recommended to run this tool in `--release` mode. - -The outcome is a report, `disk_use_report.csv`. This contains time-series data with the following columns, with one line per block: - -- `height` - height of the simulated chain. -- `db-size` - size on disk of the backing trie database. -- `transfers` - total number of transfers run. -- `time_ms` - time in milliseconds for a given block to run. -- `necessary_tries` - calculated value for the number of tries we expect to find in the trie database. -- `total_tries` - found total number of tries in the backing trie database. - -This report can be used to get a relatively quick view into disk and time cost of running transfers and auction processes. - diff --git a/execution_engine_testing/tests/bin/disk_use.rs b/execution_engine_testing/tests/bin/disk_use.rs deleted file mode 100644 index b2f533e039..0000000000 --- a/execution_engine_testing/tests/bin/disk_use.rs +++ /dev/null @@ -1,24 +0,0 @@ -use std::{fs::File, io::BufWriter}; - -use casper_engine_test_support::auction::run_blocks_with_transfers_and_step; - -fn main() { - let purse_count = 100; - let total_transfer_count = 100; - let transfers_per_block = 1; - let block_count = total_transfer_count / transfers_per_block; - let delegator_count = 20_000; - let validator_count = 100; - - let report_writer = BufWriter::new(File::create("disk_use_report.csv").unwrap()); - run_blocks_with_transfers_and_step( - transfers_per_block, - purse_count, - true, - true, - block_count, - delegator_count, - validator_count, - report_writer, - ); -} diff --git a/execution_engine_testing/tests/src/lmdb_fixture.rs b/execution_engine_testing/tests/src/lmdb_fixture.rs index b5444088a0..932426902c 100644 --- a/execution_engine_testing/tests/src/lmdb_fixture.rs +++ b/execution_engine_testing/tests/src/lmdb_fixture.rs @@ -37,7 +37,7 @@ pub(crate) fn is_fixture_generator_enabled() -> bool { /// This is a special place in the global state where fixture contains a registry. #[cfg(test)] -pub(crate) const CONTRACT_REGISTRY_SPECIAL_ADDRESS: Key = +pub(crate) const ENTRY_REGISTRY_SPECIAL_ADDRESS: Key = Key::URef(URef::new([0u8; 32], AccessRights::all())); fn path_to_lmdb_fixtures() -> PathBuf { diff --git a/execution_engine_testing/tests/src/test/bulk_update_with_scratch_trie.rs b/execution_engine_testing/tests/src/test/bulk_update_with_scratch_trie.rs deleted file mode 100644 index 31d7346b67..0000000000 --- a/execution_engine_testing/tests/src/test/bulk_update_with_scratch_trie.rs +++ /dev/null @@ -1,26 +0,0 @@ -use std::{fs::File, io::BufWriter}; - -use casper_engine_test_support::auction::run_blocks_with_transfers_and_step; - -#[ignore] -#[test] -fn should_run_transfers_and_auction_producing_expected_number_of_tries_only() { - let purse_count = 100; - let total_transfer_count = 10; - let transfers_per_block = 1; - let block_count = total_transfer_count / transfers_per_block; - let delegator_count = 100; - let validator_count = 10; - - let report_writer = BufWriter::new(File::create("disk_use_report.csv").unwrap()); - run_blocks_with_transfers_and_step( - transfers_per_block, - purse_count, - true, - true, - block_count, - delegator_count, - validator_count, - report_writer, - ); -} diff --git a/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs b/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs index baabd46871..946ba35416 100644 --- a/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs +++ b/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs @@ -76,10 +76,7 @@ fn should_raise_auth_failure_with_invalid_key() { let deploy_result = builder .get_exec_result_owned(0) - .expect("should have exec response") - .get(0) - .cloned() - .expect("should have at least one deploy result"); + .expect("should have exec response"); assert!( deploy_result.has_precondition_failure(), @@ -132,10 +129,7 @@ fn should_raise_auth_failure_with_invalid_keys() { let deploy_result = builder .get_exec_result_owned(0) - .expect("should have exec response") - .get(0) - .cloned() - .expect("should have at least one deploy result"); + .expect("should have exec response"); assert!(deploy_result.has_precondition_failure()); let message = format!("{}", deploy_result.as_error().unwrap()); @@ -234,10 +228,7 @@ fn should_raise_deploy_authorization_failure() { { let deploy_result = builder .get_exec_result_owned(0) - .expect("should have exec response") - .get(0) - .cloned() - .expect("should have at least one deploy result"); + .expect("should have exec response"); assert!(deploy_result.has_precondition_failure()); let message = format!("{}", deploy_result.as_error().unwrap()); @@ -296,10 +287,7 @@ fn should_raise_deploy_authorization_failure() { { let deploy_result = builder .get_exec_result_owned(0) - .expect("should have exec response") - .get(0) - .cloned() - .expect("should have at least one deploy result"); + .expect("should have exec response"); assert!(deploy_result.has_precondition_failure()); let message = format!("{}", deploy_result.as_error().unwrap()); @@ -461,10 +449,7 @@ fn should_not_authorize_deploy_with_duplicated_keys() { builder.clear_results().exec(exec_request_3).commit(); let deploy_result = builder .get_exec_result_owned(0) - .expect("should have exec response") - .get(0) - .cloned() - .expect("should have at least one deploy result"); + .expect("should have exec response"); assert!( deploy_result.has_precondition_failure(), @@ -549,10 +534,7 @@ fn should_not_authorize_transfer_without_deploy_key_threshold() { let response = builder .get_exec_result_owned(3) - .expect("should have response") - .first() - .cloned() - .expect("should have first result"); + .expect("should have response"); let error = response.as_error().expect("should have error"); assert!(matches!( error, diff --git a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs index dae1a60693..1d1a579a5f 100644 --- a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs +++ b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs @@ -234,9 +234,8 @@ fn should_not_write_with_read_access_rights() { builder.exec(call_request).commit(); - let exec_results = builder.get_last_exec_result().expect("should have results"); - assert_eq!(exec_results.len(), 1); - let error = exec_results[0].as_error().expect("should have error"); + let exec_result = builder.get_last_exec_result().expect("should have results"); + let error = exec_result.as_error().expect("should have error"); assert!( matches!( error, @@ -286,10 +285,8 @@ fn should_not_read_with_write_access_rights() { builder.exec(call_request).commit(); - let exec_results = builder.get_last_exec_result().expect("should have results"); - - assert_eq!(exec_results.len(), 1); - let error = exec_results[0].as_error().expect("should have error"); + let exec_result = builder.get_last_exec_result().expect("should have results"); + let error = exec_result.as_error().expect("should have error"); assert!( matches!( error, @@ -367,9 +364,8 @@ fn should_not_write_with_forged_uref() { builder.exec(call_request).commit(); - let exec_results = builder.get_last_exec_result().expect("should have results"); - assert_eq!(exec_results.len(), 1); - let error = exec_results[0].as_error().expect("should have error"); + let exec_result = builder.get_last_exec_result().expect("should have results"); + let error = exec_result.as_error().expect("should have error"); assert!( matches!( error, @@ -405,9 +401,8 @@ fn should_fail_put_with_invalid_dictionary_item_key() { .build(); builder.exec(call_request).commit(); - let exec_results = builder.get_last_exec_result().expect("should have results"); - assert_eq!(exec_results.len(), 1); - let error = exec_results[0].as_error().expect("should have error"); + let exec_result = builder.get_last_exec_result().expect("should have results"); + let error = exec_result.as_error().expect("should have error"); assert!( matches!( error, @@ -442,9 +437,8 @@ fn should_fail_get_with_invalid_dictionary_item_key() { .build(); builder.exec(call_request).commit(); - let exec_results = builder.get_last_exec_result().expect("should have results"); - assert_eq!(exec_results.len(), 1); - let error = exec_results[0].as_error().expect("should have error"); + let exec_result = builder.get_last_exec_result().expect("should have results"); + let error = exec_result.as_error().expect("should have error"); assert!( matches!( error, @@ -483,9 +477,8 @@ fn dictionary_put_should_fail_with_large_item_key() { builder.exec(fund_request).commit().expect_success(); builder.exec(install_contract_request).commit(); - let exec_results = builder.get_last_exec_result().expect("should have results"); - assert_eq!(exec_results.len(), 1); - let error = exec_results[0].as_error().expect("should have error"); + let exec_result = builder.get_last_exec_result().expect("should have results"); + let error = exec_result.as_error().expect("should have error"); assert!( matches!( error, @@ -524,9 +517,8 @@ fn dictionary_get_should_fail_with_large_item_key() { builder.exec(fund_request).commit().expect_success(); builder.exec(install_contract_request).commit(); - let exec_results = builder.get_last_exec_result().expect("should have results"); - assert_eq!(exec_results.len(), 1); - let error = exec_results[0].as_error().expect("should have error"); + let exec_result = builder.get_last_exec_result().expect("should have results"); + let error = exec_result.as_error().expect("should have error"); assert!( matches!( error, diff --git a/execution_engine_testing/tests/src/test/contract_api/get_arg.rs b/execution_engine_testing/tests/src/test/contract_api/get_arg.rs index ad548a0710..75be3aeb37 100644 --- a/execution_engine_testing/tests/src/test/contract_api/get_arg.rs +++ b/execution_engine_testing/tests/src/test/contract_api/get_arg.rs @@ -1,5 +1,5 @@ use casper_engine_test_support::{ - utils, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_types::{runtime_args, ApiError, RuntimeArgs, U512}; @@ -25,11 +25,7 @@ fn call_get_arg(args: RuntimeArgs) -> Result<(), String> { return Ok(()); } - let response = builder - .get_exec_result_owned(0) - .expect("should have a response"); - - let error_message = utils::get_error_message(response); + let error_message = builder.get_error_message().expect("should have a result"); Err(error_message) } diff --git a/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs b/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs index 33e5a3da5f..9f5ab1adb6 100644 --- a/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs +++ b/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs @@ -172,7 +172,7 @@ impl BuilderExt for LmdbWasmTestBuilder { let current_entity_hash = package.current_entity_hash().unwrap(); let current_contract_entity_key = - EntityAddr::new_contract_entity_addr(current_entity_hash.value()); + EntityAddr::new_smart_contract(current_entity_hash.value()); let cl_value = self .query( @@ -3177,14 +3177,14 @@ mod payment { ARG_CURRENT_DEPTH => 0u8, mint::ARG_AMOUNT => approved_amount(call_depth), }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_payment_code(CONTRACT_CALL_RECURSIVE_SUBCALL, args) .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) .with_authorization_keys(&[sender]) .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; super::execute_and_assert_result( @@ -3212,7 +3212,7 @@ mod payment { mint::ARG_AMOUNT => approved_amount(call_depth), }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_versioned_payment_contract_by_name( CONTRACT_PACKAGE_NAME, @@ -3225,7 +3225,7 @@ mod payment { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; super::execute_and_assert_result( @@ -3251,7 +3251,7 @@ mod payment { ARG_CURRENT_DEPTH => 0u8, mint::ARG_AMOUNT => approved_amount(call_depth), }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_versioned_payment_contract_by_hash( current_contract_package_hash, @@ -3263,7 +3263,7 @@ mod payment { .with_authorization_keys(&[sender]) .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; super::execute_and_assert_result( @@ -3291,7 +3291,7 @@ mod payment { mint::ARG_AMOUNT => approved_amount(call_depth), }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_payment_named_key( CONTRACT_NAME, @@ -3303,7 +3303,7 @@ mod payment { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; super::execute_and_assert_result( @@ -3329,7 +3329,7 @@ mod payment { ARG_CURRENT_DEPTH => 0u8, mint::ARG_AMOUNT => approved_amount(call_depth), }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_payment_hash( current_contract_hash.into(), @@ -3340,7 +3340,7 @@ mod payment { .with_authorization_keys(&[sender]) .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let is_entry_point_type_session = true; diff --git a/execution_engine_testing/tests/src/test/contract_api/get_phase.rs b/execution_engine_testing/tests/src/test/contract_api/get_phase.rs index 578257c57f..98b2aff4e9 100644 --- a/execution_engine_testing/tests/src/test/contract_api/get_phase.rs +++ b/execution_engine_testing/tests/src/test/contract_api/get_phase.rs @@ -13,7 +13,7 @@ fn should_run_get_phase_contract() { let default_account = *DEFAULT_ACCOUNT_ADDR; let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_session_code( @@ -30,7 +30,7 @@ fn should_run_get_phase_contract() { .with_authorization_keys(&[default_account]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; LmdbWasmTestBuilder::default() diff --git a/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs b/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs index 97e5fd8a34..e363a9a7ea 100644 --- a/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs +++ b/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs @@ -109,7 +109,7 @@ fn test_match( }; let deploy_hash = [42; 32]; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(caller) .with_session_code(CONTRACT_LIST_AUTHORIZATION_KEYS, session_args) .with_empty_payment_bytes(runtime_args! { @@ -118,7 +118,7 @@ fn test_match( .with_authorization_keys(&signatures) .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request).commit(); diff --git a/execution_engine_testing/tests/src/test/contract_api/multisig_authorization.rs b/execution_engine_testing/tests/src/test/contract_api/multisig_authorization.rs index c22ab19143..c3f5117f2f 100644 --- a/execution_engine_testing/tests/src/test/contract_api/multisig_authorization.rs +++ b/execution_engine_testing/tests/src/test/contract_api/multisig_authorization.rs @@ -152,14 +152,14 @@ fn test_multisig_auth( ARG_AMOUNT => *DEFAULT_PAYMENT }; let deploy_hash = [42; 32]; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(caller) .with_stored_session_named_key(CONTRACT_KEY, entry_point, session_args) .with_empty_payment_bytes(payment_args) .with_authorization_keys(authorization_keys) .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request).commit(); diff --git a/execution_engine_testing/tests/src/test/contract_api/runtime.rs b/execution_engine_testing/tests/src/test/contract_api/runtime.rs index 8939bcca39..78f547eadb 100644 --- a/execution_engine_testing/tests/src/test/contract_api/runtime.rs +++ b/execution_engine_testing/tests/src/test/contract_api/runtime.rs @@ -48,7 +48,7 @@ fn should_return_different_random_bytes_on_different_phases() { let mut rng = rand::thread_rng(); let deploy_hash = rng.gen(); let address = *DEFAULT_ACCOUNT_ADDR; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(address) .with_session_code(RANDOM_BYTES_WASM, runtime_args! {}) .with_payment_code( @@ -60,7 +60,7 @@ fn should_return_different_random_bytes_on_different_phases() { .with_authorization_keys(&[address]) .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(execute_request).commit().expect_success(); diff --git a/execution_engine_testing/tests/src/test/contract_api/subcall.rs b/execution_engine_testing/tests/src/test/contract_api/subcall.rs index 2cca9dedf5..a6898f0f6c 100644 --- a/execution_engine_testing/tests/src/test/contract_api/subcall.rs +++ b/execution_engine_testing/tests/src/test/contract_api/subcall.rs @@ -4,9 +4,7 @@ use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, PRODUCTION_RUN_GENESIS_REQUEST, }; -use casper_types::{ - package::ENTITY_INITIAL_VERSION, runtime_args, RuntimeArgs, StorageCosts, U512, -}; +use casper_types::{runtime_args, RuntimeArgs, StorageCosts, ENTITY_INITIAL_VERSION, U512}; const ARG_TARGET: &str = "target_contract"; const ARG_GAS_AMOUNT: &str = "gas_amount"; @@ -51,11 +49,11 @@ fn should_charge_gas_for_subcall() { builder.exec(no_subcall_request).expect_success().commit(); - let do_nothing_cost = builder.exec_costs(0)[0]; + let do_nothing_cost = builder.exec_cost(0); - let do_something_cost = builder.exec_costs(1)[0]; + let do_something_cost = builder.exec_cost(1); - let no_subcall_cost = builder.exec_costs(2)[0]; + let no_subcall_cost = builder.exec_cost(2); assert_ne!( do_nothing_cost, do_something_cost, @@ -150,10 +148,10 @@ fn should_add_all_gas_for_subcall() { .expect_success() .commit(); - let add_zero_gas_from_session_cost = builder.exec_costs(0)[0]; - let add_some_gas_from_session_cost = builder.exec_costs(1)[0]; - let add_zero_gas_via_subcall_cost = builder.exec_costs(2)[0]; - let add_some_gas_via_subcall_cost = builder.exec_costs(3)[0]; + let add_zero_gas_from_session_cost = builder.exec_cost(0); + let add_some_gas_from_session_cost = builder.exec_cost(1); + let add_zero_gas_via_subcall_cost = builder.exec_cost(2); + let add_some_gas_via_subcall_cost = builder.exec_cost(3); let expected_gas = U512::from(StorageCosts::default().gas_per_byte()) * gas_to_add; assert!( @@ -239,9 +237,9 @@ fn expensive_subcall_should_cost_more() { .expect_success() .commit(); - let do_nothing_cost = builder.exec_costs(2)[0]; + let do_nothing_cost = builder.exec_cost(2); - let expensive_calculation_cost = builder.exec_costs(3)[0]; + let expensive_calculation_cost = builder.exec_cost(3); assert!( do_nothing_cost < expensive_calculation_cost, diff --git a/execution_engine_testing/tests/src/test/contract_api/transfer.rs b/execution_engine_testing/tests/src/test/contract_api/transfer.rs index a514a6eb52..a70e559812 100644 --- a/execution_engine_testing/tests/src/test/contract_api/transfer.rs +++ b/execution_engine_testing/tests/src/test/contract_api/transfer.rs @@ -460,11 +460,10 @@ fn should_fail_when_insufficient_funds() { .exec(exec_request_3) .commit(); - let exec_results = builder + let exec_result = builder .get_exec_result_owned(2) .expect("should have exec response"); - assert_eq!(exec_results.len(), 1); - let exec_result = exec_results[0].as_error().expect("should have error"); + let exec_result = exec_result.as_error().expect("should have error"); let error = assert_matches!(exec_result, EngineError::Exec(Error::Revert(e)) => *e, "{:?}", exec_result); assert_eq!(error, ApiError::from(mint::Error::InsufficientFunds)); } diff --git a/execution_engine_testing/tests/src/test/contract_api/transfer_cached.rs b/execution_engine_testing/tests/src/test/contract_api/transfer_cached.rs index da5c9261f9..544e10f8ee 100644 --- a/execution_engine_testing/tests/src/test/contract_api/transfer_cached.rs +++ b/execution_engine_testing/tests/src/test/contract_api/transfer_cached.rs @@ -41,8 +41,7 @@ fn should_transfer_to_account_with_correct_balances() { let pre_state_hash = builder.get_post_state_hash(); // Default account to account 1 - let mut exec_builder = ExecuteRequestBuilder::new(); - exec_builder = exec_builder.push_deploy(transfer( + let exec_builder = ExecuteRequestBuilder::from_deploy_item(transfer( *DEFAULT_ACCOUNT_ADDR, runtime_args! { ARG_TARGET => *ACCOUNT_1_ADDR, @@ -98,48 +97,48 @@ fn should_transfer_from_default_and_then_to_another_account() { let pre_state_hash = builder.get_post_state_hash(); // Default account to account 1 - let mut exec_builder = ExecuteRequestBuilder::new(); // We must first transfer the amount account 1 will transfer to account 2, along with the fee // account 1 will need to pay for that transfer. - exec_builder = exec_builder.push_deploy(transfer( + let exec_request = ExecuteRequestBuilder::from_deploy_item(transfer( *DEFAULT_ACCOUNT_ADDR, runtime_args! { ARG_TARGET => *ACCOUNT_1_ADDR, ARG_AMOUNT => *TRANSFER_AMOUNT + DEFAULT_WASMLESS_TRANSFER_COST, ARG_ID => ID_NONE, }, - )); + )) + .build(); builder - .scratch_exec_and_commit(exec_builder.build()) + .scratch_exec_and_commit(exec_request) .expect_success(); - let mut exec_builder = ExecuteRequestBuilder::new(); - exec_builder = exec_builder.push_deploy(transfer( + let exec_request = ExecuteRequestBuilder::from_deploy_item(transfer( *ACCOUNT_1_ADDR, runtime_args! { ARG_TARGET => *ACCOUNT_2_ADDR, ARG_AMOUNT => *TRANSFER_AMOUNT, ARG_ID => ID_NONE, }, - )); + )) + .build(); builder - .scratch_exec_and_commit(exec_builder.build()) + .scratch_exec_and_commit(exec_request) .expect_success(); // Double spend test for account 1 - let mut exec_builder = ExecuteRequestBuilder::new(); - exec_builder = exec_builder.push_deploy(transfer( + let exec_request = ExecuteRequestBuilder::from_deploy_item(transfer( *ACCOUNT_1_ADDR, runtime_args! { ARG_TARGET => *ACCOUNT_2_ADDR, ARG_AMOUNT => *TRANSFER_AMOUNT, ARG_ID => ID_NONE, }, - )); + )) + .build(); builder - .scratch_exec_and_commit(exec_builder.build()) + .scratch_exec_and_commit(exec_request) .expect_failure(); builder.write_scratch_to_db(); diff --git a/execution_engine_testing/tests/src/test/contract_context.rs b/execution_engine_testing/tests/src/test/contract_context.rs index 850cd237aa..999c6cf62a 100644 --- a/execution_engine_testing/tests/src/test/contract_context.rs +++ b/execution_engine_testing/tests/src/test/contract_context.rs @@ -3,7 +3,7 @@ use casper_engine_test_support::{ PRODUCTION_RUN_GENESIS_REQUEST, }; -use casper_types::{package::ENTITY_INITIAL_VERSION, runtime_args, Key, RuntimeArgs}; +use casper_types::{runtime_args, Key, RuntimeArgs, ENTITY_INITIAL_VERSION}; const CONTRACT_HEADERS: &str = "contract_context.wasm"; const PACKAGE_HASH_KEY: &str = "package_hash_key"; diff --git a/execution_engine_testing/tests/src/test/deploy/context_association.rs b/execution_engine_testing/tests/src/test/deploy/context_association.rs index 7f8f60632c..32d3d134b9 100644 --- a/execution_engine_testing/tests/src/test/deploy/context_association.rs +++ b/execution_engine_testing/tests/src/test/deploy/context_association.rs @@ -18,7 +18,7 @@ fn should_put_system_contract_hashes_to_account_context() { let mut builder = LmdbWasmTestBuilder::default(); let request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code(SYSTEM_CONTRACT_HASHES_WASM, runtime_args! {}) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount}) @@ -26,7 +26,7 @@ fn should_put_system_contract_hashes_to_account_context() { .with_deploy_hash([1; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder diff --git a/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs b/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs index 7adcd310aa..5ebfea37a5 100644 --- a/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs +++ b/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs @@ -69,7 +69,7 @@ fn should_charge_non_main_purse() { // should be able to pay for exec using new purse let account_payment_exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(ACCOUNT_1_ADDR) .with_session_code(DO_NOTHING_WASM, RuntimeArgs::default()) .with_payment_code( @@ -83,7 +83,7 @@ fn should_charge_non_main_purse() { .with_deploy_hash([3; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let proposer_reward_starting_balance = builder.get_proposer_purse_balance(); diff --git a/execution_engine_testing/tests/src/test/deploy/preconditions.rs b/execution_engine_testing/tests/src/test/deploy/preconditions.rs index 16a56f7d9d..e8d4e191ea 100644 --- a/execution_engine_testing/tests/src/test/deploy/preconditions.rs +++ b/execution_engine_testing/tests/src/test/deploy/preconditions.rs @@ -20,7 +20,7 @@ fn should_raise_precondition_authorization_failure_invalid_account() { let transferred_amount = 1; let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_session_code( @@ -32,7 +32,7 @@ fn should_raise_precondition_authorization_failure_invalid_account() { .with_authorization_keys(&[nonexistent_account_addr]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let mut builder = LmdbWasmTestBuilder::default(); @@ -57,7 +57,7 @@ fn should_raise_precondition_authorization_failure_invalid_account() { fn should_raise_precondition_authorization_failure_empty_authorized_keys() { let empty_keys: [AccountHash; 0] = []; let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code("do_nothing.wasm", RuntimeArgs::default()) .with_empty_payment_bytes(RuntimeArgs::default()) @@ -66,7 +66,7 @@ fn should_raise_precondition_authorization_failure_empty_authorized_keys() { .with_authorization_keys(&empty_keys) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let mut builder = LmdbWasmTestBuilder::default(); @@ -95,7 +95,7 @@ fn should_raise_precondition_authorization_failure_invalid_authorized_keys() { let transferred_amount = 1; let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_session_code( @@ -107,7 +107,7 @@ fn should_raise_precondition_authorization_failure_invalid_authorized_keys() { .with_authorization_keys(&[nonexistent_account_addr]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let mut builder = LmdbWasmTestBuilder::default(); diff --git a/execution_engine_testing/tests/src/test/deploy/receipts.rs b/execution_engine_testing/tests/src/test/deploy/receipts.rs index 1374e20caf..403c2cd36d 100644 --- a/execution_engine_testing/tests/src/test/deploy/receipts.rs +++ b/execution_engine_testing/tests/src/test/deploy/receipts.rs @@ -7,7 +7,7 @@ use casper_engine_test_support::{ PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_types::{ - account::AccountHash, runtime_args, system::mint, AccessRights, DeployHash, PublicKey, + account::AccountHash, runtime_args, system::mint, AccessRights, Gas, InitiatorAddr, PublicKey, SecretKey, Transfer, TransferAddr, U512, }; @@ -65,14 +65,7 @@ fn should_record_wasmless_transfer() { ) .build(); - let deploy_hash = { - let deploy_items: Vec = transfer_request - .deploys() - .iter() - .map(|deploy_item| deploy_item.deploy_hash) - .collect(); - deploy_items[0] - }; + let txn_hash = transfer_request.transaction_hash; builder.exec(transfer_request).commit().expect_success(); @@ -88,31 +81,37 @@ fn should_record_wasmless_transfer() { .main_purse() .with_access_rights(AccessRights::ADD); - let deploy_info = builder - .get_deploy_info(deploy_hash) - .expect("should have deploy info"); + let txn_info = builder + .get_transaction_info(txn_hash) + .expect("should have txn info"); - assert_eq!(deploy_info.deploy_hash, deploy_hash); - assert_eq!(deploy_info.from, *DEFAULT_ACCOUNT_ADDR); - assert_eq!(deploy_info.source, default_account.main_purse()); + assert_eq!(txn_info.transaction_hash, txn_hash); + assert_eq!( + txn_info.from, + InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR) + ); + assert_eq!(txn_info.source, default_account.main_purse()); // TODO: reenable after new payment logic is added - // assert_eq!(deploy_info.gas, U512::from(DEFAULT_WASMLESS_TRANSFER_COST)); + // assert_eq!(txn_info.gas, U512::from(DEFAULT_WASMLESS_TRANSFER_COST)); - let transfers = deploy_info.transfers; + let transfers = txn_info.transfers; assert_eq!(transfers.len(), 1); let transfer = builder .get_transfer(transfers[0]) .expect("should have transfer"); - assert_eq!(transfer.deploy_hash, deploy_hash); - assert_eq!(transfer.from, *DEFAULT_ACCOUNT_ADDR); + assert_eq!(transfer.transaction_hash, txn_hash); + assert_eq!( + transfer.from, + InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR) + ); assert_eq!(transfer.to, Some(*ALICE_ADDR)); assert_eq!(transfer.source, default_account.main_purse()); assert_eq!(transfer.target, alice_attenuated_main_purse); assert_eq!(transfer.amount, *TRANSFER_AMOUNT_1); - assert_eq!(transfer.gas, U512::zero()); + assert_eq!(transfer.gas, Gas::zero()); assert_eq!(transfer.id, id); } @@ -132,14 +131,7 @@ fn should_record_wasm_transfer() { ) .build(); - let deploy_hash = { - let deploy_items: Vec = transfer_request - .deploys() - .iter() - .map(|deploy_item| deploy_item.deploy_hash) - .collect(); - deploy_items[0] - }; + let txn_hash = transfer_request.transaction_hash; builder.exec(transfer_request).commit().expect_success(); @@ -155,28 +147,34 @@ fn should_record_wasm_transfer() { .main_purse() .with_access_rights(AccessRights::ADD); - let deploy_info = builder - .get_deploy_info(deploy_hash) - .expect("should have deploy info"); + let txn_info = builder + .get_transaction_info(txn_hash) + .expect("should have txn info"); - assert_eq!(deploy_info.deploy_hash, deploy_hash); - assert_eq!(deploy_info.from, *DEFAULT_ACCOUNT_ADDR); - assert_eq!(deploy_info.source, default_account.main_purse()); - assert_ne!(deploy_info.gas, U512::zero()); + assert_eq!(txn_info.transaction_hash, txn_hash); + assert_eq!( + txn_info.from, + InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR) + ); + assert_eq!(txn_info.source, default_account.main_purse()); + assert_ne!(txn_info.gas, Gas::zero()); - let transfers = deploy_info.transfers; + let transfers = txn_info.transfers; assert_eq!(transfers.len(), 1); let transfer = builder .get_transfer(transfers[0]) .expect("should have transfer"); - assert_eq!(transfer.deploy_hash, deploy_hash); - assert_eq!(transfer.from, *DEFAULT_ACCOUNT_ADDR); + assert_eq!(transfer.transaction_hash, txn_hash); + assert_eq!( + transfer.from, + InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR) + ); assert_eq!(transfer.source, default_account.main_purse()); assert_eq!(transfer.target, alice_attenuated_main_purse); assert_eq!(transfer.amount, *TRANSFER_AMOUNT_1); - assert_eq!(transfer.gas, U512::zero()) // TODO + assert_eq!(transfer.gas, Gas::zero()) // TODO } #[ignore] @@ -198,14 +196,7 @@ fn should_record_wasm_transfer_with_id() { ) .build(); - let deploy_hash = { - let deploy_items: Vec = transfer_request - .deploys() - .iter() - .map(|deploy_item| deploy_item.deploy_hash) - .collect(); - deploy_items[0] - }; + let txn_hash = transfer_request.transaction_hash; builder.exec(transfer_request).commit().expect_success(); @@ -221,28 +212,34 @@ fn should_record_wasm_transfer_with_id() { .main_purse() .with_access_rights(AccessRights::ADD); - let deploy_info = builder - .get_deploy_info(deploy_hash) - .expect("should have deploy info"); + let txn_info = builder + .get_transaction_info(txn_hash) + .expect("should have txn info"); - assert_eq!(deploy_info.deploy_hash, deploy_hash); - assert_eq!(deploy_info.from, *DEFAULT_ACCOUNT_ADDR); - assert_eq!(deploy_info.source, default_account.main_purse()); - assert_ne!(deploy_info.gas, U512::zero()); + assert_eq!(txn_info.transaction_hash, txn_hash); + assert_eq!( + txn_info.from, + InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR) + ); + assert_eq!(txn_info.source, default_account.main_purse()); + assert_ne!(txn_info.gas, Gas::zero()); - let transfers = deploy_info.transfers; + let transfers = txn_info.transfers; assert_eq!(transfers.len(), 1); let transfer = builder .get_transfer(transfers[0]) .expect("should have transfer"); - assert_eq!(transfer.deploy_hash, deploy_hash); - assert_eq!(transfer.from, *DEFAULT_ACCOUNT_ADDR); + assert_eq!(transfer.transaction_hash, txn_hash); + assert_eq!( + transfer.from, + InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR) + ); assert_eq!(transfer.source, default_account.main_purse()); assert_eq!(transfer.target, alice_attenuated_main_purse); assert_eq!(transfer.amount, *TRANSFER_AMOUNT_1); - assert_eq!(transfer.gas, U512::zero()); // TODO + assert_eq!(transfer.gas, Gas::zero()); // TODO assert_eq!(transfer.id, id); } @@ -274,14 +271,7 @@ fn should_record_wasm_transfers() { ) .build(); - let deploy_hash = { - let deploy_items: Vec = transfer_request - .deploys() - .iter() - .map(|deploy_item| deploy_item.deploy_hash) - .collect(); - deploy_items[0] - }; + let txn_hash = transfer_request.transaction_hash; builder.exec(transfer_request).commit().expect_success(); @@ -313,17 +303,20 @@ fn should_record_wasm_transfers() { .main_purse() .with_access_rights(AccessRights::ADD); - let deploy_info = builder - .get_deploy_info(deploy_hash) - .expect("should have deploy info"); + let txn_info = builder + .get_transaction_info(txn_hash) + .expect("should have txn info"); - assert_eq!(deploy_info.deploy_hash, deploy_hash); - assert_eq!(deploy_info.from, *DEFAULT_ACCOUNT_ADDR); - assert_eq!(deploy_info.source, default_account.main_purse()); - assert_ne!(deploy_info.gas, U512::zero()); + assert_eq!(txn_info.transaction_hash, txn_hash); + assert_eq!( + txn_info.from, + InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR) + ); + assert_eq!(txn_info.source, default_account.main_purse()); + assert_ne!(txn_info.gas, Gas::zero()); const EXPECTED_LENGTH: usize = 3; - let transfer_addrs = deploy_info.transfers; + let transfer_addrs = txn_info.transfers; assert_eq!(transfer_addrs.len(), EXPECTED_LENGTH); assert_eq!( transfer_addrs @@ -348,35 +341,35 @@ fn should_record_wasm_transfers() { assert_eq!(transfers.len(), EXPECTED_LENGTH); assert!(transfers.contains(&Transfer { - deploy_hash, - from: *DEFAULT_ACCOUNT_ADDR, + transaction_hash: txn_hash, + from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*ALICE_ADDR), source: default_account.main_purse(), target: alice_attenuated_main_purse, amount: *TRANSFER_AMOUNT_1, - gas: U512::zero(), + gas: Gas::zero(), id: alice_id, })); assert!(transfers.contains(&Transfer { - deploy_hash, - from: *DEFAULT_ACCOUNT_ADDR, + transaction_hash: txn_hash, + from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*BOB_ADDR), source: default_account.main_purse(), target: bob_attenuated_main_purse, amount: *TRANSFER_AMOUNT_2, - gas: U512::zero(), + gas: Gas::zero(), id: bob_id, })); assert!(transfers.contains(&Transfer { - deploy_hash, - from: *DEFAULT_ACCOUNT_ADDR, + transaction_hash: txn_hash, + from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*CAROL_ADDR), source: default_account.main_purse(), target: carol_attenuated_main_purse, amount: *TRANSFER_AMOUNT_3, - gas: U512::zero(), + gas: Gas::zero(), id: carol_id, })); } @@ -420,14 +413,7 @@ fn should_record_wasm_transfers_with_subcall() { ) .build(); - let transfer_deploy_hash = { - let deploy_items: Vec = transfer_request - .deploys() - .iter() - .map(|deploy_item| deploy_item.deploy_hash) - .collect(); - deploy_items[0] - }; + let transfer_txn_hash = transfer_request.transaction_hash; builder.exec(store_request).commit().expect_success(); builder.exec(transfer_request).commit().expect_success(); @@ -478,17 +464,20 @@ fn should_record_wasm_transfers_with_subcall() { .main_purse() .with_access_rights(AccessRights::ADD); - let deploy_info = builder - .get_deploy_info(transfer_deploy_hash) - .expect("should have deploy info"); + let txn_info = builder + .get_transaction_info(transfer_txn_hash) + .expect("should have txn info"); - assert_eq!(deploy_info.deploy_hash, transfer_deploy_hash); - assert_eq!(deploy_info.from, *DEFAULT_ACCOUNT_ADDR); - assert_eq!(deploy_info.source, default_account.main_purse()); - assert_ne!(deploy_info.gas, U512::zero()); + assert_eq!(txn_info.transaction_hash, transfer_txn_hash); + assert_eq!( + txn_info.from, + InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR) + ); + assert_eq!(txn_info.source, default_account.main_purse()); + assert_ne!(txn_info.gas, Gas::zero()); const EXPECTED_LENGTH: usize = 6; - let transfer_addrs = deploy_info.transfers; + let transfer_addrs = txn_info.transfers; assert_eq!(transfer_addrs.len(), EXPECTED_LENGTH); assert_eq!( transfer_addrs @@ -511,35 +500,35 @@ fn should_record_wasm_transfers_with_subcall() { }; let session_expected_alice = Transfer { - deploy_hash: transfer_deploy_hash, - from: *DEFAULT_ACCOUNT_ADDR, + transaction_hash: transfer_txn_hash, + from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*ALICE_ADDR), source: default_account.main_purse(), target: alice_attenuated_main_purse, amount: *TRANSFER_AMOUNT_1, - gas: U512::zero(), + gas: Gas::zero(), id: alice_id, }; let session_expected_bob = Transfer { - deploy_hash: transfer_deploy_hash, - from: *DEFAULT_ACCOUNT_ADDR, + transaction_hash: transfer_txn_hash, + from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*BOB_ADDR), source: default_account.main_purse(), target: bob_attenuated_main_purse, amount: *TRANSFER_AMOUNT_2, - gas: U512::zero(), + gas: Gas::zero(), id: bob_id, }; let session_expected_carol = Transfer { - deploy_hash: transfer_deploy_hash, - from: *DEFAULT_ACCOUNT_ADDR, + transaction_hash: transfer_txn_hash, + from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*CAROL_ADDR), source: default_account.main_purse(), target: carol_attenuated_main_purse, amount: *TRANSFER_AMOUNT_3, - gas: U512::zero(), + gas: Gas::zero(), id: carol_id, }; @@ -561,35 +550,35 @@ fn should_record_wasm_transfers_with_subcall() { } let stored_expected_alice = Transfer { - deploy_hash: transfer_deploy_hash, - from: *DEFAULT_ACCOUNT_ADDR, + transaction_hash: transfer_txn_hash, + from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*ALICE_ADDR), source: contract_purse, target: alice_attenuated_main_purse, amount: *TRANSFER_AMOUNT_1, - gas: U512::zero(), + gas: Gas::zero(), id: alice_id, }; let stored_expected_bob = Transfer { - deploy_hash: transfer_deploy_hash, - from: *DEFAULT_ACCOUNT_ADDR, + transaction_hash: transfer_txn_hash, + from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*BOB_ADDR), source: contract_purse, target: bob_attenuated_main_purse, amount: *TRANSFER_AMOUNT_2, - gas: U512::zero(), + gas: Gas::zero(), id: bob_id, }; let stored_expected_carol = Transfer { - deploy_hash: transfer_deploy_hash, - from: *DEFAULT_ACCOUNT_ADDR, + transaction_hash: transfer_txn_hash, + from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*CAROL_ADDR), source: contract_purse, target: carol_attenuated_main_purse, amount: *TRANSFER_AMOUNT_3, - gas: U512::zero(), + gas: Gas::zero(), id: carol_id, }; diff --git a/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs b/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs index d58dd72870..335d571082 100644 --- a/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs +++ b/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs @@ -6,9 +6,8 @@ use casper_engine_test_support::{ }; use casper_execution_engine::{engine_state::Error, execution}; use casper_types::{ - account::AccountHash, - package::{EntityVersion, ENTITY_INITIAL_VERSION}, - runtime_args, EntityVersionKey, EraId, PackageHash, ProtocolVersion, RuntimeArgs, U512, + account::AccountHash, runtime_args, EntityVersion, EntityVersionKey, EraId, PackageHash, + ProtocolVersion, RuntimeArgs, ENTITY_INITIAL_VERSION, U512, }; const ACCOUNT_1_ADDR: AccountHash = AccountHash::new([42u8; 32]); @@ -61,7 +60,7 @@ fn install_custom_payment( .into_package_hash() .expect("should be a hash"); - let exec_cost = builder.last_exec_result().cost().value(); + let exec_cost = builder.get_last_exec_result().unwrap().gas().value(); (default_account, package_hash, exec_cost) } @@ -77,7 +76,7 @@ fn should_exec_non_stored_code() { let transferred_amount = 1; let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code( format!("{}.wasm", TRANSFER_PURSE_TO_ACCOUNT_CONTRACT_NAME), @@ -93,7 +92,7 @@ fn should_exec_non_stored_code() { .with_deploy_hash([1; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let mut builder = LmdbWasmTestBuilder::default(); @@ -156,7 +155,7 @@ fn should_fail_if_calling_non_existent_entry_point() { // next make another deploy that attempts to use the stored payment logic // but passing the name for an entry point that does not exist. let exec_request_stored_payment = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code(format!("{}.wasm", DO_NOTHING_NAME), RuntimeArgs::default()) .with_stored_payment_hash( @@ -168,7 +167,7 @@ fn should_fail_if_calling_non_existent_entry_point() { .with_deploy_hash([1; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_stored_payment).commit(); @@ -213,7 +212,7 @@ fn should_exec_stored_code_by_hash() { { let transfer_using_stored_payment = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_payment_contract_by_hash( custom_payment_package_hash.value(), @@ -231,7 +230,7 @@ fn should_exec_stored_code_by_hash() { .with_deploy_hash([2; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(transfer_using_stored_payment).expect_failure(); @@ -259,7 +258,7 @@ fn should_not_transfer_above_balance_using_stored_payment_code_by_hash() { let exec_request_stored_payment = { let account_1_account_hash = ACCOUNT_1_ADDR; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code( format!("{}.wasm", TRANSFER_PURSE_TO_ACCOUNT_CONTRACT_NAME), @@ -277,7 +276,7 @@ fn should_not_transfer_above_balance_using_stored_payment_code_by_hash() { .with_deploy_hash([2; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder @@ -311,7 +310,7 @@ fn should_empty_account_using_stored_payment_code_by_hash() { { let exec_request_stored_payment = { let account_1_account_hash = ACCOUNT_1_ADDR; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code( format!("{}.wasm", TRANSFER_PURSE_TO_ACCOUNT_CONTRACT_NAME), @@ -329,7 +328,7 @@ fn should_empty_account_using_stored_payment_code_by_hash() { .with_deploy_hash([2; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_stored_payment).expect_failure(); @@ -358,7 +357,7 @@ fn should_exec_stored_code_by_named_hash() { { let exec_request_stored_payment = { let account_1_account_hash = ACCOUNT_1_ADDR; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code( format!("{}.wasm", TRANSFER_PURSE_TO_ACCOUNT_CONTRACT_NAME), @@ -376,7 +375,7 @@ fn should_exec_stored_code_by_named_hash() { .with_deploy_hash([2; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_stored_payment).expect_failure(); @@ -432,7 +431,7 @@ fn should_fail_payment_stored_at_named_key_with_incompatible_major_version() { // next make another deploy that USES stored payment logic let exec_request_stored_payment = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code(format!("{}.wasm", DO_NOTHING_NAME), RuntimeArgs::default()) .with_stored_payment_named_key( @@ -446,10 +445,7 @@ fn should_fail_payment_stored_at_named_key_with_incompatible_major_version() { .with_deploy_hash([2; 32]) .build(); - ExecuteRequestBuilder::new() - .push_deploy(deploy) - .with_protocol_version(new_protocol_version) - .build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_stored_payment).commit(); @@ -511,7 +507,7 @@ fn should_fail_payment_stored_at_hash_with_incompatible_major_version() { // next make another deploy that USES stored payment logic let exec_request_stored_payment = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code(format!("{}.wasm", DO_NOTHING_NAME), RuntimeArgs::default()) .with_stored_payment_hash( @@ -523,10 +519,7 @@ fn should_fail_payment_stored_at_hash_with_incompatible_major_version() { .with_deploy_hash([2; 32]) .build(); - ExecuteRequestBuilder::new() - .push_deploy(deploy) - .with_protocol_version(new_protocol_version) - .build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_stored_payment).commit(); @@ -606,7 +599,7 @@ fn should_fail_session_stored_at_named_key_with_incompatible_major_version() { // Call stored session code let exec_request_stored_payment = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_session_named_key( DO_NOTHING_CONTRACT_HASH_NAME, @@ -622,10 +615,7 @@ fn should_fail_session_stored_at_named_key_with_incompatible_major_version() { .with_deploy_hash([2; 32]) .build(); - ExecuteRequestBuilder::new() - .push_deploy(deploy) - .with_protocol_version(new_protocol_version) - .build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_stored_payment).commit(); @@ -688,7 +678,7 @@ fn should_fail_session_stored_at_named_key_with_missing_new_major_version() { // Call stored session code let exec_request_stored_payment = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( DO_NOTHING_CONTRACT_PACKAGE_HASH_NAME, @@ -706,10 +696,7 @@ fn should_fail_session_stored_at_named_key_with_missing_new_major_version() { .with_deploy_hash([2; 32]) .build(); - ExecuteRequestBuilder::new() - .push_deploy(deploy) - .with_protocol_version(new_protocol_version) - .build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_stored_payment).commit(); @@ -783,7 +770,7 @@ fn should_fail_session_stored_at_hash_with_incompatible_major_version() { .expect("standard_payment named key should be hash"); let exec_request_stored_payment = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_session_named_key( DO_NOTHING_CONTRACT_HASH_NAME, @@ -799,10 +786,7 @@ fn should_fail_session_stored_at_hash_with_incompatible_major_version() { .with_deploy_hash([2; 32]) .build(); - ExecuteRequestBuilder::new() - .push_deploy(deploy) - .with_protocol_version(new_protocol_version) - .build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_stored_payment).commit(); @@ -853,7 +837,6 @@ fn should_execute_stored_payment_and_session_code_with_new_major_version() { STORED_PAYMENT_CONTRACT_NAME, RuntimeArgs::default(), ) - .with_protocol_version(new_protocol_version) .build(); let exec_request_2 = ExecuteRequestBuilder::standard( @@ -861,7 +844,6 @@ fn should_execute_stored_payment_and_session_code_with_new_major_version() { &format!("{}_stored.wasm", DO_NOTHING_NAME), RuntimeArgs::default(), ) - .with_protocol_version(new_protocol_version) .build(); // store both contracts @@ -881,7 +863,7 @@ fn should_execute_stored_payment_and_session_code_with_new_major_version() { .expect("standard_payment named key should be hash"); let exec_request_stored_payment = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( DO_NOTHING_CONTRACT_PACKAGE_HASH_NAME, @@ -898,10 +880,7 @@ fn should_execute_stored_payment_and_session_code_with_new_major_version() { .with_deploy_hash([3; 32]) .build(); - ExecuteRequestBuilder::new() - .push_deploy(deploy) - .with_protocol_version(new_protocol_version) - .build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder diff --git a/execution_engine_testing/tests/src/test/explorer/faucet.rs b/execution_engine_testing/tests/src/test/explorer/faucet.rs index 08f7370772..5d1f527680 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet.rs @@ -845,15 +845,10 @@ fn should_allow_funding_by_an_authorized_account() { .expect_failure() .commit(); - let exec_results = builder + let exec_result = builder .get_last_exec_result() .expect("failed to get exec results"); - let exec_result = exec_results - .first() - .expect("an exec result must exist") - .clone(); - let error = exec_result.as_error().unwrap(); assert!( matches!( diff --git a/execution_engine_testing/tests/src/test/gas_counter.rs b/execution_engine_testing/tests/src/test/gas_counter.rs index 86068a00e7..1249606bf0 100644 --- a/execution_engine_testing/tests/src/test/gas_counter.rs +++ b/execution_engine_testing/tests/src/test/gas_counter.rs @@ -60,12 +60,10 @@ fn should_fail_to_overflow_gas_counter() { builder.exec(exec_request).commit(); - let responses = builder + let exec_result = builder .get_exec_result_owned(0) .expect("should have response"); - let response = responses.get(0).expect("should have first element"); - - let lhs = response.as_error().expect("should have error"); + let lhs = exec_result.as_error().expect("should have error"); assert_matches!( lhs, Error::WasmPreprocessing(PreprocessingError::OperationForbiddenByGasRules) diff --git a/execution_engine_testing/tests/src/test/groups.rs b/execution_engine_testing/tests/src/test/groups.rs index f96c33f992..6cab0ace47 100644 --- a/execution_engine_testing/tests/src/test/groups.rs +++ b/execution_engine_testing/tests/src/test/groups.rs @@ -1,3 +1,5 @@ +#![allow(deprecated)] + use assert_matches::assert_matches; use once_cell::sync::Lazy; @@ -7,7 +9,7 @@ use casper_engine_test_support::{ }; use casper_execution_engine::{engine_state::Error, execution}; use casper_types::{ - account::AccountHash, package::ENTITY_INITIAL_VERSION, runtime_args, Key, RuntimeArgs, U512, + account::AccountHash, runtime_args, Key, RuntimeArgs, ENTITY_INITIAL_VERSION, U512, }; use crate::{lmdb_fixture, wasm_utils}; @@ -139,7 +141,7 @@ fn should_not_call_restricted_session_from_wrong_account() { let exec_request_3 = { let args = runtime_args! {}; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(ACCOUNT_1_ADDR) .with_stored_versioned_contract_by_hash( package_hash.into_package_addr().expect("should be hash"), @@ -152,7 +154,7 @@ fn should_not_call_restricted_session_from_wrong_account() { .with_deploy_hash([3; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_3).commit(); @@ -167,9 +169,7 @@ fn should_not_call_restricted_session_from_wrong_account() { let response = builder .get_last_exec_result() .expect("should have last response"); - assert_eq!(response.len(), 1); - let exec_response = response.last().expect("should have response"); - let error = exec_response.as_error().expect("should have error"); + let error = response.as_error().expect("should have error"); assert_matches!(error, Error::Exec(execution::Error::InvalidContext)); } @@ -204,7 +204,7 @@ fn should_not_call_restricted_session_caller_from_wrong_account() { let args = runtime_args! { "package_hash" => *package_hash, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(ACCOUNT_1_ADDR) .with_stored_versioned_contract_by_hash( package_hash.into_package_addr().expect("should be hash"), @@ -217,7 +217,7 @@ fn should_not_call_restricted_session_caller_from_wrong_account() { .with_deploy_hash([3; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_3).commit(); @@ -232,9 +232,7 @@ fn should_not_call_restricted_session_caller_from_wrong_account() { let response = builder .get_last_exec_result() .expect("should have last response"); - assert_eq!(response.len(), 1); - let exec_response = response.last().expect("should have response"); - let error = exec_response.as_error().expect("should have error"); + let error = response.as_error().expect("should have error"); assert_matches!(error, Error::Exec(execution::Error::InvalidContext)); } @@ -263,7 +261,7 @@ fn should_call_group_restricted_contract() { let args = runtime_args! { PACKAGE_HASH_ARG => *package_hash, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, @@ -276,7 +274,7 @@ fn should_call_group_restricted_contract() { .with_deploy_hash([3; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_2).expect_success().commit(); @@ -322,7 +320,7 @@ fn should_not_call_group_restricted_contract_from_wrong_account() { let args = runtime_args! { PACKAGE_HASH_ARG => *package_hash, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(ACCOUNT_1_ADDR) .with_stored_versioned_contract_by_hash( package_hash.into_package_addr().expect("should be hash"), @@ -335,7 +333,7 @@ fn should_not_call_group_restricted_contract_from_wrong_account() { .with_deploy_hash([3; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_3).commit(); @@ -343,9 +341,7 @@ fn should_not_call_group_restricted_contract_from_wrong_account() { let response = builder .get_last_exec_result() .expect("should have last response"); - assert_eq!(response.len(), 1); - let exec_response = response.last().expect("should have response"); - let error = exec_response.as_error().expect("should have error"); + let error = response.as_error().expect("should have error"); assert_matches!(error, Error::Exec(execution::Error::InvalidContext)); } @@ -371,7 +367,7 @@ fn should_call_group_unrestricted_contract_caller() { let args = runtime_args! { PACKAGE_HASH_ARG => *package_hash, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, @@ -384,7 +380,7 @@ fn should_call_group_unrestricted_contract_caller() { .with_deploy_hash([3; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_2).expect_success().commit(); @@ -535,9 +531,7 @@ fn should_call_group_restricted_contract_as_session_from_wrong_account() { let response = builder .get_last_exec_result() .expect("should have last response"); - assert_eq!(response.len(), 1); - let exec_response = response.last().expect("should have response"); - let error = exec_response.as_error().expect("should have error"); + let error = response.as_error().expect("should have error"); assert_matches!(error, Error::Exec(execution::Error::InvalidContext)); } @@ -566,7 +560,7 @@ fn should_not_call_uncallable_contract_from_deploy() { let args = runtime_args! { PACKAGE_HASH_ARG => *package_hash, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, @@ -579,23 +573,21 @@ fn should_not_call_uncallable_contract_from_deploy() { .with_deploy_hash([3; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_2).commit(); let response = builder .get_last_exec_result() .expect("should have last response"); - assert_eq!(response.len(), 1); - let exec_response = response.last().expect("should have response"); - let error = exec_response.as_error().expect("should have error"); + let error = response.as_error().expect("should have error"); assert_matches!(error, Error::Exec(execution::Error::InvalidContext)); let exec_request_3 = { let args = runtime_args! { PACKAGE_HASH_ARG => *package_hash, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, @@ -608,7 +600,7 @@ fn should_not_call_uncallable_contract_from_deploy() { .with_deploy_hash([6; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_3).expect_failure(); @@ -641,7 +633,7 @@ fn should_not_call_uncallable_session_from_deploy() { let args = runtime_args! { PACKAGE_HASH_ARG => *package_hash, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, @@ -654,23 +646,21 @@ fn should_not_call_uncallable_session_from_deploy() { .with_deploy_hash([3; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_2).commit(); let response = builder .get_last_exec_result() .expect("should have last response"); - assert_eq!(response.len(), 1); - let exec_response = response.last().expect("should have response"); - let error = exec_response.as_error().expect("should have error"); + let error = response.as_error().expect("should have error"); assert_matches!(error, Error::Exec(execution::Error::InvalidContext)); let exec_request_3 = { let args = runtime_args! { PACKAGE_HASH_ARG => *package_hash, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, @@ -683,7 +673,7 @@ fn should_not_call_uncallable_session_from_deploy() { .with_deploy_hash([6; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_3).expect_failure(); @@ -723,7 +713,7 @@ fn should_not_call_group_restricted_stored_payment_code_from_invalid_account() { let args = runtime_args! { "amount" => *DEFAULT_PAYMENT, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(ACCOUNT_1_ADDR) .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) .with_stored_versioned_payment_contract_by_hash( @@ -738,7 +728,7 @@ fn should_not_call_group_restricted_stored_payment_code_from_invalid_account() { .with_deploy_hash([3; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_3).commit(); @@ -753,9 +743,7 @@ fn should_not_call_group_restricted_stored_payment_code_from_invalid_account() { let response = builder .get_last_exec_result() .expect("should have last response"); - assert_eq!(response.len(), 1); - let exec_response = response.last().expect("should have response"); - let error = exec_response.as_error().expect("should have error"); + let error = response.as_error().expect("should have error"); assert_matches!(error, Error::Exec(execution::Error::InvalidContext)); } @@ -793,7 +781,7 @@ fn should_call_group_restricted_stored_payment_code() { let args = runtime_args! { "amount" => *DEFAULT_PAYMENT, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) // .with_stored_versioned_contract_by_name(name, version, entry_point, args) @@ -809,7 +797,7 @@ fn should_call_group_restricted_stored_payment_code() { .with_deploy_hash([3; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_3).expect_failure(); diff --git a/execution_engine_testing/tests/src/test/mod.rs b/execution_engine_testing/tests/src/test/mod.rs index d30b47c94f..fca009baed 100644 --- a/execution_engine_testing/tests/src/test/mod.rs +++ b/execution_engine_testing/tests/src/test/mod.rs @@ -1,4 +1,3 @@ -mod bulk_update_with_scratch_trie; mod chainspec_registry; mod check_transfer_success; mod contract_api; diff --git a/execution_engine_testing/tests/src/test/private_chain/management.rs b/execution_engine_testing/tests/src/test/private_chain/management.rs index 1da14202df..7310266b18 100644 --- a/execution_engine_testing/tests/src/test/private_chain/management.rs +++ b/execution_engine_testing/tests/src/test/private_chain/management.rs @@ -235,7 +235,7 @@ fn genesis_accounts_should_not_remove_associated_keys() { let account_hash = *ACCOUNT_1_ADDR; let deploy_hash: [u8; 32] = [55; 32]; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(ADD_ASSOCIATED_KEY_CONTRACT, session_args) .with_empty_payment_bytes(runtime_args! { @@ -245,7 +245,7 @@ fn genesis_accounts_should_not_remove_associated_keys() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder @@ -311,7 +311,7 @@ fn administrator_account_should_disable_any_account() { let deploy_hash = [54; 32]; // Here, deploy is sent as an account, but signed by an administrator. - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_session_code(SET_ACTION_THRESHOLDS_CONTRACT, session_args) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) @@ -319,7 +319,7 @@ fn administrator_account_should_disable_any_account() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() } }; @@ -358,7 +358,7 @@ fn administrator_account_should_disable_any_account() { let deploy_hash = [53; 32]; // Here, deploy is sent as an account, but signed by an administrator. - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_session_code(SET_ACTION_THRESHOLDS_CONTRACT, session_args) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) @@ -366,7 +366,7 @@ fn administrator_account_should_disable_any_account() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let enable_request_2 = { @@ -379,7 +379,7 @@ fn administrator_account_should_disable_any_account() { let deploy_hash = [52; 32]; // Here, deploy is sent as an account, but signed by an administrator. - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_session_code(SET_ACTION_THRESHOLDS_CONTRACT, session_args) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) @@ -387,7 +387,7 @@ fn administrator_account_should_disable_any_account() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(enable_request_1).expect_success().commit(); @@ -717,7 +717,7 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { }; let session_args = RuntimeArgs::default(); - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) .with_stored_payment_named_key( @@ -728,7 +728,7 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { .with_authorization_keys(&[sender]) .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_1).expect_failure(); @@ -769,7 +769,7 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { let sender = *ACCOUNT_1_ADDR; let deploy_hash = [100; 32]; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args.clone()) .with_stored_payment_named_key( @@ -780,21 +780,21 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { .with_authorization_keys(&[sender]) .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let call_by_hash = { let sender = *ACCOUNT_1_ADDR; let deploy_hash = [100; 32]; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) .with_stored_payment_hash(stored_entity_hash, PAY_ENTRYPOINT, payment_args) .with_authorization_keys(&[sender]) .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; vec![call_by_name, call_by_hash] @@ -837,7 +837,7 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { let sender = *ACCOUNT_1_ADDR; let deploy_hash = [100; 32]; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args.clone()) .with_stored_payment_named_key( @@ -848,21 +848,21 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { .with_authorization_keys(&[sender]) .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let call_by_hash = { let sender = *ACCOUNT_1_ADDR; let deploy_hash = [100; 32]; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) .with_stored_payment_hash(stored_entity_hash, PAY_ENTRYPOINT, payment_args) .with_authorization_keys(&[sender]) .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; vec![call_by_name, call_by_hash] diff --git a/execution_engine_testing/tests/src/test/private_chain/unrestricted_transfers.rs b/execution_engine_testing/tests/src/test/private_chain/unrestricted_transfers.rs index 52e202fc58..b354d63dd1 100644 --- a/execution_engine_testing/tests/src/test/private_chain/unrestricted_transfers.rs +++ b/execution_engine_testing/tests/src/test/private_chain/unrestricted_transfers.rs @@ -472,7 +472,7 @@ fn should_not_allow_payment_to_purse_in_stored_payment() { let session_args = RuntimeArgs::default(); const PAY_ENTRYPOINT: &str = "pay"; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) .with_stored_payment_named_key( @@ -483,7 +483,7 @@ fn should_not_allow_payment_to_purse_in_stored_payment() { .with_authorization_keys(&[sender]) .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_1).expect_failure().commit(); @@ -728,14 +728,14 @@ fn should_allow_custom_payment_by_paying_to_system_account() { }; let session_args = RuntimeArgs::default(); - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) .with_payment_code("non_standard_payment.wasm", payment_args) .with_authorization_keys(&[sender]) .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_1).expect_success().commit(); @@ -774,14 +774,14 @@ fn should_allow_wasm_transfer_to_system() { "amount" => U512::one(), }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_session_code("transfer_to_account_u512.wasm", session_args) .with_payment_bytes(Vec::new(), payment_args) .with_authorization_keys(&[sender]) .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request_1).expect_success().commit(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1129.rs b/execution_engine_testing/tests/src/test/regression/ee_1129.rs index 212fc0a15d..0ef14e8943 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1129.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1129.rs @@ -75,7 +75,7 @@ fn should_run_ee_1129_underfunded_delegate_call() { auction::ARG_AMOUNT => bid_amount, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_session_hash(auction, auction::METHOD_DELEGATE, args) .with_empty_payment_bytes(runtime_args! { @@ -85,15 +85,13 @@ fn should_run_ee_1129_underfunded_delegate_call() { .with_deploy_hash(deploy_hash) .build(); - let exec_request = ExecuteRequestBuilder::new().push_deploy(deploy).build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build(); builder.exec(exec_request).commit(); let error = builder .get_last_exec_result() .expect("should have results") - .get(0) - .expect("should have first result") .as_error() .cloned() .expect("should have error"); @@ -139,7 +137,7 @@ fn should_run_ee_1129_underfunded_add_bid_call() { auction::ARG_DELEGATION_RATE => delegation_rate, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*VALIDATOR_1_ADDR) .with_stored_session_hash(auction, auction::METHOD_ADD_BID, args) .with_empty_payment_bytes(runtime_args! { @@ -149,15 +147,13 @@ fn should_run_ee_1129_underfunded_add_bid_call() { .with_deploy_hash(deploy_hash) .build(); - let exec_request = ExecuteRequestBuilder::new().push_deploy(deploy).build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build(); builder.exec(exec_request).commit(); let error = builder .get_last_exec_result() .expect("should have results") - .get(0) - .expect("should have first result") .as_error() .cloned() .expect("should have error"); @@ -184,7 +180,7 @@ fn should_run_ee_1129_underfunded_mint_contract_call() { .build(); let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_session_named_key(CONTRACT_KEY, ENTRY_POINT_NAME, RuntimeArgs::default()) .with_empty_payment_bytes(runtime_args! { @@ -194,7 +190,7 @@ fn should_run_ee_1129_underfunded_mint_contract_call() { .with_deploy_hash([42; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(install_exec_request).expect_success().commit(); @@ -204,8 +200,6 @@ fn should_run_ee_1129_underfunded_mint_contract_call() { let error = builder .get_last_exec_result() .expect("should have results") - .get(0) - .expect("should have first result") .as_error() .cloned() .expect("should have error"); @@ -232,7 +226,7 @@ fn should_not_panic_when_calling_session_contract_by_uref() { .build(); let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_session_named_key(ACCESS_KEY, ENTRY_POINT_NAME, RuntimeArgs::default()) .with_empty_payment_bytes(runtime_args! { @@ -242,7 +236,7 @@ fn should_not_panic_when_calling_session_contract_by_uref() { .with_deploy_hash([42; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(install_exec_request).expect_success().commit(); @@ -252,8 +246,6 @@ fn should_not_panic_when_calling_session_contract_by_uref() { let error = builder .get_last_exec_result() .expect("should have results") - .get(0) - .expect("should have first result") .as_error() .cloned() .expect("should have error"); @@ -280,7 +272,7 @@ fn should_not_panic_when_calling_payment_contract_by_uref() { .build(); let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::new()) .with_stored_payment_named_key(ACCESS_KEY, ENTRY_POINT_NAME, RuntimeArgs::new()) @@ -288,7 +280,7 @@ fn should_not_panic_when_calling_payment_contract_by_uref() { .with_deploy_hash([42; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(install_exec_request).expect_success().commit(); @@ -298,8 +290,6 @@ fn should_not_panic_when_calling_payment_contract_by_uref() { let error = builder .get_last_exec_result() .expect("should have results") - .get(0) - .expect("should have first result") .as_error() .cloned() .expect("should have error"); @@ -326,7 +316,7 @@ fn should_not_panic_when_calling_contract_package_by_uref() { .build(); let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( ACCESS_KEY, @@ -341,7 +331,7 @@ fn should_not_panic_when_calling_contract_package_by_uref() { .with_deploy_hash([42; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(install_exec_request).expect_success().commit(); @@ -351,8 +341,6 @@ fn should_not_panic_when_calling_contract_package_by_uref() { let error = builder .get_last_exec_result() .expect("should have results") - .get(0) - .expect("should have first result") .as_error() .cloned() .expect("should have error"); @@ -379,7 +367,7 @@ fn should_not_panic_when_calling_payment_versioned_contract_by_uref() { .build(); let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::new()) .with_stored_versioned_payment_contract_by_name( @@ -392,7 +380,7 @@ fn should_not_panic_when_calling_payment_versioned_contract_by_uref() { .with_deploy_hash([42; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(install_exec_request).expect_success().commit(); @@ -402,8 +390,6 @@ fn should_not_panic_when_calling_payment_versioned_contract_by_uref() { let error = builder .get_last_exec_result() .expect("should have results") - .get(0) - .expect("should have first result") .as_error() .cloned() .expect("should have error"); @@ -439,7 +425,7 @@ fn should_not_panic_when_calling_module_without_memory() { builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_bytes(do_nothing_without_memory(), RuntimeArgs::new()) .with_empty_payment_bytes(runtime_args! { @@ -449,7 +435,7 @@ fn should_not_panic_when_calling_module_without_memory() { .with_deploy_hash([42; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request).commit(); @@ -457,8 +443,6 @@ fn should_not_panic_when_calling_module_without_memory() { let error = builder .get_last_exec_result() .expect("should have results") - .get(0) - .expect("should have first result") .as_error() .cloned() .expect("should have error"); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1160.rs b/execution_engine_testing/tests/src/test/regression/ee_1160.rs index 15eb0c5d46..f40d8dba60 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1160.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1160.rs @@ -53,7 +53,6 @@ fn ee_1160_wasmless_transfer_should_empty_account() { .commit(); let last_result = builder.get_exec_result_owned(0).unwrap(); - let last_result = &last_result[0]; assert!(last_result.as_error().is_none(), "{:?}", last_result); assert!(!last_result.transfers().is_empty()); @@ -115,7 +114,6 @@ fn ee_1160_transfer_larger_than_balance_should_fail() { .expect("gas overflow"); let last_result = builder.get_exec_result_owned(0).unwrap(); - let last_result = &last_result[0]; assert_eq!( balance_before - wasmless_transfer_motes.value(), balance_after @@ -182,7 +180,6 @@ fn ee_1160_large_wasmless_transfer_should_avoid_overflow() { ); let last_result = builder.get_exec_result_owned(0).unwrap(); - let last_result = &last_result[0]; // TODO: reenable when new payment logic is added // assert_eq!(last_result.cost(), wasmless_transfer_gas_cost); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1163.rs b/execution_engine_testing/tests/src/test/regression/ee_1163.rs index f0cd0ab489..f4c56d8a4e 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1163.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1163.rs @@ -44,10 +44,7 @@ fn should_charge_for_user_error( let response = builder .get_exec_result_owned(0) - .expect("should have result") - .get(0) - .cloned() - .expect("should have first result"); + .expect("should have result"); // TODO: reenable when new payment logic is added // assert_eq!(response.cost(), transfer_cost); assert_eq!( diff --git a/execution_engine_testing/tests/src/test/regression/ee_1174.rs b/execution_engine_testing/tests/src/test/regression/ee_1174.rs index ccb0fe87d1..c34564f9fe 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1174.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1174.rs @@ -44,8 +44,6 @@ fn should_run_ee_1174_delegation_rate_too_high() { let error = builder .get_last_exec_result() .expect("should have results") - .get(0) - .expect("should have first result") .as_error() .cloned() .expect("should have error"); diff --git a/execution_engine_testing/tests/src/test/regression/ee_532.rs b/execution_engine_testing/tests/src/test/regression/ee_532.rs index 373aff0b04..485926a51a 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_532.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_532.rs @@ -26,10 +26,7 @@ fn should_run_ee_532_non_existent_account_regression_test() { let deploy_result = builder .get_exec_result_owned(0) - .expect("should have exec response") - .get(0) - .cloned() - .expect("should have at least one deploy result"); + .expect("should have exec response"); assert!( deploy_result.has_precondition_failure(), diff --git a/execution_engine_testing/tests/src/test/regression/ee_572.rs b/execution_engine_testing/tests/src/test/regression/ee_572.rs index 330fc14a64..975c86ab3d 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_572.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_572.rs @@ -1,5 +1,5 @@ use casper_engine_test_support::{ - utils, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_types::{account::AccountHash, runtime_args, Key, U512}; @@ -68,6 +68,7 @@ fn should_run_ee_572_regression() { .expect("Could not find contract pointer") }; + // Attempt to forge a new URef with escalated privileges let exec_request_4 = ExecuteRequestBuilder::standard( ACCOUNT_2_ADDR, CONTRACT_ESCALATE, @@ -78,12 +79,12 @@ fn should_run_ee_572_regression() { .build(); // Attempt to forge a new URef with escalated privileges - let response = builder + let _ = builder .exec(exec_request_4) .get_exec_result_owned(3) .expect("should have a response"); - let error_message = utils::get_error_message(response); + let error_message = builder.get_error_message().unwrap(); assert!( error_message.contains("ForgedReference"), diff --git a/execution_engine_testing/tests/src/test/regression/ee_597.rs b/execution_engine_testing/tests/src/test/regression/ee_597.rs index c454708352..7e79cd81b9 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_597.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_597.rs @@ -47,11 +47,7 @@ fn should_fail_when_bonding_amount_is_zero_ee_597_regression() { .exec(exec_request) .commit(); - let response = builder - .get_exec_result_owned(0) - .expect("should have a response"); - - let error_message = utils::get_error_message(response); + let error_message = builder.get_error_message().expect("should have a result"); // Error::BondTooSmall => 5, assert!( diff --git a/execution_engine_testing/tests/src/test/regression/ee_599.rs b/execution_engine_testing/tests/src/test/regression/ee_599.rs index 4b0dd4190a..b59bf33a55 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_599.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_599.rs @@ -87,7 +87,7 @@ fn should_not_be_able_to_transfer_funds_with_transfer_purse_to_purse() { let transaction_fee = builder.get_proposer_purse_balance() - proposer_reward_starting_balance; - let error_msg = builder.exec_error_message(0).expect("should have error"); + let error_msg = builder.get_error_message().expect("should have error"); assert!( error_msg.contains(EXPECTED_ERROR), "Got error: {}", @@ -147,7 +147,7 @@ fn should_not_be_able_to_transfer_funds_with_transfer_from_purse_to_account() { let transaction_fee = builder.get_proposer_purse_balance() - proposer_reward_starting_balance; - let error_msg = builder.exec_error_message(0).expect("should have error"); + let error_msg = builder.get_error_message().expect("should have error"); assert!( error_msg.contains(EXPECTED_ERROR), "Got error: {}", @@ -215,7 +215,7 @@ fn should_not_be_able_to_transfer_funds_with_transfer_to_account() { let transaction_fee = builder.get_proposer_purse_balance() - proposer_reward_starting_balance; - let error_msg = builder.exec_error_message(0).expect("should have error"); + let error_msg = builder.get_error_message().expect("should have error"); assert!( error_msg.contains(EXPECTED_ERROR), "Got error: {}", @@ -277,7 +277,7 @@ fn should_not_be_able_to_get_main_purse_in_invalid_builder() { let transaction_fee = builder.get_proposer_purse_balance() - proposer_reward_starting_balance; - let error_msg = builder.exec_error_message(0).expect("should have error"); + let error_msg = builder.get_error_message().expect("should have error"); assert!( error_msg.contains(EXPECTED_ERROR), "Got error: {}", diff --git a/execution_engine_testing/tests/src/test/regression/ee_601.rs b/execution_engine_testing/tests/src/test/regression/ee_601.rs index 9a0b7042a9..83544f4d7a 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_601.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_601.rs @@ -15,7 +15,7 @@ fn should_run_ee_601_pay_session_new_uref_collision() { let genesis_account_hash = *DEFAULT_ACCOUNT_ADDR; let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_deploy_hash([1; 32]) .with_address(*DEFAULT_ACCOUNT_ADDR) .with_payment_code( @@ -26,7 +26,7 @@ fn should_run_ee_601_pay_session_new_uref_collision() { .with_authorization_keys(&[genesis_account_hash]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let mut builder = LmdbWasmTestBuilder::default(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_771.rs b/execution_engine_testing/tests/src/test/regression/ee_771.rs index 9ee1e9850d..3bf979d842 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_771.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_771.rs @@ -22,11 +22,11 @@ fn should_run_ee_771_regression() { .exec(exec_request) .commit(); - let response = builder + let exec_result = builder .get_exec_result_owned(0) .expect("should have a response"); - let error = response[0].as_error().expect("should have error"); + let error = exec_result.as_error().expect("should have error"); assert_eq!( format!("{}", error), "Function not found: functiondoesnotexist" diff --git a/execution_engine_testing/tests/src/test/regression/ee_890.rs b/execution_engine_testing/tests/src/test/regression/ee_890.rs index 0d090a499f..ce94fdc64a 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_890.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_890.rs @@ -40,7 +40,7 @@ fn make_do_nothing_with_start() -> Vec { fn should_run_ee_890_gracefully_reject_start_node_in_session() { let wasm_binary = make_do_nothing_with_start(); - let deploy_1 = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_bytes(wasm_binary, RuntimeArgs::new()) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) @@ -48,14 +48,14 @@ fn should_run_ee_890_gracefully_reject_start_node_in_session() { .with_deploy_hash([123; 32]) .build(); - let exec_request_1 = ExecuteRequestBuilder::new().push_deploy(deploy_1).build(); + let exec_request_1 = ExecuteRequestBuilder::from_deploy_item(deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); builder .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) .exec(exec_request_1) .commit(); - let message = builder.exec_error_message(0).expect("should fail"); + let message = builder.get_error_message().expect("should fail"); assert!( message.contains("UnsupportedWasmStart"), "Error message {:?} does not contain expected pattern", @@ -68,7 +68,7 @@ fn should_run_ee_890_gracefully_reject_start_node_in_session() { fn should_run_ee_890_gracefully_reject_start_node_in_payment() { let wasm_binary = make_do_nothing_with_start(); - let deploy_1 = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code(DO_NOTHING_WASM, RuntimeArgs::new()) .with_payment_bytes(wasm_binary, RuntimeArgs::new()) @@ -76,14 +76,14 @@ fn should_run_ee_890_gracefully_reject_start_node_in_payment() { .with_deploy_hash([123; 32]) .build(); - let exec_request_1 = ExecuteRequestBuilder::new().push_deploy(deploy_1).build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); builder .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) - .exec(exec_request_1) + .exec(exec_request) .commit(); - let message = builder.exec_error_message(0).expect("should fail"); + let message = builder.get_error_message().expect("should fail"); assert!( message.contains("UnsupportedWasmStart"), "Error message {:?} does not contain expected pattern", diff --git a/execution_engine_testing/tests/src/test/regression/ee_966.rs b/execution_engine_testing/tests/src/test/regression/ee_966.rs index 064157afcc..dadd74cd4f 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_966.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_966.rs @@ -63,7 +63,7 @@ fn make_session_code_with_memory_pages(initial_pages: u32, max_pages: Option) -> ExecuteRequest { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_bytes(session_code, RuntimeArgs::new()) .with_empty_payment_bytes(runtime_args! { @@ -73,7 +73,7 @@ fn make_request_with_session_bytes(session_code: Vec) -> ExecuteRequest { .with_deploy_hash([42; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() } #[ignore] @@ -104,10 +104,10 @@ fn should_run_ee_966_cant_have_too_much_initial_memory() { builder.exec(exec_request).commit(); - let exec_response = &builder + let exec_result = &builder .get_exec_result_owned(0) - .expect("should have exec response")[0]; - let error = exec_response.as_error().expect("should have error"); + .expect("should have exec response"); + let error = exec_result.as_error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::Interpreter(_))); } @@ -156,10 +156,10 @@ fn should_run_ee_966_cant_have_too_much_max_memory() { builder.exec(exec_request).commit(); - let exec_response = &builder + let exec_result = &builder .get_exec_result_owned(0) - .expect("should have exec response")[0]; - let error = exec_response.as_error().expect("should have error"); + .expect("should have exec response"); + let error = exec_result.as_error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::Interpreter(_))); } @@ -179,10 +179,10 @@ fn should_run_ee_966_cant_have_way_too_much_max_memory() { builder.exec(exec_request).commit(); - let exec_response = &builder + let exec_result = &builder .get_exec_result_owned(0) - .expect("should have exec response")[0]; - let error = exec_response.as_error().expect("should have error"); + .expect("should have exec response"); + let error = exec_result.as_error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::Interpreter(_))); } @@ -200,10 +200,10 @@ fn should_run_ee_966_cant_have_larger_initial_than_max_memory() { builder.exec(exec_request).commit(); - let exec_response = &builder + let exec_result = &builder .get_exec_result_owned(0) - .expect("should have exec response")[0]; - let error = exec_response.as_error().expect("should have error"); + .expect("should have exec response"); + let error = exec_result.as_error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::Interpreter(_))); } @@ -223,10 +223,10 @@ fn should_run_ee_966_regression_fail_when_growing_mem_past_max() { builder.exec(exec_request).commit(); - let results = &builder + let exec_result = &builder .get_exec_result_owned(0) - .expect("should have exec response")[0]; - let error = results.as_error().expect("should have error"); + .expect("should have exec response"); + let error = exec_result.as_error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::Revert(ApiError::OutOfMemory))); } @@ -250,10 +250,10 @@ fn should_run_ee_966_regression_when_growing_mem_after_upgrade() { // This request should fail - as it's exceeding default memory limit // - let results = &builder + let exec_result = &builder .get_exec_result_owned(0) - .expect("should have exec response")[0]; - let error = results.as_error().expect("should have error"); + .expect("should have exec response"); + let error = exec_result.as_error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::Revert(ApiError::OutOfMemory))); // @@ -281,7 +281,6 @@ fn should_run_ee_966_regression_when_growing_mem_after_upgrade() { CONTRACT_EE_966_REGRESSION, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(exec_request_2).commit().expect_success(); diff --git a/execution_engine_testing/tests/src/test/regression/gh_1470.rs b/execution_engine_testing/tests/src/test/regression/gh_1470.rs index b87328015b..02b84de6e8 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1470.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1470.rs @@ -147,15 +147,10 @@ fn gh_1470_call_contract_should_verify_group_access() { builder.exec(call_contract_request).commit(); - let response = builder + let exec_result = builder .get_last_exec_result() .expect("should have last response"); - assert_eq!(response.len(), 1); - let exec_response = response.last().expect("should have response"); - let call_contract_error = exec_response - .as_error() - .cloned() - .expect("should have error"); + let call_contract_error = exec_result.as_error().cloned().expect("should have error"); let call_versioned_contract_request = { let args = runtime_args! { @@ -167,12 +162,10 @@ fn gh_1470_call_contract_should_verify_group_access() { builder.exec(call_versioned_contract_request).commit(); - let response = builder + let exec_result = builder .get_last_exec_result() .expect("should have last response"); - assert_eq!(response.len(), 1); - let exec_response = response.last().expect("should have response"); - let call_versioned_contract_error = exec_response.as_error().expect("should have error"); + let call_versioned_contract_error = exec_result.as_error().expect("should have error"); match (&call_contract_error, &call_versioned_contract_error) { ( @@ -484,15 +477,10 @@ fn gh_1470_call_contract_should_verify_wrong_argument_types() { builder.exec(call_contract_request).commit(); - let response = builder + let exec_result = builder .get_last_exec_result() .expect("should have last response"); - assert_eq!(response.len(), 1); - let exec_response = response.last().expect("should have response"); - let call_contract_error = exec_response - .as_error() - .cloned() - .expect("should have error"); + let call_contract_error = exec_result.as_error().cloned().expect("should have error"); let call_versioned_contract_request = { let args = runtime_args! { @@ -505,12 +493,10 @@ fn gh_1470_call_contract_should_verify_wrong_argument_types() { builder.exec(call_versioned_contract_request).commit(); - let response = builder + let exec_result = builder .get_last_exec_result() .expect("should have last response"); - assert_eq!(response.len(), 1); - let exec_response = response.last().expect("should have response"); - let call_versioned_contract_error = exec_response.as_error().expect("should have error"); + let call_versioned_contract_error = exec_result.as_error().expect("should have error"); let expected = gh_1470_regression::Arg1Type::cl_type(); let found = gh_1470_regression::Arg3Type::cl_type(); @@ -591,15 +577,10 @@ fn gh_1470_call_contract_should_verify_wrong_optional_argument_types() { builder.exec(call_contract_request).commit(); - let response = builder + let exec_result = builder .get_last_exec_result() .expect("should have last response"); - assert_eq!(response.len(), 1); - let exec_response = response.last().expect("should have response"); - let call_contract_error = exec_response - .as_error() - .cloned() - .expect("should have error"); + let call_contract_error = exec_result.as_error().cloned().expect("should have error"); let call_versioned_contract_request = { let args = runtime_args! { @@ -612,12 +593,10 @@ fn gh_1470_call_contract_should_verify_wrong_optional_argument_types() { builder.exec(call_versioned_contract_request).commit(); - let response = builder + let exec_result = builder .get_last_exec_result() .expect("should have last response"); - assert_eq!(response.len(), 1); - let exec_response = response.last().expect("should have response"); - let call_versioned_contract_error = exec_response.as_error().expect("should have error"); + let call_versioned_contract_error = exec_result.as_error().expect("should have error"); let expected = gh_1470_regression::Arg3Type::cl_type(); let found = gh_1470_regression::Arg4Type::cl_type(); @@ -684,9 +663,7 @@ fn should_transfer_after_major_version_bump_from_1_2_0() { mint::ARG_ID => Some(1u64), }; - let transfer = ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args) - .with_protocol_version(new_protocol_version) - .build(); + let transfer = ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args).build(); println!("About to execute"); @@ -729,9 +706,7 @@ fn should_transfer_after_minor_version_bump_from_1_2_0() { .upgrade_with_upgrade_request_and_config(None, &mut upgrade_request) .expect_upgrade_success(); - let transfer = ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args) - .with_protocol_version(new_protocol_version) - .build(); + let transfer = ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args).build(); builder.exec(transfer).expect_success().commit(); } @@ -771,7 +746,6 @@ fn should_add_bid_after_major_bump() { auction::ARG_DELEGATION_RATE => BID_DELEGATION_RATE, }, ) - .with_protocol_version(new_protocol_version) .build(); builder.exec(add_bid_request).expect_success().commit(); @@ -820,7 +794,6 @@ fn should_add_bid_after_minor_bump() { auction::ARG_DELEGATION_RATE => BID_DELEGATION_RATE, }, ) - .with_protocol_version(new_protocol_version) .build(); builder.exec(add_bid_request).expect_success().commit(); @@ -865,7 +838,6 @@ fn should_wasm_transfer_after_major_bump() { ARG_TARGET => AccountHash::new([1; 32]), }, ) - .with_protocol_version(new_protocol_version) .build(); builder.exec(wasm_transfer).expect_success().commit(); @@ -913,7 +885,6 @@ fn should_wasm_transfer_after_minor_bump() { ARG_TARGET => AccountHash::new([1; 32]), }, ) - .with_protocol_version(new_protocol_version) .build(); builder.exec(wasm_transfer).expect_success().commit(); diff --git a/execution_engine_testing/tests/src/test/regression/gh_1688.rs b/execution_engine_testing/tests/src/test/regression/gh_1688.rs index 8040483950..a388c6e9c6 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1688.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1688.rs @@ -90,7 +90,7 @@ fn test(request_builder: impl FnOnce(PackageHash, AddressableEntityHash) -> Exec #[test] fn should_run_gh_1688_regression_stored_versioned_contract_by_hash() { test(|contract_package_hash, _contract_hash| { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_hash( contract_package_hash.value(), @@ -102,7 +102,7 @@ fn should_run_gh_1688_regression_stored_versioned_contract_by_hash() { .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([42; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }); } @@ -110,7 +110,7 @@ fn should_run_gh_1688_regression_stored_versioned_contract_by_hash() { #[test] fn should_run_gh_1688_regression_stored_versioned_contract_by_name() { test(|_contract_package_hash, _contract_hash| { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_KEY, @@ -123,7 +123,7 @@ fn should_run_gh_1688_regression_stored_versioned_contract_by_name() { .with_deploy_hash([42; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }); } @@ -131,7 +131,7 @@ fn should_run_gh_1688_regression_stored_versioned_contract_by_name() { #[test] fn should_run_gh_1688_regression_stored_contract_by_hash() { test(|_contract_package_hash, contract_hash| { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_session_hash(contract_hash, METHOD_PUT_KEY, RuntimeArgs::default()) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) @@ -139,7 +139,7 @@ fn should_run_gh_1688_regression_stored_contract_by_hash() { .with_deploy_hash([42; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }); } @@ -147,7 +147,7 @@ fn should_run_gh_1688_regression_stored_contract_by_hash() { #[test] fn should_run_gh_1688_regression_stored_contract_by_name() { test(|_contract_package_hash, _contract_hash| { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_session_named_key( CONTRACT_HASH_KEY, @@ -159,6 +159,6 @@ fn should_run_gh_1688_regression_stored_contract_by_name() { .with_deploy_hash([42; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }); } diff --git a/execution_engine_testing/tests/src/test/regression/gh_1902.rs b/execution_engine_testing/tests/src/test/regression/gh_1902.rs index 229289d93a..ba03d3fd8c 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1902.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1902.rs @@ -103,7 +103,7 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { auction::ARG_DELEGATION_RATE => DELEGATION_RATE, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_hash(contract_hash, entry_point, session_args) .with_empty_payment_bytes(payment_args) @@ -111,7 +111,7 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { .with_deploy_hash([43; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; exec_and_assert_costs( @@ -141,7 +141,7 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { }; let deploy_hash = [55; 32]; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_hash(contract_hash, entry_point, session_args) .with_empty_payment_bytes(payment_args) @@ -149,7 +149,7 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; exec_and_assert_costs( @@ -179,7 +179,7 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { }; let deploy_hash = [56; 32]; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_hash(contract_hash, entry_point, session_args) .with_empty_payment_bytes(payment_args) @@ -187,7 +187,7 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; exec_and_assert_costs( @@ -215,7 +215,7 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { auction::ARG_AMOUNT => unbond_amount, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_hash(contract_hash, entry_point, session_args) .with_empty_payment_bytes(payment_args) @@ -223,7 +223,7 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { .with_deploy_hash([58; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; exec_and_assert_costs( diff --git a/execution_engine_testing/tests/src/test/regression/gh_2280.rs b/execution_engine_testing/tests/src/test/regression/gh_2280.rs index febcc02b31..1e17b0dd40 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_2280.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_2280.rs @@ -92,7 +92,7 @@ fn gh_2280_transfer_should_always_cost_the_same_gas() { ARG_AMOUNT => TOKEN_AMOUNT, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(session_file, faucet_args_2) // + default_create_purse_cost @@ -103,9 +103,8 @@ fn gh_2280_transfer_should_always_cost_the_same_gas() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy) - } - .build(); + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + }; builder.exec(fund_request_2).expect_success().commit(); let gas_cost_2 = builder.last_exec_gas_cost(); @@ -156,7 +155,7 @@ fn gh_2280_transfer_should_always_cost_the_same_gas() { ARG_AMOUNT => TOKEN_AMOUNT, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(session_file, faucet_args_3) .with_empty_payment_bytes(runtime_args! { @@ -166,10 +165,7 @@ fn gh_2280_transfer_should_always_cost_the_same_gas() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new() - .push_deploy(deploy) - .with_protocol_version(*NEW_PROTOCOL_VERSION) - .build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(fund_request_3).expect_success().commit(); @@ -214,7 +210,7 @@ fn gh_2280_create_purse_should_always_cost_the_same_gas() { ARG_PURSE_NAME => TEST_PURSE_NAME, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(session_file, create_purse_args_2) // + default_create_purse_cost @@ -225,9 +221,8 @@ fn gh_2280_create_purse_should_always_cost_the_same_gas() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy) - } - .build(); + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + }; builder.exec(fund_request_2).expect_success().commit(); let gas_cost_2 = builder.last_exec_gas_cost(); @@ -283,7 +278,7 @@ fn gh_2280_create_purse_should_always_cost_the_same_gas() { ARG_PURSE_NAME => TEST_PURSE_NAME, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(session_file, create_purse_args_3) .with_empty_payment_bytes(runtime_args! { @@ -293,10 +288,7 @@ fn gh_2280_create_purse_should_always_cost_the_same_gas() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new() - .push_deploy(deploy) - .with_protocol_version(*NEW_PROTOCOL_VERSION) - .build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(fund_request_3).expect_success().commit(); @@ -343,7 +335,7 @@ fn gh_2280_transfer_purse_to_account_should_always_cost_the_same_gas() { ARG_AMOUNT => U512::from(TOKEN_AMOUNT), }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(TRANSFER_PURSE_TO_ACCOUNT_CONTRACT, faucet_args_2) // + default_create_purse_cost @@ -354,9 +346,8 @@ fn gh_2280_transfer_purse_to_account_should_always_cost_the_same_gas() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy) - } - .build(); + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + }; builder.exec(fund_request_2).expect_success().commit(); let gas_cost_2 = builder.last_exec_gas_cost(); @@ -409,7 +400,7 @@ fn gh_2280_transfer_purse_to_account_should_always_cost_the_same_gas() { ARG_AMOUNT => U512::from(TOKEN_AMOUNT), }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(session_file, faucet_args_3) .with_empty_payment_bytes(runtime_args! { @@ -419,10 +410,7 @@ fn gh_2280_transfer_purse_to_account_should_always_cost_the_same_gas() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new() - .push_deploy(deploy) - .with_protocol_version(*NEW_PROTOCOL_VERSION) - .build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(fund_request_3).expect_success().commit(); @@ -472,7 +460,7 @@ fn gh_2280_stored_transfer_to_account_should_always_cost_the_same_gas() { ARG_TARGET => *ACCOUNT_2_ADDR, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_stored_session_hash(gh_2280_regression, entry_point, faucet_args_2) // + default_create_purse_cost @@ -483,9 +471,8 @@ fn gh_2280_stored_transfer_to_account_should_always_cost_the_same_gas() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy) - } - .build(); + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + }; builder.exec(fund_request_2).expect_success().commit(); let gas_cost_2 = builder.last_exec_gas_cost(); @@ -538,7 +525,7 @@ fn gh_2280_stored_transfer_to_account_should_always_cost_the_same_gas() { ARG_TARGET => *ACCOUNT_3_ADDR, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_stored_session_hash(gh_2280_regression, entry_point, faucet_args_3) .with_empty_payment_bytes(runtime_args! { @@ -548,10 +535,7 @@ fn gh_2280_stored_transfer_to_account_should_always_cost_the_same_gas() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new() - .push_deploy(deploy) - .with_protocol_version(*NEW_PROTOCOL_VERSION) - .build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(fund_request_3).expect_success().commit(); @@ -598,7 +582,7 @@ fn gh_2280_stored_faucet_call_should_cost_the_same() { ARG_TARGET => *ACCOUNT_2_ADDR, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(session_file, faucet_args_2) // + default_create_purse_cost @@ -609,9 +593,8 @@ fn gh_2280_stored_faucet_call_should_cost_the_same() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy) - } - .build(); + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + }; builder.exec(fund_request_2).expect_success().commit(); let gas_cost_2 = builder.last_exec_gas_cost(); @@ -665,7 +648,7 @@ fn gh_2280_stored_faucet_call_should_cost_the_same() { ARG_TARGET => *ACCOUNT_3_ADDR, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(session_file, faucet_args_3) .with_empty_payment_bytes(runtime_args! { @@ -675,10 +658,7 @@ fn gh_2280_stored_faucet_call_should_cost_the_same() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new() - .push_deploy(deploy) - .with_protocol_version(*NEW_PROTOCOL_VERSION) - .build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(fund_request_3).expect_success().commit(); diff --git a/execution_engine_testing/tests/src/test/regression/gh_3208.rs b/execution_engine_testing/tests/src/test/regression/gh_3208.rs index 52a08c84d7..af4db0c6da 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_3208.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_3208.rs @@ -204,7 +204,7 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule() auction::ARG_AMOUNT => *DEFAULT_PROPOSER_ACCOUNT_INITIAL_STAKE, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_hash(contract_hash, entry_point, session_args) .with_empty_payment_bytes(payment_args) @@ -212,7 +212,7 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule() .with_deploy_hash([58; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let withdraw_bid_request_2 = { @@ -225,7 +225,7 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule() auction::ARG_AMOUNT => *DEFAULT_PROPOSER_ACCOUNT_INITIAL_STAKE, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_hash(contract_hash, entry_point, session_args) .with_empty_payment_bytes(payment_args) @@ -233,7 +233,7 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule() .with_deploy_hash([59; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder @@ -344,7 +344,7 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule_a auction::ARG_AMOUNT => *DEFAULT_PROPOSER_ACCOUNT_INITIAL_STAKE, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_hash(contract_hash, entry_point, session_args) .with_empty_payment_bytes(payment_args) @@ -352,7 +352,7 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule_a .with_deploy_hash([58; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder diff --git a/execution_engine_testing/tests/src/test/regression/gov_42.rs b/execution_engine_testing/tests/src/test/regression/gov_42.rs index 17690c7344..915fe16da7 100644 --- a/execution_engine_testing/tests/src/test/regression/gov_42.rs +++ b/execution_engine_testing/tests/src/test/regression/gov_42.rs @@ -19,7 +19,6 @@ use casper_engine_test_support::{ }; use casper_execution_engine::engine_state::MAX_PAYMENT; use casper_types::{runtime_args, Gas, RuntimeArgs}; -use num_traits::Zero; use crate::{ test::regression::test_utils::{ @@ -62,14 +61,14 @@ fn run_test_case(input_wasm_bytes: &[u8], expected_error: &str, execution_phase: expected_error, ), }; - let deploy = deploy_item_builder + let deploy_item = deploy_item_builder .with_address(account_hash) .with_authorization_keys(&[account_hash]) .with_deploy_hash(deploy_hash) .build(); ( - ExecuteRequestBuilder::new().push_deploy(deploy), + ExecuteRequestBuilder::from_deploy_item(deploy_item), expected_error_message, ) }; diff --git a/execution_engine_testing/tests/src/test/regression/gov_74.rs b/execution_engine_testing/tests/src/test/regression/gov_74.rs index b33d3418ca..2613aac5c5 100644 --- a/execution_engine_testing/tests/src/test/regression/gov_74.rs +++ b/execution_engine_testing/tests/src/test/regression/gov_74.rs @@ -131,7 +131,6 @@ fn should_observe_stack_height_limit() { module_bytes, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build() }; @@ -155,7 +154,6 @@ fn should_observe_stack_height_limit() { module_bytes, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build() }; diff --git a/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs b/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs index defbd24e3b..b2589c86d7 100644 --- a/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs +++ b/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs @@ -49,7 +49,7 @@ const TRANSFER_FROM_MAIN_PURSE_AMOUNT: u64 = 2_000_000_u64; #[ignore] #[test] fn host_function_metrics_has_acceptable_size() { - let size = utils::read_wasm_file_bytes(CONTRACT_HOST_FUNCTION_METRICS).len(); + let size = utils::read_wasm_file(CONTRACT_HOST_FUNCTION_METRICS).len(); assert!( size <= HOST_FUNCTION_METRICS_MAX_SIZE, "Performance regression: contract host-function-metrics became {} bytes long; up to {} bytes long would be acceptable.", diff --git a/execution_engine_testing/tests/src/test/regression/regression_20210707.rs b/execution_engine_testing/tests/src/test/regression/regression_20210707.rs index d89de1095e..4bf5c6dce9 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20210707.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20210707.rs @@ -393,7 +393,7 @@ fn should_not_refund_to_bob_and_charge_alice() { ARG_SOURCE => bob_main_purse, ARG_AMOUNT => *DEFAULT_PAYMENT, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) // Just do nothing if ever we'd get into session execution .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) @@ -402,7 +402,7 @@ fn should_not_refund_to_bob_and_charge_alice() { .with_deploy_hash([77; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(call_request).commit(); @@ -451,7 +451,7 @@ fn should_not_charge_alice_for_execution() { ARG_SOURCE => bob_main_purse, ARG_AMOUNT => *DEFAULT_PAYMENT, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) // Just do nothing if ever we'd get into session execution .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) @@ -460,7 +460,7 @@ fn should_not_charge_alice_for_execution() { .with_deploy_hash([77; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(call_request).commit(); @@ -505,7 +505,7 @@ fn should_not_charge_for_execution_from_hardcoded_purse() { let args = runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) // Just do nothing if ever we'd get into session execution .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) @@ -514,7 +514,7 @@ fn should_not_charge_for_execution_from_hardcoded_purse() { .with_deploy_hash([77; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(call_request).commit(); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20210924.rs b/execution_engine_testing/tests/src/test/regression/regression_20210924.rs index 8e90e4d358..5eb0f509cb 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20210924.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20210924.rs @@ -1,5 +1,3 @@ -use num_traits::Zero; - use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, PRODUCTION_RUN_GENESIS_REQUEST, @@ -21,7 +19,7 @@ fn should_charge_minimum_for_do_nothing_session() { let session_args = RuntimeArgs::default(); let deploy_hash = [42; 32]; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_bytes(wasm_utils::do_nothing_bytes(), session_args) .with_empty_payment_bytes(runtime_args! { @@ -31,9 +29,8 @@ fn should_charge_minimum_for_do_nothing_session() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy) - } - .build(); + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + }; let mut builder = LmdbWasmTestBuilder::default(); @@ -79,7 +76,7 @@ fn should_execute_do_minimum_session() { let session_args = RuntimeArgs::default(); let deploy_hash = [42; 32]; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) .with_empty_payment_bytes(runtime_args! { @@ -89,9 +86,8 @@ fn should_execute_do_minimum_session() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy) - } - .build(); + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + }; let mut builder = LmdbWasmTestBuilder::default(); @@ -133,7 +129,7 @@ fn should_charge_minimum_for_do_nothing_payment() { let session_args = RuntimeArgs::default(); let deploy_hash = [42; 32]; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_bytes(wasm_utils::do_nothing_bytes(), session_args) .with_payment_bytes( @@ -146,9 +142,8 @@ fn should_charge_minimum_for_do_nothing_payment() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy) - } - .build(); + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + }; let mut builder = LmdbWasmTestBuilder::default(); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220221.rs b/execution_engine_testing/tests/src/test/regression/regression_20220221.rs index 2e9b8f3d2a..1c018d2199 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220221.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220221.rs @@ -87,7 +87,6 @@ fn regression_20220221_should_distribute_to_many_validators() { mint::ARG_ID => >::None, }, ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(transfer_request).commit().expect_success(); @@ -106,7 +105,6 @@ fn regression_20220221_should_distribute_to_many_validators() { auction::METHOD_ADD_BID, session_args, ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(execute_request).expect_success().commit(); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220224.rs b/execution_engine_testing/tests/src/test/regression/regression_20220224.rs index 13068ad5fa..3b95c1e358 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220224.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220224.rs @@ -22,7 +22,7 @@ fn should_not_transfer_above_approved_limit_in_payment_code() { }; let session_args = RuntimeArgs::default(); - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(CONTRACT_REVERT, session_args) .with_payment_code(CONTRACT_REGRESSION_PAYMENT, payment_args) @@ -30,7 +30,7 @@ fn should_not_transfer_above_approved_limit_in_payment_code() { .with_deploy_hash(deploy_hash) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(exec_request).expect_failure().commit(); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220303.rs b/execution_engine_testing/tests/src/test/regression/regression_20220303.rs index 1cb17524a1..06ceb980a4 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220303.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220303.rs @@ -12,7 +12,7 @@ use casper_types::{ }; use rand::Rng; -use crate::lmdb_fixture::{self, CONTRACT_REGISTRY_SPECIAL_ADDRESS}; +use crate::lmdb_fixture::{self, ENTRY_REGISTRY_SPECIAL_ADDRESS}; const DEFAULT_ACTIVATION_POINT: EraId = EraId::new(1); @@ -45,8 +45,8 @@ fn test_upgrade(major_bump: u32, minor_bump: u32, patch_bump: u32, upgrade_entri lmdb_fixture::builder_from_global_state_fixture(lmdb_fixture::RELEASE_1_3_1); let mint_contract_hash = { let stored_value: StoredValue = builder - .query(None, CONTRACT_REGISTRY_SPECIAL_ADDRESS, &[]) - .expect("should query system contract registry"); + .query(None, ENTRY_REGISTRY_SPECIAL_ADDRESS, &[]) + .expect("should query system entity registry"); let cl_value = stored_value .as_cl_value() .cloned() diff --git a/execution_engine_testing/tests/src/test/regression/transforms_must_be_ordered.rs b/execution_engine_testing/tests/src/test/regression/transforms_must_be_ordered.rs index 67249a0716..c7dfdb01eb 100644 --- a/execution_engine_testing/tests/src/test/regression/transforms_must_be_ordered.rs +++ b/execution_engine_testing/tests/src/test/regression/transforms_must_be_ordered.rs @@ -88,8 +88,7 @@ fn contract_transforms_should_be_ordered_in_the_effects() { .commit(); let exec_result = builder.get_exec_result_owned(1).unwrap(); - assert_eq!(exec_result.len(), 1); - let effects = exec_result[0].effects(); + let effects = exec_result.effects(); let contract = builder .get_entity_with_named_keys_by_entity_hash(contract_hash) diff --git a/execution_engine_testing/tests/src/test/storage_costs.rs b/execution_engine_testing/tests/src/test/storage_costs.rs index e6f31ad799..b78e70a739 100644 --- a/execution_engine_testing/tests/src/test/storage_costs.rs +++ b/execution_engine_testing/tests/src/test/storage_costs.rs @@ -144,7 +144,6 @@ fn should_verify_isolate_host_side_payment_code_is_free() { DO_NOTHING_WASM, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); let account = builder @@ -182,7 +181,6 @@ fn should_verify_isolated_auction_storage_is_free() { SYSTEM_CONTRACT_HASHES_NAME, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(exec_request).expect_success().commit(); @@ -208,7 +206,6 @@ fn should_verify_isolated_auction_storage_is_free() { auction::ARG_DELEGATION_RATE => DELEGATION_RATE, }, ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); let balance_before = builder.get_purse_balance(account.main_purse()); @@ -247,7 +244,6 @@ fn should_measure_gas_cost_for_storage_usage_write() { STORAGE_COSTS_NAME, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(install_exec_request).expect_success().commit(); @@ -278,7 +274,6 @@ fn should_measure_gas_cost_for_storage_usage_write() { WRITE_FUNCTION_SMALL_NAME, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder_a @@ -319,7 +314,6 @@ fn should_measure_gas_cost_for_storage_usage_write() { WRITE_FUNCTION_LARGE_NAME, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder_b @@ -469,7 +463,6 @@ fn should_measure_gas_cost_for_storage_usage_add() { STORAGE_COSTS_NAME, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(install_exec_request).expect_success().commit(); @@ -500,7 +493,6 @@ fn should_measure_gas_cost_for_storage_usage_add() { ADD_FUNCTION_SMALL_NAME, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder_a @@ -541,7 +533,6 @@ fn should_measure_gas_cost_for_storage_usage_add() { ADD_FUNCTION_LARGE_NAME, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder_b @@ -693,7 +684,6 @@ fn should_verify_new_uref_is_charging_for_storage() { STORAGE_COSTS_NAME, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(install_exec_request).expect_success().commit(); @@ -717,7 +707,6 @@ fn should_verify_new_uref_is_charging_for_storage() { NEW_UREF_FUNCTION, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(exec_request).expect_success().commit(); @@ -737,7 +726,6 @@ fn should_verify_put_key_is_charging_for_storage() { STORAGE_COSTS_NAME, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(install_exec_request).expect_success().commit(); @@ -761,7 +749,6 @@ fn should_verify_put_key_is_charging_for_storage() { PUT_KEY_FUNCTION, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(exec_request).expect_success().commit(); @@ -781,7 +768,6 @@ fn should_verify_remove_key_is_charging_for_storage() { STORAGE_COSTS_NAME, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(install_exec_request).expect_success().commit(); @@ -805,7 +791,6 @@ fn should_verify_remove_key_is_charging_for_storage() { REMOVE_KEY_FUNCTION, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(exec_request).expect_success().commit(); @@ -825,7 +810,6 @@ fn should_verify_create_contract_at_hash_is_charging_for_storage() { STORAGE_COSTS_NAME, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(install_exec_request).expect_success().commit(); @@ -849,7 +833,6 @@ fn should_verify_create_contract_at_hash_is_charging_for_storage() { CREATE_CONTRACT_PACKAGE_AT_HASH_FUNCTION, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(exec_request).expect_success().commit(); @@ -869,7 +852,6 @@ fn should_verify_create_contract_user_group_is_charging_for_storage() { STORAGE_COSTS_NAME, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(install_exec_request).expect_success().commit(); @@ -893,7 +875,6 @@ fn should_verify_create_contract_user_group_is_charging_for_storage() { CREATE_CONTRACT_USER_GROUP_FUNCTION_FUNCTION, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(exec_request).expect_success().commit(); @@ -910,7 +891,6 @@ fn should_verify_create_contract_user_group_is_charging_for_storage() { PROVISION_UREFS_FUNCTION, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(exec_request).expect_success().commit(); @@ -927,7 +907,6 @@ fn should_verify_create_contract_user_group_is_charging_for_storage() { REMOVE_CONTRACT_USER_GROUP_FUNCTION, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(exec_request).expect_success().commit(); @@ -947,7 +926,6 @@ fn should_verify_subcall_new_uref_is_charging_for_storage() { STORAGE_COSTS_NAME, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(install_exec_request).expect_success().commit(); diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs b/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs index 0e9de35c0f..8d960cf2d9 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs @@ -837,16 +837,12 @@ fn should_release_founder_stake() { builder.exec(full_unbond).commit(); - let error = { - let response = builder - .get_last_exec_result() - .expect("should have last exec result"); - let exec_response = response.last().expect("should have response"); - exec_response - .as_error() - .cloned() - .expect("should have error") - }; + let error = builder + .get_last_exec_result() + .expect("should have last exec result") + .as_error() + .cloned() + .expect("should have error"); assert_matches!( error, engine_state::Error::Exec(execution::Error::Revert(ApiError::AuctionError(15))) @@ -2360,16 +2356,12 @@ fn should_not_partially_undelegate_uninitialized_vesting_schedule() { .build(); builder.exec(partial_undelegate).commit(); - let error = { - let response = builder - .get_last_exec_result() - .expect("should have last exec result"); - let exec_response = response.last().expect("should have response"); - exec_response - .as_error() - .cloned() - .expect("should have error") - }; + let error = builder + .get_last_exec_result() + .expect("should have last exec result") + .as_error() + .cloned() + .expect("should have error"); assert!(matches!( error, @@ -2434,16 +2426,12 @@ fn should_not_fully_undelegate_uninitialized_vesting_schedule() { .build(); builder.exec(full_undelegate).commit(); - let error = { - let response = builder - .get_last_exec_result() - .expect("should have last exec result"); - let exec_response = response.last().expect("should have response"); - exec_response - .as_error() - .cloned() - .expect("should have error") - }; + let error = builder + .get_last_exec_result() + .expect("should have last exec result") + .as_error() + .cloned() + .expect("should have error"); assert!(matches!( error, @@ -2566,16 +2554,12 @@ fn should_not_undelegate_vfta_holder_stake() { ) .build(); builder.exec(partial_unbond).commit(); - let error = { - let response = builder - .get_last_exec_result() - .expect("should have last exec result"); - let exec_response = response.last().expect("should have response"); - exec_response - .as_error() - .cloned() - .expect("should have error") - }; + let error = builder + .get_last_exec_result() + .expect("should have last exec result") + .as_error() + .cloned() + .expect("should have error"); assert!(matches!( error, @@ -2632,16 +2616,12 @@ fn should_release_vfta_holder_stake() { builder.exec(full_undelegate).commit(); - let error = { - let response = builder - .get_last_exec_result() - .expect("should have last exec result"); - let exec_response = response.last().expect("should have response"); - exec_response - .as_error() - .cloned() - .expect("should have error") - }; + let error = builder + .get_last_exec_result() + .expect("should have last exec result") + .as_error() + .cloned() + .expect("should have error"); assert!( matches!( diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs b/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs index f5b8bebc27..bc82ad009d 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs @@ -281,18 +281,18 @@ fn should_fail_bonding_with_insufficient_funds() { builder.exec(exec_request_2).commit(); - let response = builder + let exec_result = builder .get_exec_result_owned(1) - .expect("should have a response"); - - assert_eq!(response.len(), 1); - let exec_result = response[0].as_error().expect("should have error"); + .expect("should have a response") + .as_error() + .cloned() + .expect("should have error"); assert!( matches!( exec_result, EngineError::Exec(Error::Revert(ApiError::Mint(mint_error)) ) - if *mint_error == mint::Error::InsufficientFunds as u8), + if mint_error == mint::Error::InsufficientFunds as u8), "{:?}", exec_result ); @@ -339,11 +339,7 @@ fn should_fail_unbonding_validator_with_locked_funds() { builder.exec(exec_request_2).commit(); - let response = builder - .get_exec_result_owned(0) - .expect("should have a response"); - - let error_message = utils::get_error_message(response); + let error_message = builder.get_error_message().expect("should have a result"); // handle_payment::Error::NotBonded => 0 assert!( @@ -375,11 +371,7 @@ fn should_fail_unbonding_validator_without_bonding_first() { builder.exec(exec_request).commit(); - let response = builder - .get_exec_result_owned(0) - .expect("should have a response"); - - let error_message = utils::get_error_message(response); + let error_message = builder.get_error_message().expect("should have a result"); assert!( error_message.contains(&format!( @@ -591,7 +583,6 @@ fn should_run_successful_unbond_funds_after_changing_unbonding_delay() { "amount" => U512::from(TRANSFER_AMOUNT) }, ) - .with_protocol_version(new_protocol_version) .build(); builder.exec(exec_request).expect_success().commit(); @@ -609,7 +600,6 @@ fn should_run_successful_unbond_funds_after_changing_unbonding_delay() { ARG_DELEGATION_RATE => DELEGATION_RATE, }, ) - .with_protocol_version(new_protocol_version) .build(); builder.exec(exec_request_1).expect_success().commit(); @@ -646,7 +636,6 @@ fn should_run_successful_unbond_funds_after_changing_unbonding_delay() { ARG_PUBLIC_KEY => default_public_key_arg.clone(), }, ) - .with_protocol_version(new_protocol_version) .build(); builder.exec(exec_request_2).expect_success().commit(); diff --git a/execution_engine_testing/tests/src/test/system_contracts/genesis.rs b/execution_engine_testing/tests/src/test/system_contracts/genesis.rs index 3776e4c698..b3d80d3554 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/genesis.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/genesis.rs @@ -7,11 +7,12 @@ use casper_engine_test_support::{ DEFAULT_ROUND_SEIGNIORAGE_RATE, DEFAULT_SYSTEM_CONFIG, DEFAULT_UNBONDING_DELAY, DEFAULT_VALIDATOR_SLOTS, DEFAULT_WASM_CONFIG, }; +use casper_execution_engine::engine_state::engine_config::DEFAULT_FEE_HANDLING; use casper_storage::data_access_layer::GenesisRequest; use casper_types::{ account::AccountHash, addressable_entity::EntityKindTag, system::auction::DelegationRate, GenesisAccount, GenesisConfigBuilder, GenesisValidator, Key, Motes, ProtocolVersion, PublicKey, - SecretKey, StoredValue, DEFAULT_FEE_HANDLING, DEFAULT_REFUND_HANDLING, U512, + SecretKey, StoredValue, DEFAULT_REFUND_HANDLING, U512, }; const GENESIS_CONFIG_HASH: [u8; 32] = [127; 32]; diff --git a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/finalize_payment.rs b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/finalize_payment.rs index ba3ca5cd22..0c20174450 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/finalize_payment.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/finalize_payment.rs @@ -128,7 +128,7 @@ fn finalize_payment_should_refund_to_specified_purse() { let exec_request = { let genesis_account_hash = *DEFAULT_ACCOUNT_ADDR; - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_session_code("do_nothing.wasm", RuntimeArgs::default()) @@ -136,7 +136,7 @@ fn finalize_payment_should_refund_to_specified_purse() { .with_authorization_keys(&[genesis_account_hash]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let proposer_reward_starting_balance = builder.get_proposer_purse_balance(); diff --git a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/refund_purse.rs b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/refund_purse.rs index a1b6844725..130a0570e3 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/refund_purse.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/refund_purse.rs @@ -90,7 +90,7 @@ fn refund_tests(builder: &mut LmdbWasmTestBuilder, account_hash: AccountHash) { .commit(); let refund_purse_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_deploy_hash([2; 32]) .with_session_code("do_nothing.wasm", RuntimeArgs::default()) @@ -106,7 +106,7 @@ fn refund_tests(builder: &mut LmdbWasmTestBuilder, account_hash: AccountHash) { .with_authorization_keys(&[account_hash]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder.exec(refund_purse_request).expect_success().commit(); diff --git a/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs b/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs index b40ade6082..4881bc6721 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use assert_matches::assert_matches; use casper_engine_test_support::{ - utils, DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, + DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_ACCOUNT_KEY, DEFAULT_GAS_PRICE, DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, }; @@ -50,14 +50,12 @@ fn should_raise_insufficient_payment_when_caller_lacks_minimum_balance() { ExecuteRequestBuilder::standard(ACCOUNT_1_ADDR, REVERT_WASM, RuntimeArgs::default()) .build(); - let account_1_response = builder + let error_message = builder .exec(account_1_request) .commit() - .get_exec_result_owned(1) + .get_error_message() .expect("there should be a response"); - let error_message = utils::get_error_message(account_1_response); - assert!( error_message.contains("InsufficientPayment"), "expected insufficient payment, got: {}", @@ -81,7 +79,7 @@ fn should_forward_payment_execution_runtime_error() { let transferred_amount = U512::from(1); let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_payment_code(REVERT_WASM, RuntimeArgs::default()) @@ -92,7 +90,7 @@ fn should_forward_payment_execution_runtime_error() { .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let mut builder = LmdbWasmTestBuilder::default(); @@ -131,12 +129,11 @@ fn should_forward_payment_execution_runtime_error() { "no net resources should be gained or lost post-distribution" ); - let response = builder + let exec_result = builder .get_exec_result_owned(0) .expect("there should be a response"); - let execution_result = utils::get_success_result(&response); - let error = execution_result.as_error().expect("should have error"); + let error = exec_result.as_error().expect("should have error"); assert_matches!( error, Error::Exec(execution::Error::Revert(ApiError::User(100))) @@ -154,7 +151,7 @@ fn should_forward_payment_execution_gas_limit_error() { builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_payment_code(ENDLESS_LOOP_WASM, RuntimeArgs::default()) @@ -165,7 +162,7 @@ fn should_forward_payment_execution_gas_limit_error() { .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let proposer_reward_starting_balance = builder.get_proposer_purse_balance(); @@ -200,17 +197,16 @@ fn should_forward_payment_execution_gas_limit_error() { "no net resources should be gained or lost post-distribution" ); - let response = builder + let exec_result = builder .get_exec_result_owned(0) .expect("there should be a response"); - let execution_result = utils::get_success_result(&response); - let error = execution_result.as_error().expect("should have error"); + let error = exec_result.as_error().expect("should have error"); assert_matches!(error, Error::Exec(execution::Error::GasLimit)); let payment_gas_limit = Gas::from_motes(Motes::new(*MAX_PAYMENT), DEFAULT_GAS_PRICE) .expect("should convert to gas"); assert_eq!( - execution_result.cost(), + exec_result.gas(), payment_gas_limit, "cost should equal gas limit" ); @@ -224,7 +220,7 @@ fn should_run_out_of_gas_when_session_code_exceeds_gas_limit() { let transferred_amount = 1; let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) @@ -235,7 +231,7 @@ fn should_run_out_of_gas_when_session_code_exceeds_gas_limit() { .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let mut builder = LmdbWasmTestBuilder::default(); @@ -245,17 +241,16 @@ fn should_run_out_of_gas_when_session_code_exceeds_gas_limit() { .exec(exec_request) .commit(); - let response = builder + let exec_result = builder .get_exec_result_owned(0) .expect("there should be a response"); - let execution_result = utils::get_success_result(&response); - let error = execution_result.as_error().expect("should have error"); + let error = exec_result.as_error().expect("should have error"); assert_matches!(error, Error::Exec(execution::Error::GasLimit)); let session_gas_limit = Gas::from_motes(Motes::new(payment_purse_amount), DEFAULT_GAS_PRICE) .expect("should convert to gas"); assert_eq!( - execution_result.cost(), + exec_result.gas(), session_gas_limit, "cost should equal gas limit" ); @@ -267,7 +262,7 @@ fn should_correctly_charge_when_session_code_runs_out_of_gas() { let payment_purse_amount = *DEFAULT_PAYMENT; let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) @@ -275,7 +270,7 @@ fn should_correctly_charge_when_session_code_runs_out_of_gas() { .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let mut builder = LmdbWasmTestBuilder::default(); @@ -296,12 +291,11 @@ fn should_correctly_charge_when_session_code_runs_out_of_gas() { "balance should be less than initial balance" ); - let response = builder + let exec_result = builder .get_exec_result_owned(0) .expect("there should be a response"); - let success_result = utils::get_success_result(&response); - let gas = success_result.cost(); + let gas = exec_result.gas(); let motes = Motes::from_gas(gas, DEFAULT_GAS_PRICE).expect("should have motes"); let tally = motes.value() + modified_balance; @@ -311,13 +305,12 @@ fn should_correctly_charge_when_session_code_runs_out_of_gas() { "no net resources should be gained or lost post-distribution" ); - let execution_result = utils::get_success_result(&response); - let error = execution_result.as_error().expect("should have error"); + let error = exec_result.as_error().expect("should have error"); assert_matches!(error, Error::Exec(execution::Error::GasLimit)); let session_gas_limit = Gas::from_motes(Motes::new(payment_purse_amount), DEFAULT_GAS_PRICE) .expect("should convert to gas"); assert_eq!( - execution_result.cost(), + exec_result.gas(), session_gas_limit, "cost should equal gas limit" ); @@ -331,7 +324,7 @@ fn should_correctly_charge_when_session_code_fails() { let transferred_amount = 1; let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) @@ -342,7 +335,7 @@ fn should_correctly_charge_when_session_code_fails() { .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let mut builder = LmdbWasmTestBuilder::default(); @@ -381,7 +374,7 @@ fn should_correctly_charge_when_session_code_succeeds() { let transferred_amount = 1; let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_session_code( @@ -392,7 +385,7 @@ fn should_correctly_charge_when_session_code_succeeds() { .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let mut builder = LmdbWasmTestBuilder::default(); @@ -438,7 +431,7 @@ fn should_finalize_to_rewards_purse() { let transferred_amount = 1; let exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code( TRANSFER_PURSE_TO_ACCOUNT_WASM, @@ -449,7 +442,7 @@ fn should_finalize_to_rewards_purse() { .with_deploy_hash([1; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let mut builder = LmdbWasmTestBuilder::default(); @@ -478,7 +471,7 @@ fn independent_standard_payments_should_not_write_the_same_keys() { let mut builder = LmdbWasmTestBuilder::default(); let setup_exec_request = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code( TRANSFER_PURSE_TO_ACCOUNT_WASM, @@ -489,7 +482,7 @@ fn independent_standard_payments_should_not_write_the_same_keys() { .with_deploy_hash([1; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; // create another account via transfer @@ -500,7 +493,7 @@ fn independent_standard_payments_should_not_write_the_same_keys() { .commit(); let exec_request_from_genesis = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code(DO_NOTHING_WASM, RuntimeArgs::default()) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) @@ -508,11 +501,11 @@ fn independent_standard_payments_should_not_write_the_same_keys() { .with_deploy_hash([2; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; let exec_request_from_account_1 = { - let deploy = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(ACCOUNT_1_ADDR) .with_session_code(DO_NOTHING_WASM, RuntimeArgs::default()) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) @@ -520,7 +513,7 @@ fn independent_standard_payments_should_not_write_the_same_keys() { .with_deploy_hash([1; 32]) .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; // run two independent deploys diff --git a/execution_engine_testing/tests/src/test/system_contracts/upgrade.rs b/execution_engine_testing/tests/src/test/system_contracts/upgrade.rs index 3179caa4ab..738daf579f 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/upgrade.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/upgrade.rs @@ -8,7 +8,7 @@ use casper_engine_test_support::{ DEFAULT_MAX_ASSOCIATED_KEYS, DEFAULT_UNBONDING_DELAY, PRODUCTION_RUN_GENESIS_REQUEST, }; -use crate::{lmdb_fixture, lmdb_fixture::CONTRACT_REGISTRY_SPECIAL_ADDRESS}; +use crate::{lmdb_fixture, lmdb_fixture::ENTRY_REGISTRY_SPECIAL_ADDRESS}; use casper_types::{ account::{AccountHash, ACCOUNT_HASH_LENGTH}, runtime_args, system, @@ -703,7 +703,6 @@ fn should_increase_max_associated_keys_after_upgrade() { ARG_ACCOUNT => account_hash, }, ) - .with_protocol_version(new_protocol_version) .build(); builder.exec(add_request).expect_success().commit(); @@ -726,10 +725,10 @@ fn should_correctly_migrate_and_prune_system_contract_records() { let (mut builder, lmdb_fixture_state, _temp_dir) = lmdb_fixture::builder_from_global_state_fixture(lmdb_fixture::RELEASE_1_3_1); - let legacy_system_contract_registry = { + let legacy_system_entity_registry = { let stored_value: StoredValue = builder - .query(None, CONTRACT_REGISTRY_SPECIAL_ADDRESS, &[]) - .expect("should query system contract registry"); + .query(None, ENTRY_REGISTRY_SPECIAL_ADDRESS, &[]) + .expect("should query system entity registry"); let cl_value = stored_value .as_cl_value() .cloned() @@ -744,7 +743,7 @@ fn should_correctly_migrate_and_prune_system_contract_records() { let mut global_state_update = BTreeMap::::new(); - let registry = CLValue::from_t(legacy_system_contract_registry.clone()) + let registry = CLValue::from_t(legacy_system_entity_registry.clone()) .expect("must convert to StoredValue") .into(); @@ -766,7 +765,7 @@ fn should_correctly_migrate_and_prune_system_contract_records() { let system_names = vec![system::MINT, system::AUCTION, system::HANDLE_PAYMENT]; for name in system_names { - let legacy_hash = *legacy_system_contract_registry + let legacy_hash = *legacy_system_entity_registry .get(name) .expect("must have hash"); diff --git a/execution_engine_testing/tests/src/test/system_costs.rs b/execution_engine_testing/tests/src/test/system_costs.rs index b627f0f89c..150d3c450b 100644 --- a/execution_engine_testing/tests/src/test/system_costs.rs +++ b/execution_engine_testing/tests/src/test/system_costs.rs @@ -212,7 +212,6 @@ fn upgraded_add_bid_and_withdraw_bid_have_expected_costs() { SYSTEM_CONTRACT_HASHES_NAME, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder .exec(system_contract_hashes_request) @@ -239,7 +238,6 @@ fn upgraded_add_bid_and_withdraw_bid_have_expected_costs() { auction::ARG_DELEGATION_RATE => BID_DELEGATION_RATE, }, ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); let balance_before = builder.get_purse_balance(account.main_purse()); @@ -276,7 +274,6 @@ fn upgraded_add_bid_and_withdraw_bid_have_expected_costs() { auction::ARG_AMOUNT => U512::from(BOND_AMOUNT), }, ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); let balance_before = builder.get_purse_balance(account.main_purse()); @@ -529,7 +526,6 @@ fn upgraded_delegate_and_undelegate_have_expected_costs() { SYSTEM_CONTRACT_HASHES_NAME, RuntimeArgs::default(), ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder .exec(system_contract_hashes_request) @@ -556,7 +552,6 @@ fn upgraded_delegate_and_undelegate_have_expected_costs() { auction::ARG_AMOUNT => U512::from(BID_AMOUNT), }, ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); let proposer_reward_starting_balance_1 = builder.get_proposer_purse_balance(); @@ -593,7 +588,6 @@ fn upgraded_delegate_and_undelegate_have_expected_costs() { auction::ARG_NEW_VALIDATOR => VALIDATOR_2.clone() }, ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); builder.exec(redelegate_request).expect_success().commit(); @@ -618,7 +612,6 @@ fn upgraded_delegate_and_undelegate_have_expected_costs() { auction::ARG_AMOUNT => U512::from(BID_AMOUNT - DEFAULT_MINIMUM_DELEGATION_AMOUNT), }, ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); let balance_before = builder.get_purse_balance(account.main_purse()); @@ -815,8 +808,6 @@ fn should_charge_for_erroneous_system_contract_calls() { let _error = builder .get_last_exec_result() .expect("should have results") - .get(0) - .expect("should have first result") .as_error() .unwrap_or_else(|| panic!("should have error while executing {}", entrypoint)); @@ -982,7 +973,6 @@ fn should_verify_wasm_add_bid_wasm_cost_is_not_recursive() { auction::ARG_DELEGATION_RATE => BID_DELEGATION_RATE, }, ) - .with_protocol_version(*NEW_PROTOCOL_VERSION) .build(); // Verify that user is called and deploy raises runtime error diff --git a/execution_engine_testing/tests/src/test/upgrade.rs b/execution_engine_testing/tests/src/test/upgrade.rs index aa41c5d3a7..9d54094a93 100644 --- a/execution_engine_testing/tests/src/test/upgrade.rs +++ b/execution_engine_testing/tests/src/test/upgrade.rs @@ -7,10 +7,10 @@ use casper_execution_engine::{engine_state, execution::Error}; use casper_types::{ account::AccountHash, addressable_entity::{AssociatedKeys, Weight}, - package::{EntityVersion, ENTITY_INITIAL_VERSION}, runtime_args, system::mint, - AddressableEntityHash, CLValue, EraId, PackageHash, ProtocolVersion, RuntimeArgs, StoredValue, + AddressableEntityHash, CLValue, EntityVersion, EraId, PackageHash, ProtocolVersion, + RuntimeArgs, StoredValue, ENTITY_INITIAL_VERSION, }; const DO_NOTHING_STORED_CONTRACT_NAME: &str = "do_nothing_stored"; @@ -825,14 +825,14 @@ fn should_only_upgrade_if_threshold_is_met() { entity_account_hashes }; - let valid_upgrade_request = ExecuteRequestBuilder::with_authorization_keys( + let valid_upgrade_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, UPGRADE_THRESHOLD_UPGRADER, runtime_args! { ARG_CONTRACT_PACKAGE => upgrade_threshold_package_hash }, - &authorization_keys, ) + .with_authorization_keys(authorization_keys.into_iter().collect()) .build(); builder @@ -841,7 +841,7 @@ fn should_only_upgrade_if_threshold_is_met() { .commit(); } -fn setup_upgrade_threshold_state() -> (LmdbWasmTestBuilder, ProtocolVersion, AccountHash) { +fn setup_upgrade_threshold_state() -> (LmdbWasmTestBuilder, AccountHash) { const ACCOUNT_1_ADDR: AccountHash = AccountHash::new([1u8; 32]); const UPGRADE_THRESHOLDS_FIXTURE: &str = "upgrade_thresholds"; @@ -876,18 +876,17 @@ fn setup_upgrade_threshold_state() -> (LmdbWasmTestBuilder, ProtocolVersion, Acc mint::ARG_ID => Some(42u64), }, ) - .with_protocol_version(new_protocol_version) .build(); builder.exec(transfer).expect_success().commit(); - (builder, new_protocol_version, ACCOUNT_1_ADDR) + (builder, ACCOUNT_1_ADDR) } #[ignore] #[test] fn should_migrate_with_correct_upgrade_thresholds() { - let (mut builder, new_protocol_version, _) = setup_upgrade_threshold_state(); + let (mut builder, _) = setup_upgrade_threshold_state(); let default_addressable_entity = builder .get_entity_with_named_keys_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -908,7 +907,6 @@ fn should_migrate_with_correct_upgrade_thresholds() { HASH_KEY_NAME => contract_hash }, ) - .with_protocol_version(new_protocol_version) .build(); builder.exec(exec_request).expect_success().commit(); let purse_holder_as_entity = builder @@ -925,7 +923,7 @@ fn should_migrate_with_correct_upgrade_thresholds() { #[ignore] #[test] fn should_correctly_set_upgrade_threshold_on_entity_upgrade() { - let (mut builder, new_protocol_version, entity_1) = setup_upgrade_threshold_state(); + let (mut builder, entity_1) = setup_upgrade_threshold_state(); let default_addressable_entity = builder .get_entity_with_named_keys_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -955,7 +953,6 @@ fn should_correctly_set_upgrade_threshold_on_entity_upgrade() { HASH_KEY_NAME => entity_hash }, ) - .with_protocol_version(new_protocol_version) .build(); builder.exec(exec_request).expect_success().commit(); @@ -975,7 +972,6 @@ fn should_correctly_set_upgrade_threshold_on_entity_upgrade() { ARG_CONTRACT_PACKAGE => stored_package_hash }, ) - .with_protocol_version(new_protocol_version) .build(); builder.exec(upgrade_request).expect_success().commit(); @@ -1010,7 +1006,7 @@ enum InvocationType { } fn call_and_migrate_purse_holder_contract(invocation_type: InvocationType) { - let (mut builder, new_protocol_version, _) = setup_upgrade_threshold_state(); + let (mut builder, _) = setup_upgrade_threshold_state(); let runtime_args = runtime_args! { PURSE_NAME_ARG_NAME => PURSE_1 @@ -1044,7 +1040,6 @@ fn call_and_migrate_purse_holder_contract(invocation_type: InvocationType) { ENTRY_POINT_ADD, runtime_args, ) - .with_protocol_version(new_protocol_version) .build() } InvocationType::ByPackageHash(maybe_contract_version) => { @@ -1055,7 +1050,6 @@ fn call_and_migrate_purse_holder_contract(invocation_type: InvocationType) { ENTRY_POINT_ADD, runtime_args, ) - .with_protocol_version(new_protocol_version) .build() } InvocationType::ByContractHash => ExecuteRequestBuilder::contract_call_by_hash( @@ -1064,7 +1058,6 @@ fn call_and_migrate_purse_holder_contract(invocation_type: InvocationType) { ENTRY_POINT_ADD, runtime_args, ) - .with_protocol_version(new_protocol_version) .build(), InvocationType::ByContractName => ExecuteRequestBuilder::contract_call_by_name( *DEFAULT_ACCOUNT_ADDR, @@ -1072,7 +1065,6 @@ fn call_and_migrate_purse_holder_contract(invocation_type: InvocationType) { ENTRY_POINT_ADD, runtime_args, ) - .with_protocol_version(new_protocol_version) .build(), InvocationType::ByUpgrader => ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -1081,7 +1073,6 @@ fn call_and_migrate_purse_holder_contract(invocation_type: InvocationType) { ARG_CONTRACT_PACKAGE => package_hash }, ) - .with_protocol_version(new_protocol_version) .build(), }; diff --git a/execution_engine_testing/tests/src/test/wasmless_transfer.rs b/execution_engine_testing/tests/src/test/wasmless_transfer.rs index cf1cbfae24..1839397fab 100644 --- a/execution_engine_testing/tests/src/test/wasmless_transfer.rs +++ b/execution_engine_testing/tests/src/test/wasmless_transfer.rs @@ -520,10 +520,7 @@ fn invalid_transfer_wasmless(invalid_wasmless_transfer: InvalidWasmlessTransfer) let result = builder .get_last_exec_result() - .expect("Expected to be called after run()") - .get(0) - .cloned() - .expect("Unable to get first deploy result"); + .expect("Expected to be called after run()"); assert!(result.is_failure(), "was expected to fail"); @@ -1018,9 +1015,7 @@ fn transfer_wasmless_should_observe_upgraded_cost() { .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([42; 32]) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item) - .with_protocol_version(new_protocol_version) - .build() + ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; builder diff --git a/node/src/components/contract_runtime.rs b/node/src/components/contract_runtime.rs index 86a98ef0db..a2328461a8 100644 --- a/node/src/components/contract_runtime.rs +++ b/node/src/components/contract_runtime.rs @@ -26,7 +26,7 @@ use lmdb::DatabaseFlags; use prometheus::Registry; use tracing::{debug, error, info, trace}; -use casper_execution_engine::engine_state::{DeployItem, EngineConfigBuilder, EngineState}; +use casper_execution_engine::engine_state::{EngineConfigBuilder, EngineState}; use casper_storage::{ data_access_layer::{ @@ -42,9 +42,7 @@ use casper_storage::{ system::{genesis::GenesisError, protocol_upgrade::ProtocolUpgradeError}, tracking_copy::TrackingCopyError, }; -use casper_types::{ - Chainspec, ChainspecRawBytes, ChainspecRegistry, ProtocolUpgradeConfig, Transaction, -}; +use casper_types::{Chainspec, ChainspecRawBytes, ChainspecRegistry, ProtocolUpgradeConfig}; use crate::{ components::{fetcher::FetchResponse, Component, ComponentState}, @@ -72,8 +70,8 @@ pub(crate) use operations::compute_execution_results_checksum; pub use operations::execute_finalized_block; use operations::speculatively_execute; pub(crate) use types::{ - BlockAndExecutionResults, ExecutionArtifact, ExecutionPreState, SpeculativeExecutionState, - StepEffectsAndUpcomingEraValidators, + BlockAndExecutionResults, ExecutionArtifact, ExecutionPreState, SpeculativeExecutionError, + SpeculativeExecutionState, StepEffectsAndUpcomingEraValidators, }; use utils::{exec_or_requeue, run_intensive_task}; @@ -137,6 +135,7 @@ impl ContractRuntime { .with_allow_unrestricted_transfers(chainspec.core_config.allow_unrestricted_transfers) .with_refund_handling(chainspec.core_config.refund_handling) .with_fee_handling(chainspec.core_config.fee_handling) + .with_protocol_version(chainspec.protocol_version()) .build(); let engine_state = EngineState::new(data_access_layer, engine_config); @@ -565,24 +564,19 @@ impl ContractRuntime { transaction, responder, } => { - if let Transaction::Deploy(deploy) = *transaction { - let engine_state = Arc::clone(&self.engine_state); - async move { - let result = run_intensive_task(move || { - speculatively_execute( - engine_state.as_ref(), - execution_prestate, - DeployItem::from(deploy.clone()), - ) - }) - .await; - responder.respond(result).await - } - .ignore() - } else { - unreachable!() - //async move { responder.respond(Ok(None)).await }.ignore() + let engine_state = Arc::clone(&self.engine_state); + async move { + let result = run_intensive_task(move || { + speculatively_execute( + engine_state.as_ref(), + execution_prestate, + *transaction, + ) + }) + .await; + responder.respond(result).await } + .ignore() } } } diff --git a/node/src/components/contract_runtime/error.rs b/node/src/components/contract_runtime/error.rs index 28091861b7..570b6be3ef 100644 --- a/node/src/components/contract_runtime/error.rs +++ b/node/src/components/contract_runtime/error.rs @@ -5,7 +5,9 @@ use std::collections::BTreeMap; use serde::Serialize; use thiserror::Error; -use casper_execution_engine::engine_state::{Error as EngineStateError, StepError}; +use casper_execution_engine::engine_state::{ + Error as EngineStateError, NewRequestError, StepError, +}; use casper_storage::{ global_state::error::Error as GlobalStateError, tracking_copy::TrackingCopyError, }; @@ -115,4 +117,11 @@ pub enum BlockExecutionError { /// A root state hash was not found. #[error("Root state hash not found in global state.")] RootNotFound(Digest), + /// An error that occurred while constructing the execution request. + #[error(transparent)] + NewRequest( + #[from] + #[serde(skip_serializing)] + NewRequestError, + ), } diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 13c0c8f4f0..cd86080906 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -4,11 +4,9 @@ use itertools::Itertools; use tracing::{debug, error, info, trace, warn}; use casper_execution_engine::engine_state::{ - self, - execution_result::{ExecutionResultAndMessages, ExecutionResults}, - step::EvictItem, - DeployItem, EngineState, ExecuteRequest, ExecutionResult as EngineExecutionResult, PruneConfig, - PruneResult, StepError, StepRequest, StepSuccess, + self, execution_result::ExecutionResultAndMessages, step::EvictItem, EngineState, + ExecuteRequest, ExecutionResult as EngineExecutionResult, PruneConfig, PruneResult, StepError, + StepRequest, StepSuccess, }; use casper_storage::{ data_access_layer::{ @@ -22,16 +20,16 @@ use casper_types::{ bytesrepr::{self, ToBytes, U32_SERIALIZED_LENGTH}, contract_messages::Messages, execution::{Effects, ExecutionResult, ExecutionResultV2, Transform, TransformKind}, - BlockV2, CLValue, ChecksumRegistry, DeployHash, Digest, EraEndV2, EraId, Gas, Key, - ProtocolVersion, PublicKey, Transaction, U512, + BlockTime, BlockV2, CLValue, ChecksumRegistry, Digest, EraEndV2, EraId, Gas, Key, + ProtocolVersion, PublicKey, Transaction, TransactionHash, TransactionHeader, U512, }; use crate::{ components::{ contract_runtime::{ error::BlockExecutionError, types::StepEffectsAndUpcomingEraValidators, - BlockAndExecutionResults, ExecutionPreState, Metrics, SpeculativeExecutionState, - APPROVALS_CHECKSUM_NAME, EXECUTION_RESULTS_CHECKSUM_NAME, + BlockAndExecutionResults, ExecutionPreState, Metrics, SpeculativeExecutionError, + SpeculativeExecutionState, APPROVALS_CHECKSUM_NAME, EXECUTION_RESULTS_CHECKSUM_NAME, }, fetcher::FetchItem, }, @@ -69,7 +67,7 @@ pub fn execute_finalized_block( let mut state_root_hash = pre_state_root_hash; let mut execution_results: Vec = Vec::with_capacity(executable_block.transactions.len()); - // Run any deploys that must be executed + // Run any transactions that must be executed let block_time = executable_block.timestamp.millis(); let start = Instant::now(); let txn_ids = executable_block @@ -96,9 +94,10 @@ pub fn execute_finalized_block( } for transaction in executable_block.transactions { - let (deploy_hash, deploy) = match transaction { + let (txn_hash, txn) = match transaction { Transaction::Deploy(deploy) => { let deploy_hash = *deploy.hash(); + let txn_hash = TransactionHash::Deploy(deploy_hash); if deploy.is_transfer() { // native transfers are routed to the data provider let authorization_keys = deploy @@ -122,11 +121,9 @@ pub fn execute_finalized_block( ); // native transfer auto-commits let transfer_result = data_access_layer.transfer(transfer_req); - trace!(?deploy_hash, ?transfer_result, "native transfer result"); - match EngineExecutionResult::from_transfer_result( - transfer_result, - Gas::new(U512::zero()), - ) { + trace!(%txn_hash, ?transfer_result, "native transfer result"); + match EngineExecutionResult::from_transfer_result(transfer_result, Gas::zero()) + { Err(_) => return Err(BlockExecutionError::RootNotFound(state_root_hash)), Ok(exec_result) => { let ExecutionResultAndMessages { @@ -136,8 +133,8 @@ pub fn execute_finalized_block( let versioned_execution_result = ExecutionResult::from(execution_result); execution_results.push(ExecutionArtifact::new( - deploy_hash, - deploy.header().clone(), + txn_hash, + TransactionHeader::Deploy(deploy.header().clone()), versioned_execution_result, messages, )); @@ -145,42 +142,51 @@ pub fn execute_finalized_block( } continue; } - (deploy_hash, deploy) + ( + TransactionHash::Deploy(deploy_hash), + Transaction::Deploy(deploy), + ) } - Transaction::V1(_) => continue, + txn @ Transaction::V1(_) => (txn.hash(), txn), }; - let deploy_header = deploy.header().clone(); + if txn.is_native() { + todo!("route native transactions to data access layer"); + } + + let txn_header = match &txn { + Transaction::Deploy(deploy) => TransactionHeader::from(deploy.header().clone()), + Transaction::V1(v1_txn) => TransactionHeader::from(v1_txn.header().clone()), + }; let execute_request = ExecuteRequest::new( state_root_hash, - block_time, - vec![DeployItem::from(deploy)], - protocol_version, - PublicKey::clone(&executable_block.proposer), - ); + BlockTime::new(block_time), + txn, + (*executable_block.proposer).clone(), + )?; - let result = execute(&scratch_state, metrics.clone(), execute_request)?; + let exec_result_and_msgs = execute(&scratch_state, metrics.clone(), execute_request)?; - trace!(?deploy_hash, ?result, "deploy execution result"); + trace!(%txn_hash, ?exec_result_and_msgs, "transaction execution result"); // As for now a given state is expected to exist. - let (state_hash, execution_result, messages) = commit_execution_results( + let new_state_root_hash = commit_execution_result( &scratch_state, // data_access_layer, metrics.clone(), state_root_hash, - deploy_hash, - result, + txn_hash, + &exec_result_and_msgs.execution_result, )?; execution_results.push(ExecutionArtifact::new( - deploy_hash, - deploy_header, - execution_result, - messages, + txn_hash, + txn_header, + ExecutionResult::from(exec_result_and_msgs.execution_result), + exec_result_and_msgs.messages, )); - state_root_hash = state_hash; + state_root_hash = new_state_root_hash; } - // Write the deploy approvals' and execution results' checksums to global state. + // Write the transaction approvals' and execution results' checksums to global state. let execution_results_checksum = compute_execution_results_checksum( execution_results .iter() @@ -416,138 +422,84 @@ pub fn execute_finalized_block( } /// Commits the execution results. -fn commit_execution_results( +fn commit_execution_result( engine_state: &EngineState, // data_access_layer: &DataAccessLayer, metrics: Option>, state_root_hash: Digest, - deploy_hash: DeployHash, - execution_results: ExecutionResults, -) -> Result<(Digest, ExecutionResult, Messages), BlockExecutionError> + txn_hash: TransactionHash, + execution_result: &ExecutionResultV2, +) -> Result where S: StateProvider + CommitProvider, { - let ee_execution_result = execution_results - .into_iter() - .exactly_one() - .map_err(|_| BlockExecutionError::MoreThanOneExecutionResult)?; - - let effects = match &ee_execution_result { - EngineExecutionResult::Success { effects, cost, .. } => { - // We do want to see the deploy hash and cost in the logs. - // We don't need to see the effects in the logs. - debug!(?deploy_hash, %cost, "execution succeeded"); + let start = Instant::now(); + let effects = match execution_result { + ExecutionResultV2::Success { effects, gas, .. } => { + debug!(%txn_hash, %gas, "execution succeeded"); effects.clone() } - EngineExecutionResult::Failure { - error, + ExecutionResultV2::Failure { + error_message, effects, - cost, + gas, .. } => { - // Failure to execute a contract is a user error, not a system error. - // We do want to see the deploy hash, error, and cost in the logs. - // We don't need to see the effects in the logs. - debug!(?deploy_hash, ?error, %cost, "execution failure"); + debug!(%txn_hash, %error_message, %gas, "execution failed"); effects.clone() } }; - let new_state_root = commit_transforms(engine_state, metrics, state_root_hash, effects)?; - // let new_state_root = commit_transforms(data_access_layer, metrics, state_root_hash, - // effects)?; - let ExecutionResultAndMessages { - execution_result, - messages, - } = ExecutionResultAndMessages::from(ee_execution_result); - let versioned_execution_result = ExecutionResult::from(execution_result); - Ok((new_state_root, versioned_execution_result, messages)) -} - -fn commit_transforms( - engine_state: &EngineState, - // data_access_layer: &DataAccessLayer, - metrics: Option>, - state_root_hash: Digest, - effects: Effects, -) -> Result -// ) -> Result -where - S: StateProvider + CommitProvider, -{ - trace!(?state_root_hash, ?effects, "commit"); - let start = Instant::now(); - let result = engine_state.commit_effects(state_root_hash, effects); - // let result = data_access_layer.commit(state_root_hash, effects); + let commit_result = engine_state.commit_effects(state_root_hash, effects); if let Some(metrics) = metrics { metrics.apply_effect.observe(start.elapsed().as_secs_f64()); } - trace!(?result, "commit result"); - result.map(Digest::from) - // result + commit_result.map_err(BlockExecutionError::from) } /// Execute the transaction without committing the effects. /// Intended to be used for discovery operations on read-only nodes. /// /// Returns effects of the execution. -pub fn speculatively_execute( +pub(super) fn speculatively_execute( engine_state: &EngineState, execution_state: SpeculativeExecutionState, - deploy: DeployItem, -) -> Result, engine_state::Error> + txn: Transaction, +) -> Result<(ExecutionResultV2, Messages), SpeculativeExecutionError> where S: StateProvider + CommitProvider, { let SpeculativeExecutionState { state_root_hash, block_time, - protocol_version, + protocol_version: _, } = execution_state; - let deploy_hash = deploy.deploy_hash; + if txn.is_native() { + todo!("route native transactions to data access layer"); + } let execute_request = ExecuteRequest::new( state_root_hash, - block_time.millis(), - vec![deploy], - protocol_version, + BlockTime::new(block_time.millis()), + txn, PublicKey::System, - ); - let results = execute(engine_state, None, execute_request); - results.map(|mut execution_results| { - let len = execution_results.len(); - if len != 1 { - warn!( - ?deploy_hash, - "got more ({}) execution results from a single transaction", len - ); - None - } else { - // We know it must be 1, we could unwrap and then wrap - // with `Some(_)` but `pop_front` already returns an `Option`. - // We need to transform the `engine_state::ExecutionResult` into - // `casper_types::ExecutionResult` as well. - execution_results.pop_front().map(|result| { - let ExecutionResultAndMessages { - execution_result, - messages, - } = result.into(); - - (execution_result, messages) - }) - } - }) + )?; + execute(engine_state, None, execute_request) + .map(|res_and_msgs| (res_and_msgs.execution_result, res_and_msgs.messages)) + .map_err(SpeculativeExecutionError::from) } fn execute( engine_state: &EngineState, metrics: Option>, execute_request: ExecuteRequest, -) -> Result +) -> Result where S: StateProvider + CommitProvider, { trace!(?execute_request, "execute"); let start = Instant::now(); - let result = engine_state.run_execute(execute_request); + let result = engine_state + .execute_transaction(execute_request) + .map(ExecutionResultAndMessages::from); if let Some(metrics) = metrics { metrics.run_execute.observe(start.elapsed().as_secs_f64()); } diff --git a/node/src/components/contract_runtime/rewards.rs b/node/src/components/contract_runtime/rewards.rs index ccdc1f6197..6a8ca88b67 100644 --- a/node/src/components/contract_runtime/rewards.rs +++ b/node/src/components/contract_runtime/rewards.rs @@ -1,7 +1,7 @@ #[cfg(test)] mod tests; -use std::{collections::BTreeMap, ops::Range, sync::Arc}; +use std::{collections::BTreeMap, ops::Range}; use casper_storage::data_access_layer::{ EraValidatorsRequest, RoundSeigniorageRateRequest, RoundSeigniorageRateResult, @@ -353,7 +353,7 @@ impl EraInfo { /// It is done in 2 steps so that it is easier to unit test the rewards calculation. pub(crate) async fn fetch_data_and_calculate_rewards_for_era( effect_builder: EffectBuilder, - chainspec: Arc, + chainspec: &Chainspec, executable_block: ExecutableBlock, ) -> Result, RewardsError> { let current_era_id = executable_block.era_id; diff --git a/node/src/components/contract_runtime/tests.rs b/node/src/components/contract_runtime/tests.rs index 5c34ef2d29..1085083c67 100644 --- a/node/src/components/contract_runtime/tests.rs +++ b/node/src/components/contract_runtime/tests.rs @@ -1,4 +1,4 @@ -use std::{sync::Arc, time::Duration}; +use std::{iter, sync::Arc, time::Duration}; use derive_more::{Display, From}; use prometheus::Registry; @@ -8,7 +8,7 @@ use tempfile::TempDir; use casper_types::{ bytesrepr::Bytes, runtime_args, BlockHash, Chainspec, ChainspecRawBytes, Deploy, Digest, EraId, - ExecutableDeployItem, PublicKey, SecretKey, TimeDiff, Timestamp, U512, + ExecutableDeployItem, PublicKey, SecretKey, TimeDiff, Timestamp, Transaction, U512, }; use super::*; @@ -304,7 +304,7 @@ async fn should_not_set_shared_pre_state_to_lower_block_height() { }, }; - let txns: Vec = std::iter::repeat_with(|| { + let txns: Vec = iter::repeat_with(|| { let target_public_key = PublicKey::random(rng); let session = ExecutableDeployItem::Transfer { args: runtime_args! { @@ -396,6 +396,7 @@ async fn should_not_set_shared_pre_state_to_lower_block_height() { mod trie_chunking_tests { use std::sync::Arc; + use casper_execution_engine::engine_state::engine_config::DEFAULT_FEE_HANDLING; use casper_storage::global_state::{ state::StateProvider, trie::{Pointer, Trie}, @@ -406,7 +407,7 @@ mod trie_chunking_tests { execution::{Transform, TransformKind}, testing::TestRng, ActivationPoint, CLValue, Chainspec, ChunkWithProof, CoreConfig, Digest, EraId, Key, - ProtocolConfig, StoredValue, TimeDiff, DEFAULT_FEE_HANDLING, DEFAULT_REFUND_HANDLING, + ProtocolConfig, StoredValue, TimeDiff, DEFAULT_REFUND_HANDLING, }; use prometheus::Registry; use tempfile::tempdir; diff --git a/node/src/components/contract_runtime/types.rs b/node/src/components/contract_runtime/types.rs index b70713e99d..3534e9ff33 100644 --- a/node/src/components/contract_runtime/types.rs +++ b/node/src/components/contract_runtime/types.rs @@ -2,13 +2,15 @@ use std::{collections::BTreeMap, sync::Arc}; use datasize::DataSize; use serde::Serialize; +use thiserror::Error; +use casper_execution_engine::engine_state::{Error as EngineStateError, NewRequestError}; use casper_storage::data_access_layer::EraValidatorsRequest; use casper_types::{ contract_messages::Messages, execution::{Effects, ExecutionResult}, - BlockHash, BlockHeaderV2, BlockV2, DeployHash, DeployHeader, Digest, EraId, ProtocolVersion, - PublicKey, Timestamp, U512, + BlockHash, BlockHeaderV2, BlockV2, Digest, EraId, ProtocolVersion, PublicKey, Timestamp, + TransactionHash, TransactionHeader, U512, }; use crate::types::ApprovalsHashes; @@ -64,22 +66,22 @@ pub(crate) struct StepEffectsAndUpcomingEraValidators { #[derive(Clone, Debug, DataSize, PartialEq, Eq, Serialize)] pub(crate) struct ExecutionArtifact { - pub(crate) deploy_hash: DeployHash, - pub(crate) deploy_header: DeployHeader, + pub(crate) transaction_hash: TransactionHash, + pub(crate) transaction_header: TransactionHeader, pub(crate) execution_result: ExecutionResult, pub(crate) messages: Messages, } impl ExecutionArtifact { pub(crate) fn new( - deploy_hash: DeployHash, - deploy_header: DeployHeader, + transaction_hash: TransactionHash, + transaction_header: TransactionHeader, execution_result: ExecutionResult, messages: Messages, ) -> Self { Self { - deploy_hash, - deploy_header, + transaction_hash, + transaction_header, execution_result, messages, } @@ -174,3 +176,13 @@ impl ExecutionPreState { self.parent_seed } } + +#[derive(Debug, Error)] +pub enum SpeculativeExecutionError { + /// An error that occurred while constructing the execution request. + #[error(transparent)] + NewRequest(#[from] NewRequestError), + /// An error that occurred while constructing the execution request. + #[error(transparent)] + EngineState(#[from] EngineStateError), +} diff --git a/node/src/components/contract_runtime/utils.rs b/node/src/components/contract_runtime/utils.rs index de32981f0e..40b54b1c2f 100644 --- a/node/src/components/contract_runtime/utils.rs +++ b/node/src/components/contract_runtime/utils.rs @@ -82,7 +82,7 @@ pub(super) async fn exec_or_requeue( executable_block.rewards = Some(if chainspec.core_config.compute_rewards { let rewards = match rewards::fetch_data_and_calculate_rewards_for_era( effect_builder, - chainspec, + chainspec.as_ref(), executable_block.clone(), ) .await @@ -193,7 +193,7 @@ pub(super) async fn exec_or_requeue( let execution_results_map: HashMap<_, _> = execution_results .iter() .cloned() - .map(|artifact| (artifact.deploy_hash.into(), artifact.execution_result)) + .map(|artifact| (artifact.transaction_hash, artifact.execution_result)) .collect(); if meta_block_state.register_as_stored().was_updated() { effect_builder diff --git a/node/src/components/rpc_server/rpcs/chain.rs b/node/src/components/rpc_server/rpcs/chain.rs index eed35ce76b..4c646adc97 100644 --- a/node/src/components/rpc_server/rpcs/chain.rs +++ b/node/src/components/rpc_server/rpcs/chain.rs @@ -11,8 +11,9 @@ use serde::{Deserialize, Serialize}; use casper_storage::data_access_layer::QueryResult; use casper_types::{ - Block, BlockHash, BlockHeaderV2, Digest, DigestError, JsonBlockWithSignatures, Key, - ProtocolVersion, Transfer, + account::AccountHash, AccessRights, Block, BlockHash, BlockHeaderV2, Digest, DigestError, Gas, + InitiatorAddr, JsonBlockWithSignatures, Key, ProtocolVersion, PublicKey, SecretKey, + TransactionHash, TransactionV1Hash, Transfer, URef, U512, }; use super::{ @@ -43,7 +44,16 @@ static GET_BLOCK_TRANSFERS_RESULT: Lazy = Lazy::new(|| GetBlockTransfersResult { api_version: DOCS_EXAMPLE_PROTOCOL_VERSION, block_hash: Some(*BlockHash::example()), - transfers: Some(vec![Transfer::default()]), + transfers: Some(vec![Transfer::new( + TransactionHash::V1(TransactionV1Hash::new(Digest::from([9; Digest::LENGTH]))), + InitiatorAddr::PublicKey(PublicKey::from(SecretKey::example())), + Some(AccountHash::new([10; 32])), + URef::new([11; 32], AccessRights::all()), + URef::new([12; 32], AccessRights::empty()), + U512::from(3_000_000_000_u64), + Gas::new(2_500_000_000_u64), + Some(9), + )]), }); static GET_STATE_ROOT_HASH_PARAMS: Lazy = Lazy::new(|| GetStateRootHashParams { diff --git a/node/src/components/rpc_server/rpcs/speculative_exec.rs b/node/src/components/rpc_server/rpcs/speculative_exec.rs index fce8fddb34..f285fad8f4 100644 --- a/node/src/components/rpc_server/rpcs/speculative_exec.rs +++ b/node/src/components/rpc_server/rpcs/speculative_exec.rs @@ -20,7 +20,10 @@ use super::{ docs::{DocExample, DOCS_EXAMPLE_PROTOCOL_VERSION}, Error, ErrorCode, ReactorEventT, RpcWithParams, }; -use crate::{components::contract_runtime::SpeculativeExecutionState, effect::EffectBuilder}; +use crate::{ + components::contract_runtime::{SpeculativeExecutionError, SpeculativeExecutionState}, + effect::EffectBuilder, +}; static SPECULATIVE_EXEC_TXN_PARAMS: Lazy = Lazy::new(|| SpeculativeExecTxnParams { @@ -174,7 +177,7 @@ async fn handle_request( .await; match result { - Ok(Some((execution_result, messages))) => { + Ok((execution_result, messages)) => { let result = SpeculativeExecTxnResult { api_version, block_hash, @@ -183,24 +186,24 @@ async fn handle_request( }; Ok(result) } - Ok(None) => Err(Error::new( - ErrorCode::NoSuchBlock, - "block hash not found".to_string(), - )), - Err(error) => { + Err(SpeculativeExecutionError::NewRequest(error)) => { + let rpc_error = Error::new(ErrorCode::InvalidTransaction, error.to_string()); + Err(rpc_error) + } + Err(SpeculativeExecutionError::EngineState(error)) => { let rpc_error = match error { EngineStateError::RootNotFound(_) => Error::new(ErrorCode::NoSuchStateRoot, ""), EngineStateError::WasmPreprocessing(error) => { - Error::new(ErrorCode::InvalidDeploy, error.to_string()) + Error::new(ErrorCode::InvalidTransaction, error.to_string()) } EngineStateError::InvalidDeployItemVariant(error) => { - Error::new(ErrorCode::InvalidDeploy, error) + Error::new(ErrorCode::InvalidTransaction, error) } EngineStateError::InvalidProtocolVersion(_) => Error::new( - ErrorCode::InvalidDeploy, + ErrorCode::InvalidTransaction, format!("deploy used invalid protocol version {}", error), ), - EngineStateError::Deploy => Error::new(ErrorCode::InvalidDeploy, ""), + EngineStateError::Deploy => Error::new(ErrorCode::InvalidTransaction, ""), EngineStateError::Genesis(_) | EngineStateError::WasmSerialization(_) | EngineStateError::Exec(_) @@ -214,7 +217,7 @@ async fn handle_request( | EngineStateError::InvalidKeyVariant | EngineStateError::ProtocolUpgrade(_) | EngineStateError::CommitError(_) - | EngineStateError::MissingSystemContractRegistry + | EngineStateError::MissingSystemEntityRegistry | EngineStateError::MissingSystemContractHash(_) | EngineStateError::RuntimeStackOverflow | EngineStateError::FailedToGetKeys(_) diff --git a/node/src/components/storage.rs b/node/src/components/storage.rs index 48e81ae9ba..e077abe5c2 100644 --- a/node/src/components/storage.rs +++ b/node/src/components/storage.rs @@ -2973,14 +2973,14 @@ fn successful_transfers(execution_result: &ExecutionResult) -> Vec { if let execution_result_v1::Transform::WriteTransfer(transfer) = &transform_entry.transform { - transfers.push(*transfer); + transfers.push(transfer.clone()); } } } ExecutionResult::V2(ExecutionResultV2::Success { effects, .. }) => { for transform in effects.transforms() { if let TransformKind::Write(StoredValue::Transfer(transfer)) = transform.kind() { - transfers.push(*transfer); + transfers.push(transfer.clone()); } } } diff --git a/node/src/components/storage/tests.rs b/node/src/components/storage/tests.rs index 5e5baf5c35..0772947cd5 100644 --- a/node/src/components/storage/tests.rs +++ b/node/src/components/storage/tests.rs @@ -26,9 +26,10 @@ use casper_types::{ testing::TestRng, AccessRights, Block, BlockHash, BlockHeader, BlockSignatures, BlockSignaturesV2, BlockV2, ChainNameDigest, Chainspec, ChainspecRawBytes, Deploy, DeployApprovalsHash, DeployHash, Digest, - EraId, FinalitySignature, FinalitySignatureV2, Key, ProtocolVersion, PublicKey, SecretKey, - SignedBlockHeader, TestBlockBuilder, TestBlockV1Builder, TimeDiff, Transaction, - TransactionApprovalsHash, TransactionHash, TransactionV1Hash, Transfer, URef, U512, + EraId, FinalitySignature, FinalitySignatureV2, Gas, InitiatorAddr, Key, ProtocolVersion, + PublicKey, SecretKey, SignedBlockHeader, TestBlockBuilder, TestBlockV1Builder, TimeDiff, + Transaction, TransactionApprovalsHash, TransactionHash, TransactionV1Hash, Transfer, URef, + U512, }; use tempfile::tempdir; @@ -1329,21 +1330,21 @@ fn store_execution_results_twice_for_same_block_deploy_pair() { fn prepare_exec_result_with_transfer( rng: &mut TestRng, - deploy_hash: &DeployHash, + txn_hash: &TransactionHash, ) -> (ExecutionResult, Transfer) { let transfer = Transfer::new( - *deploy_hash, - rng.gen(), + *txn_hash, + InitiatorAddr::random(rng), Some(rng.gen()), rng.gen(), rng.gen(), rng.gen(), - rng.gen(), + Gas::from(rng.gen::()), Some(rng.gen()), ); let transform = TransformEntry { - key: Key::DeployInfo(*deploy_hash).to_formatted_string(), - transform: Transform::WriteTransfer(transfer), + key: Key::TransactionInfo(*txn_hash).to_formatted_string(), + transform: Transform::WriteTransfer(transfer.clone()), }; let effect = ExecutionEffect { operations: vec![], @@ -1372,7 +1373,8 @@ fn store_identical_execution_results() { storage.put_block(&block).unwrap(); let block_hash = *block.hash(); - let (exec_result, transfer) = prepare_exec_result_with_transfer(&mut harness.rng, &deploy_hash); + let (exec_result, transfer) = + prepare_exec_result_with_transfer(&mut harness.rng, &TransactionHash::Deploy(deploy_hash)); let mut exec_results = HashMap::new(); exec_results.insert(TransactionHash::from(deploy_hash), exec_result.clone()); @@ -1483,7 +1485,8 @@ fn should_provide_transfers_after_emptied() { storage.put_block(&block).unwrap(); let block_hash = *block.hash(); - let (exec_result, transfer) = prepare_exec_result_with_transfer(&mut harness.rng, &deploy_hash); + let (exec_result, transfer) = + prepare_exec_result_with_transfer(&mut harness.rng, &TransactionHash::Deploy(deploy_hash)); let mut exec_results = HashMap::new(); exec_results.insert(TransactionHash::from(deploy_hash), exec_result); @@ -2945,6 +2948,7 @@ fn assert_highest_block_in_storage( // Since this change impacts the storage APIs, create a test to prove that we can still access old // unversioned blocks through the new APIs and also check that both versioned and unversioned blocks // can co-exist in storage. +#[ignore = "stop ignoring once decision around Transfer type is made"] fn check_block_operations_with_node_1_5_2_storage() { let rng: TestRng = TestRng::new(); @@ -3007,7 +3011,10 @@ fn check_block_operations_with_node_1_5_2_storage() { let mut stored_transfers: Vec = transfers .unwrap() .iter() - .map(|transfer| transfer.deploy_hash) + .map(|transfer| match transfer.transaction_hash { + TransactionHash::Deploy(deploy_hash) => deploy_hash, + TransactionHash::V1(_) => panic!("expected deploy"), + }) .collect(); stored_transfers.sort(); let mut expected_deploys = block_info.deploy_hashes.clone(); diff --git a/node/src/components/transaction_acceptor.rs b/node/src/components/transaction_acceptor.rs index a7282a1eec..c1f0345519 100644 --- a/node/src/components/transaction_acceptor.rs +++ b/node/src/components/transaction_acceptor.rs @@ -14,11 +14,11 @@ use casper_execution_engine::engine_state::MAX_PAYMENT; use casper_storage::data_access_layer::BalanceRequest; use casper_types::{ account::AccountHash, addressable_entity::AddressableEntity, contracts::ContractHash, - package::Package, system::auction::ARG_AMOUNT, AddressableEntityHash, - AddressableEntityIdentifier, BlockHeader, Chainspec, EntityAddr, EntityVersion, - EntityVersionKey, ExecutableDeployItem, ExecutableDeployItemIdentifier, InitiatorAddr, Key, - PackageAddr, PackageHash, PackageIdentifier, ProtocolVersion, Transaction, TransactionConfig, - TransactionEntryPoint, TransactionInvocationTarget, TransactionTarget, U512, + system::auction::ARG_AMOUNT, AddressableEntityHash, AddressableEntityIdentifier, BlockHeader, + Chainspec, EntityAddr, EntityVersion, EntityVersionKey, ExecutableDeployItem, + ExecutableDeployItemIdentifier, InitiatorAddr, Key, Package, PackageAddr, PackageHash, + PackageIdentifier, ProtocolVersion, Transaction, TransactionConfig, TransactionEntryPoint, + TransactionInvocationTarget, TransactionTarget, U512, }; use crate::{ diff --git a/node/src/components/transaction_acceptor/tests.rs b/node/src/components/transaction_acceptor/tests.rs index c30ee1c35f..d32b535ab9 100644 --- a/node/src/components/transaction_acceptor/tests.rs +++ b/node/src/components/transaction_acceptor/tests.rs @@ -407,7 +407,7 @@ impl TestScenario { } ContractScenario::MissingContractAtHash => { let txn = TransactionV1Builder::new_targeting_invocable_entity( - EntityAddr::SmartContract(HashAddr::default()), + AddressableEntityHash::new(HashAddr::default()), "call", ) .with_chain_name("casper-example") @@ -419,7 +419,7 @@ impl TestScenario { } ContractScenario::MissingEntryPoint => { let txn = TransactionV1Builder::new_targeting_invocable_entity( - EntityAddr::SmartContract(HashAddr::default()), + AddressableEntityHash::new(HashAddr::default()), "non-existent-entry-point", ) .with_chain_name("casper-example") @@ -469,7 +469,7 @@ impl TestScenario { } ContractPackageScenario::MissingPackageAtHash => { let txn = TransactionV1Builder::new_targeting_package( - PackageAddr::default(), + PackageHash::new(PackageAddr::default()), None, "call", ) @@ -482,7 +482,7 @@ impl TestScenario { } ContractPackageScenario::MissingContractVersion => { let txn = TransactionV1Builder::new_targeting_package( - PackageAddr::default(), + PackageHash::new(PackageAddr::default()), Some(6), "call", ) diff --git a/node/src/effect.rs b/node/src/effect.rs index f321bb5354..fbce06e879 100644 --- a/node/src/effect.rs +++ b/node/src/effect.rs @@ -114,7 +114,6 @@ use smallvec::{smallvec, SmallVec}; use tokio::{sync::Semaphore, time}; use tracing::{debug, error, warn}; -use casper_execution_engine::engine_state::{self}; use casper_storage::data_access_layer::{ BalanceRequest, BalanceResult, BidsRequest, BidsResult, QueryRequest, QueryResult, }; @@ -127,10 +126,10 @@ use casper_storage::data_access_layer::{ use casper_types::{ contract_messages::Messages, execution::{Effects as ExecutionEffects, ExecutionResult, ExecutionResultV2}, - package::Package, Block, BlockHash, BlockHeader, BlockSignatures, BlockV2, ChainspecRawBytes, DeployHash, Digest, - EraId, FinalitySignature, FinalitySignatureId, FinalitySignatureV2, Key, PublicKey, TimeDiff, - Timestamp, Transaction, TransactionHash, TransactionHeader, TransactionId, Transfer, U512, + EraId, FinalitySignature, FinalitySignatureId, FinalitySignatureV2, Key, Package, PublicKey, + TimeDiff, Timestamp, Transaction, TransactionHash, TransactionHeader, TransactionId, Transfer, + U512, }; use crate::{ @@ -140,6 +139,7 @@ use crate::{ TrieAccumulatorError, TrieAccumulatorResponse, }, consensus::{ClContext, EraDump, ProposedBlock, ValidatorChange}, + contract_runtime::{SpeculativeExecutionError, SpeculativeExecutionState}, diagnostics_port::StopAtSpec, fetcher::{FetchItem, FetchResult}, gossiper::GossipItem, @@ -147,7 +147,6 @@ use crate::{ transaction_acceptor, upgrade_watcher::NextUpgrade, }, - contract_runtime::SpeculativeExecutionState, failpoints::FailpointActivation, reactor::{main_reactor::ReactorState, EventQueueHandle, QueueKind}, types::{ @@ -2208,7 +2207,7 @@ impl EffectBuilder { self, execution_prestate: SpeculativeExecutionState, transaction: Box, - ) -> Result, engine_state::Error> + ) -> Result<(ExecutionResultV2, Messages), SpeculativeExecutionError> where REv: From, { diff --git a/node/src/effect/requests.rs b/node/src/effect/requests.rs index 0cf2984f7b..1859391496 100644 --- a/node/src/effect/requests.rs +++ b/node/src/effect/requests.rs @@ -15,7 +15,6 @@ use serde::Serialize; use smallvec::SmallVec; use static_assertions::const_assert; -use casper_execution_engine::engine_state::{self}; use casper_storage::data_access_layer::{ get_bids::{BidsRequest, BidsResult}, AddressableEntityResult, BalanceRequest, BalanceResult, EraValidatorsRequest, @@ -40,6 +39,7 @@ use crate::{ TrieAccumulatorError, TrieAccumulatorResponse, }, consensus::{ClContext, ProposedBlock, ValidatorChange}, + contract_runtime::{SpeculativeExecutionError, SpeculativeExecutionState}, diagnostics_port::StopAtSpec, fetcher::{FetchItem, FetchResult}, gossiper::GossipItem, @@ -47,7 +47,6 @@ use crate::{ transaction_acceptor, upgrade_watcher::NextUpgrade, }, - contract_runtime::SpeculativeExecutionState, reactor::main_reactor::ReactorState, rpcs::docs::OpenRpcSchema, types::{ @@ -960,7 +959,7 @@ pub(crate) enum ContractRuntimeRequest { /// Transaction to execute. transaction: Box, /// Results - responder: Responder, engine_state::Error>>, + responder: Responder>, }, } diff --git a/node/src/reactor/main_reactor.rs b/node/src/reactor/main_reactor.rs index 2cb9001b8a..e5f9f0d3b5 100644 --- a/node/src/reactor/main_reactor.rs +++ b/node/src/reactor/main_reactor.rs @@ -28,7 +28,7 @@ use tracing::{debug, error, info, warn}; use casper_types::{ Block, BlockHash, BlockV2, Chainspec, ChainspecRawBytes, DeployId, EraId, FinalitySignature, FinalitySignatureV2, PublicKey, TimeDiff, Timestamp, Transaction, TransactionHash, - TransactionHeader, TransactionId, U512, + TransactionId, U512, }; #[cfg(test)] @@ -1642,10 +1642,8 @@ impl MainReactor { MetaBlock::Forward(fwd_meta_block) => { for exec_artifact in fwd_meta_block.execution_results.iter() { let event = event_stream_server::Event::TransactionProcessed { - transaction_hash: TransactionHash::Deploy(exec_artifact.deploy_hash), - transaction_header: Box::new(TransactionHeader::Deploy( - exec_artifact.deploy_header.clone(), - )), + transaction_hash: exec_artifact.transaction_hash, + transaction_header: Box::new(exec_artifact.transaction_header.clone()), block_hash: *fwd_meta_block.block.hash(), execution_result: Box::new(exec_artifact.execution_result.clone()), messages: exec_artifact.messages.clone(), diff --git a/node/src/reactor/main_reactor/tests.rs b/node/src/reactor/main_reactor/tests.rs index 6c36a1d0d2..6aefd7fbc9 100644 --- a/node/src/reactor/main_reactor/tests.rs +++ b/node/src/reactor/main_reactor/tests.rs @@ -621,7 +621,7 @@ impl TestFixture { .expect("should have block"); // we need the native auction addr so we can directly call it w/o wasm - // we can get it out of the system contract registry which is just a + // we can get it out of the system entity registry which is just a // value in global state under a stable key. let maybe_registry = reactor .contract_runtime @@ -634,14 +634,14 @@ impl TestFixture { .expect("should not have gs storage error") .expect("should have stored value"); - let system_contract_registry: SystemEntityRegistry = match maybe_registry { + let system_entity_registry: SystemEntityRegistry = match maybe_registry { StoredValue::CLValue(cl_value) => CLValue::into_t(cl_value).unwrap(), _ => { panic!("expected CLValue") } }; - *system_contract_registry.get(system_contract_name).unwrap() + *system_entity_registry.get(system_contract_name).unwrap() } async fn inject_transaction(&mut self, txn: Transaction) { @@ -691,13 +691,11 @@ impl TestFixture { effects.transforms().to_vec() } ExecutionResult::V2(ExecutionResultV2::Failure { - cost, - error_message, - .. + gas, error_message, .. }) => { panic!( - "transaction execution failed: {} cost: {}", - error_message, cost + "transaction execution failed: {} gas: {}", + error_message, gas ); } } diff --git a/node/src/types/appendable_block.rs b/node/src/types/appendable_block.rs index afd0b130a2..fff704af74 100644 --- a/node/src/types/appendable_block.rs +++ b/node/src/types/appendable_block.rs @@ -4,7 +4,6 @@ use std::{ }; use datasize::DataSize; -use num_traits::Zero; use thiserror::Error; use casper_types::{ diff --git a/node/src/types/block/meta_block.rs b/node/src/types/block/meta_block.rs index 37c545ed62..93b38957bd 100644 --- a/node/src/types/block/meta_block.rs +++ b/node/src/types/block/meta_block.rs @@ -171,7 +171,9 @@ impl From for MetaBlock { mod tests { use std::convert::TryInto; - use casper_types::{execution::ExecutionResultV2, testing::TestRng, Deploy, TestBlockBuilder}; + use casper_types::{ + execution::ExecutionResultV2, testing::TestRng, TestBlockBuilder, TransactionV1, + }; use super::*; @@ -180,10 +182,10 @@ mod tests { let rng = &mut TestRng::new(); let block = Arc::new(TestBlockBuilder::new().build(rng)); - let deploy = Deploy::random(rng); + let txn = TransactionV1::random(rng); let execution_results = vec![ExecutionArtifact::new( - *deploy.hash(), - deploy.take_header(), + TransactionHash::V1(*txn.hash()), + TransactionHeader::V1(txn.take_header()), ExecutionResult::from(ExecutionResultV2::random(rng)), Vec::new(), )]; @@ -235,10 +237,10 @@ mod tests { let rng = &mut TestRng::new(); let block = Arc::new(TestBlockBuilder::new().build(rng)); - let deploy = Deploy::random(rng); + let txn = TransactionV1::random(rng); let execution_results = vec![ExecutionArtifact::new( - *deploy.hash(), - deploy.take_header(), + TransactionHash::V1(*txn.hash()), + TransactionHeader::V1(txn.take_header()), ExecutionResult::from(ExecutionResultV2::random(rng)), Vec::new(), )]; @@ -273,10 +275,10 @@ mod tests { .switch_block(true) .build(rng), ); - let deploy = Deploy::random(rng); + let txn = TransactionV1::random(rng); let execution_results = vec![ExecutionArtifact::new( - *deploy.hash(), - deploy.take_header(), + TransactionHash::V1(*txn.hash()), + TransactionHeader::V1(txn.take_header()), ExecutionResult::from(ExecutionResultV2::random(rng)), Vec::new(), )]; @@ -306,17 +308,17 @@ mod tests { let rng = &mut TestRng::new(); let block = Arc::new(TestBlockBuilder::new().build(rng)); - let deploy1 = Deploy::random(rng); + let txn1 = TransactionV1::random(rng); let execution_results1 = vec![ExecutionArtifact::new( - *deploy1.hash(), - deploy1.take_header(), + TransactionHash::V1(*txn1.hash()), + TransactionHeader::V1(txn1.take_header()), ExecutionResult::from(ExecutionResultV2::random(rng)), Vec::new(), )]; - let deploy2 = Deploy::random(rng); + let txn2 = TransactionV1::random(rng); let execution_results2 = vec![ExecutionArtifact::new( - *deploy2.hash(), - deploy2.take_header(), + TransactionHash::V1(*txn2.hash()), + TransactionHeader::V1(txn2.take_header()), ExecutionResult::from(ExecutionResultV2::random(rng)), Vec::new(), )]; diff --git a/node/src/utils/specimen.rs b/node/src/utils/specimen.rs index 9e4dc9f62e..fe95ea7327 100644 --- a/node/src/utils/specimen.rs +++ b/node/src/utils/specimen.rs @@ -27,9 +27,9 @@ use casper_types::{ EraReport, ExecutableDeployItem, FinalitySignature, FinalitySignatureId, FinalitySignatureV2, PackageHash, ProtocolVersion, RewardedSignatures, RuntimeArgs, SecretKey, SemVer, SignedBlockHeader, SingleBlockRewardedSignatures, TimeDiff, Timestamp, Transaction, - TransactionApprovalsHash, TransactionHash, TransactionId, TransactionV1, TransactionV1Approval, - TransactionV1ApprovalsHash, TransactionV1Builder, TransactionV1Hash, URef, KEY_HASH_LENGTH, - U512, + TransactionApprovalsHash, TransactionHash, TransactionId, TransactionSessionKind, + TransactionV1, TransactionV1Approval, TransactionV1ApprovalsHash, TransactionV1Builder, + TransactionV1Hash, URef, KEY_HASH_LENGTH, U512, }; use crate::{ @@ -1000,14 +1000,19 @@ impl LargestSpecimen for TransactionV1Hash { impl LargestSpecimen for TransactionV1 { fn largest_specimen(estimator: &E, cache: &mut Cache) -> Self { - TransactionV1Builder::new_transfer( - LargestSpecimen::largest_specimen(estimator, cache), - LargestSpecimen::largest_specimen(estimator, cache), - U512::largest_specimen(estimator, cache), - LargestSpecimen::largest_specimen(estimator, cache), - LargestSpecimen::largest_specimen(estimator, cache), + // See comment in `impl LargestSpecimen for ExecutableDeployItem` below for rationale here. + let max_size_with_margin = + estimator.parameter::("max_transaction_size").max(0) as usize + 10 * 4; + + TransactionV1Builder::new_session( + TransactionSessionKind::Installer, + Bytes::from(vec_of_largest_specimen( + estimator, + max_size_with_margin, + cache, + )), + "a", ) - .unwrap() .with_secret_key(&LargestSpecimen::largest_specimen(estimator, cache)) .with_timestamp(LargestSpecimen::largest_specimen(estimator, cache)) .with_ttl(LargestSpecimen::largest_specimen(estimator, cache)) diff --git a/resources/local/chainspec.toml.in b/resources/local/chainspec.toml.in index 1e757d342d..d93698ddd2 100644 --- a/resources/local/chainspec.toml.in +++ b/resources/local/chainspec.toml.in @@ -118,13 +118,13 @@ max_ttl = '18 hours' # Maximum transaction size in bytes. Size is of the transaction when serialized via ToBytes. max_transaction_size = 1_048_576 # Maximum number of transfer transactions allowed in a block. -block_max_transfer_count = 1000 +block_max_transfer_count = 500 # Maximum number of staking transactions allowed in a block. -block_max_staking_count = 200 +block_max_staking_count = 100 # Maximum number of installer/upgrader transactions allowed in a block. block_max_install_upgrade_count = 2 # Maximum number of other transactions (non-transfer, non-staking, non-installer/upgrader) allowed in a block. -block_max_standard_count = 100 +block_max_standard_count = 50 # The maximum number of approvals permitted in a single block. block_max_approval_count = 2600 # Maximum block size in bytes including transactions contained by the block. 0 means unlimited. diff --git a/resources/production/chainspec.toml b/resources/production/chainspec.toml index b6cbc099da..d7ff228906 100644 --- a/resources/production/chainspec.toml +++ b/resources/production/chainspec.toml @@ -129,13 +129,13 @@ max_ttl = '18 hours' # Maximum transaction size in bytes. Size is of the transaction when serialized via ToBytes. max_transaction_size = 1_048_576 # Maximum number of transfer transactions allowed in a block. -block_max_transfer_count = 1000 +block_max_transfer_count = 500 # Maximum number of staking transactions allowed in a block. -block_max_staking_count = 200 +block_max_staking_count = 100 # Maximum number of installer/upgrader transactions allowed in a block. block_max_install_upgrade_count = 2 # Maximum number of other transactions (non-transfer, non-staking, non-installer/upgrader) allowed in a block. -block_max_standard_count = 100 +block_max_standard_count = 50 # The maximum number of approvals permitted in a single block. block_max_approval_count = 2600 # Maximum block size in bytes including transactions contained by the block. 0 means unlimited. diff --git a/resources/test/rpc_schema.json b/resources/test/rpc_schema.json index ae85d59387..007976a8c8 100644 --- a/resources/test/rpc_schema.json +++ b/resources/test/rpc_schema.json @@ -166,12 +166,12 @@ "name": "transaction", "value": { "Version1": { - "hash": "6aaf4a54499e3757eb4be6967503dcc431e4623bf8bb57a14c1729a114a1aaa2", + "hash": "fc3c2ad84d579b41d46b0ed187b828404db17a168369af6452713dbcc0d1a0a0", "header": { "chain_name": "casper-example", "timestamp": "2020-11-17T00:39:24.072Z", "ttl": "1h", - "body_hash": "d2433e28993036fbdf7c963cd753893fefe619e7dbb5c0cafa5cb03bcf3ff9db", + "body_hash": "8c36f401d829378219b676ac6cceef90b08171499f5f5726ab5021df46d8b824", "pricing_mode": { "GasPriceMultiplier": 1 }, @@ -185,8 +185,10 @@ [ "source", { - "cl_type": "URef", - "bytes": "0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07", + "cl_type": { + "Option": "URef" + }, + "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07", "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007" } ], @@ -206,18 +208,6 @@ "parsed": "30000000000" } ], - [ - "to", - { - "cl_type": { - "Option": { - "ByteArray": 32 - } - }, - "bytes": "012828282828282828282828282828282828282828282828282828282828282828", - "parsed": "2828282828282828282828282828282828282828282828282828282828282828" - } - ], [ "id", { @@ -236,7 +226,7 @@ "approvals": [ { "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c", - "signature": "012152c1eab67f63faa6a482ec4847ecd145c3b2c3e2affe763303ecb4ccf8618a1b2d24de7313fbf8a2ac1b5256471cc6bbf21745af15516331e5fc3d4a2fa201" + "signature": "014e1ceede22e4182d0d069a269a24ac5a5375de3da9787fafaecb368e48546e3dc52e5ac14e371f6bf13acac919f3eee9f94610c26c69a70e155967a3decc7500" } ] } @@ -248,7 +238,7 @@ "value": { "api_version": "2.0.0", "transaction_hash": { - "Version1": "6aaf4a54499e3757eb4be6967503dcc431e4623bf8bb57a14c1729a114a1aaa2" + "Version1": "fc3c2ad84d579b41d46b0ed187b828404db17a168369af6452713dbcc0d1a0a0" } } } @@ -405,7 +395,7 @@ "transfer-5959595959595959595959595959595959595959595959595959595959595959", "transfer-8282828282828282828282828282828282828282828282828282828282828282" ], - "cost": "123456" + "gas": "123456" } } } @@ -483,7 +473,7 @@ { "name": "transaction_hash", "value": { - "Version1": "6aaf4a54499e3757eb4be6967503dcc431e4623bf8bb57a14c1729a114a1aaa2" + "Version1": "fc3c2ad84d579b41d46b0ed187b828404db17a168369af6452713dbcc0d1a0a0" } }, { @@ -497,12 +487,12 @@ "api_version": "2.0.0", "transaction": { "Version1": { - "hash": "6aaf4a54499e3757eb4be6967503dcc431e4623bf8bb57a14c1729a114a1aaa2", + "hash": "fc3c2ad84d579b41d46b0ed187b828404db17a168369af6452713dbcc0d1a0a0", "header": { "chain_name": "casper-example", "timestamp": "2020-11-17T00:39:24.072Z", "ttl": "1h", - "body_hash": "d2433e28993036fbdf7c963cd753893fefe619e7dbb5c0cafa5cb03bcf3ff9db", + "body_hash": "8c36f401d829378219b676ac6cceef90b08171499f5f5726ab5021df46d8b824", "pricing_mode": { "GasPriceMultiplier": 1 }, @@ -516,8 +506,10 @@ [ "source", { - "cl_type": "URef", - "bytes": "0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07", + "cl_type": { + "Option": "URef" + }, + "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07", "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007" } ], @@ -537,18 +529,6 @@ "parsed": "30000000000" } ], - [ - "to", - { - "cl_type": { - "Option": { - "ByteArray": 32 - } - }, - "bytes": "012828282828282828282828282828282828282828282828282828282828282828", - "parsed": "2828282828282828282828282828282828282828282828282828282828282828" - } - ], [ "id", { @@ -567,7 +547,7 @@ "approvals": [ { "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c", - "signature": "012152c1eab67f63faa6a482ec4847ecd145c3b2c3e2affe763303ecb4ccf8618a1b2d24de7313fbf8a2ac1b5256471cc6bbf21745af15516331e5fc3d4a2fa201" + "signature": "014e1ceede22e4182d0d069a269a24ac5a5375de3da9787fafaecb368e48546e3dc52e5ac14e371f6bf13acac919f3eee9f94610c26c69a70e155967a3decc7500" } ] } @@ -593,7 +573,7 @@ "transfer-5959595959595959595959595959595959595959595959595959595959595959", "transfer-8282828282828282828282828282828282828282828282828282828282828282" ], - "cost": "123456" + "gas": "123456" } } } @@ -1539,14 +1519,18 @@ "block_hash": "0707070707070707070707070707070707070707070707070707070707070707", "transfers": [ { - "deploy_hash": "0000000000000000000000000000000000000000000000000000000000000000", - "from": "account-hash-0000000000000000000000000000000000000000000000000000000000000000", - "to": null, - "source": "uref-0000000000000000000000000000000000000000000000000000000000000000-000", - "target": "uref-0000000000000000000000000000000000000000000000000000000000000000-000", - "amount": "0", - "gas": "0", - "id": null + "transaction_hash": { + "Version1": "0909090909090909090909090909090909090909090909090909090909090909" + }, + "from": { + "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c" + }, + "to": "account-hash-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a", + "source": "uref-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b-007", + "target": "uref-0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c-000", + "amount": "3000000000", + "gas": "2500000000", + "id": 9 } ] } @@ -4016,31 +4000,31 @@ "type": "object", "required": [ "amount", - "deploy_hash", "from", "gas", "source", - "target" + "target", + "transaction_hash" ], "properties": { - "deploy_hash": { - "description": "Hex-encoded Deploy hash of Deploy that created the transfer.", + "transaction_hash": { + "description": "Transaction that created the transfer.", "allOf": [ { - "$ref": "#/components/schemas/DeployHash" + "$ref": "#/components/schemas/TransactionHash" } ] }, "from": { - "description": "Account from which transfer was executed", + "description": "Entity from which transfer was executed.", "allOf": [ { - "$ref": "#/components/schemas/AccountHash" + "$ref": "#/components/schemas/InitiatorAddr" } ] }, "to": { - "description": "Account to which funds are transferred", + "description": "Account to which funds are transferred.", "anyOf": [ { "$ref": "#/components/schemas/AccountHash" @@ -4051,7 +4035,7 @@ ] }, "source": { - "description": "Source purse", + "description": "Source purse.", "allOf": [ { "$ref": "#/components/schemas/URef" @@ -4059,7 +4043,7 @@ ] }, "target": { - "description": "Target purse", + "description": "Target purse.", "allOf": [ { "$ref": "#/components/schemas/URef" @@ -4067,7 +4051,7 @@ ] }, "amount": { - "description": "Transfer amount", + "description": "Transfer amount.", "allOf": [ { "$ref": "#/components/schemas/U512" @@ -4075,15 +4059,15 @@ ] }, "gas": { - "description": "Gas", + "description": "Gas.", "allOf": [ { - "$ref": "#/components/schemas/U512" + "$ref": "#/components/schemas/Gas" } ] }, "id": { - "description": "User-defined id", + "description": "User-defined ID.", "type": [ "integer", "null" @@ -4094,6 +4078,14 @@ }, "additionalProperties": false }, + "Gas": { + "description": "The `Gas` struct represents a `U512` amount of gas.", + "allOf": [ + { + "$ref": "#/components/schemas/U512" + } + ] + }, "Bid": { "description": "An entry in the validator map.", "type": "object", @@ -4508,7 +4500,7 @@ "additionalProperties": false }, "ExecutionResultV2": { - "description": "The result of executing a single deploy.", + "description": "The result of executing a single transaction.", "oneOf": [ { "description": "The result of a failed execution.", @@ -4520,14 +4512,14 @@ "Failure": { "type": "object", "required": [ - "cost", "effects", "error_message", + "gas", "transfers" ], "properties": { "effects": { - "description": "The effects of executing the deploy.", + "description": "The effects of executing the transaction.", "allOf": [ { "$ref": "#/components/schemas/Effects" @@ -4535,22 +4527,22 @@ ] }, "transfers": { - "description": "A record of transfers performed while executing the deploy.", + "description": "A record of transfers performed while executing the transaction.", "type": "array", "items": { "$ref": "#/components/schemas/TransferAddr" } }, - "cost": { - "description": "The cost in Motes of executing the deploy.", + "gas": { + "description": "The gas consumed executing the transaction.", "allOf": [ { - "$ref": "#/components/schemas/U512" + "$ref": "#/components/schemas/Gas" } ] }, "error_message": { - "description": "The error message associated with executing the deploy.", + "description": "The error message associated with executing the transaction.", "type": "string" } }, @@ -4569,13 +4561,13 @@ "Success": { "type": "object", "required": [ - "cost", "effects", + "gas", "transfers" ], "properties": { "effects": { - "description": "The effects of executing the deploy.", + "description": "The effects of executing the transaction.", "allOf": [ { "$ref": "#/components/schemas/Effects" @@ -4583,17 +4575,17 @@ ] }, "transfers": { - "description": "A record of transfers performed while executing the deploy.", + "description": "A record of transfers performed while executing the transaction.", "type": "array", "items": { "$ref": "#/components/schemas/TransferAddr" } }, - "cost": { - "description": "The cost in Motes of executing the deploy.", + "gas": { + "description": "The gas consumed executing the transaction.", "allOf": [ { - "$ref": "#/components/schemas/U512" + "$ref": "#/components/schemas/Gas" } ] } @@ -5132,6 +5124,19 @@ } }, "additionalProperties": false + }, + { + "description": "Info about a transaction.", + "type": "object", + "required": [ + "TransactionInfo" + ], + "properties": { + "TransactionInfo": { + "$ref": "#/components/schemas/TransactionInfo" + } + }, + "additionalProperties": false } ] }, @@ -5812,6 +5817,59 @@ } } }, + "TransactionInfo": { + "description": "Information relating to the given Transaction, stored in global state under .", + "type": "object", + "required": [ + "from", + "gas", + "source", + "transaction_hash", + "transfers" + ], + "properties": { + "transaction_hash": { + "description": "The transaction hash.", + "allOf": [ + { + "$ref": "#/components/schemas/TransactionHash" + } + ] + }, + "transfers": { + "description": "Transfers done during execution of the transaction.", + "type": "array", + "items": { + "$ref": "#/components/schemas/TransferAddr" + } + }, + "from": { + "description": "Identifier of the initiator of the transaction.", + "allOf": [ + { + "$ref": "#/components/schemas/InitiatorAddr" + } + ] + }, + "source": { + "description": "Source purse used for payment of the transaction.", + "allOf": [ + { + "$ref": "#/components/schemas/URef" + } + ] + }, + "gas": { + "description": "Gas used in executing the transaction.", + "allOf": [ + { + "$ref": "#/components/schemas/Gas" + } + ] + } + }, + "additionalProperties": false + }, "GlobalStateIdentifier": { "description": "Identifier for possible ways to query Global State", "oneOf": [ diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index 8e31497428..7f4fa5f75a 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -2742,31 +2742,31 @@ "type": "object", "required": [ "amount", - "deploy_hash", "from", "gas", "source", - "target" + "target", + "transaction_hash" ], "properties": { - "deploy_hash": { - "description": "Hex-encoded Deploy hash of Deploy that created the transfer.", + "transaction_hash": { + "description": "Transaction that created the transfer.", "allOf": [ { - "$ref": "#/definitions/DeployHash" + "$ref": "#/definitions/TransactionHash" } ] }, "from": { - "description": "Account from which transfer was executed", + "description": "Entity from which transfer was executed.", "allOf": [ { - "$ref": "#/definitions/AccountHash" + "$ref": "#/definitions/InitiatorAddr" } ] }, "to": { - "description": "Account to which funds are transferred", + "description": "Account to which funds are transferred.", "anyOf": [ { "$ref": "#/definitions/AccountHash" @@ -2777,7 +2777,7 @@ ] }, "source": { - "description": "Source purse", + "description": "Source purse.", "allOf": [ { "$ref": "#/definitions/URef" @@ -2785,7 +2785,7 @@ ] }, "target": { - "description": "Target purse", + "description": "Target purse.", "allOf": [ { "$ref": "#/definitions/URef" @@ -2793,7 +2793,7 @@ ] }, "amount": { - "description": "Transfer amount", + "description": "Transfer amount.", "allOf": [ { "$ref": "#/definitions/U512" @@ -2801,15 +2801,15 @@ ] }, "gas": { - "description": "Gas", + "description": "Gas.", "allOf": [ { - "$ref": "#/definitions/U512" + "$ref": "#/definitions/Gas" } ] }, "id": { - "description": "User-defined id", + "description": "User-defined ID.", "type": [ "integer", "null" @@ -2820,6 +2820,14 @@ }, "additionalProperties": false }, + "Gas": { + "description": "The `Gas` struct represents a `U512` amount of gas.", + "allOf": [ + { + "$ref": "#/definitions/U512" + } + ] + }, "Bid": { "description": "An entry in the validator map.", "type": "object", @@ -3234,7 +3242,7 @@ "additionalProperties": false }, "ExecutionResultV2": { - "description": "The result of executing a single deploy.", + "description": "The result of executing a single transaction.", "oneOf": [ { "description": "The result of a failed execution.", @@ -3246,14 +3254,14 @@ "Failure": { "type": "object", "required": [ - "cost", "effects", "error_message", + "gas", "transfers" ], "properties": { "effects": { - "description": "The effects of executing the deploy.", + "description": "The effects of executing the transaction.", "allOf": [ { "$ref": "#/definitions/Effects" @@ -3261,22 +3269,22 @@ ] }, "transfers": { - "description": "A record of transfers performed while executing the deploy.", + "description": "A record of transfers performed while executing the transaction.", "type": "array", "items": { "$ref": "#/definitions/TransferAddr" } }, - "cost": { - "description": "The cost in Motes of executing the deploy.", + "gas": { + "description": "The gas consumed executing the transaction.", "allOf": [ { - "$ref": "#/definitions/U512" + "$ref": "#/definitions/Gas" } ] }, "error_message": { - "description": "The error message associated with executing the deploy.", + "description": "The error message associated with executing the transaction.", "type": "string" } }, @@ -3295,13 +3303,13 @@ "Success": { "type": "object", "required": [ - "cost", "effects", + "gas", "transfers" ], "properties": { "effects": { - "description": "The effects of executing the deploy.", + "description": "The effects of executing the transaction.", "allOf": [ { "$ref": "#/definitions/Effects" @@ -3309,17 +3317,17 @@ ] }, "transfers": { - "description": "A record of transfers performed while executing the deploy.", + "description": "A record of transfers performed while executing the transaction.", "type": "array", "items": { "$ref": "#/definitions/TransferAddr" } }, - "cost": { - "description": "The cost in Motes of executing the deploy.", + "gas": { + "description": "The gas consumed executing the transaction.", "allOf": [ { - "$ref": "#/definitions/U512" + "$ref": "#/definitions/Gas" } ] } diff --git a/smart_contracts/contract/src/contract_api/runtime.rs b/smart_contracts/contract/src/contract_api/runtime.rs index abd69f436e..1eadc136c0 100644 --- a/smart_contracts/contract/src/contract_api/runtime.rs +++ b/smart_contracts/contract/src/contract_api/runtime.rs @@ -9,10 +9,10 @@ use casper_types::{ api_error, bytesrepr::{self, FromBytes}, contract_messages::{MessagePayload, MessageTopicOperation}, - package::EntityVersion, system::Caller, - AddressableEntityHash, ApiError, BlockTime, CLTyped, CLValue, Key, PackageHash, Phase, - RuntimeArgs, URef, BLAKE2B_DIGEST_LENGTH, BLOCKTIME_SERIALIZED_LENGTH, PHASE_SERIALIZED_LENGTH, + AddressableEntityHash, ApiError, BlockTime, CLTyped, CLValue, EntityVersion, Key, PackageHash, + Phase, RuntimeArgs, URef, BLAKE2B_DIGEST_LENGTH, BLOCKTIME_SERIALIZED_LENGTH, + PHASE_SERIALIZED_LENGTH, }; use crate::{contract_api, ext_ffi, unwrap_or_revert::UnwrapOrRevert}; diff --git a/smart_contracts/contract/src/contract_api/storage.rs b/smart_contracts/contract/src/contract_api/storage.rs index ca8f63bc57..db8bc8dc51 100644 --- a/smart_contracts/contract/src/contract_api/storage.rs +++ b/smart_contracts/contract/src/contract_api/storage.rs @@ -7,9 +7,8 @@ use casper_types::{ addressable_entity::{EntryPoints, NamedKeys}, api_error, bytesrepr::{self, FromBytes, ToBytes}, - package::EntityVersion, - AccessRights, AddressableEntityHash, ApiError, CLTyped, CLValue, HashAddr, Key, PackageHash, - URef, DICTIONARY_ITEM_KEY_MAX_LENGTH, UREF_SERIALIZED_LENGTH, + AccessRights, AddressableEntityHash, ApiError, CLTyped, CLValue, EntityVersion, HashAddr, Key, + PackageHash, URef, DICTIONARY_ITEM_KEY_MAX_LENGTH, UREF_SERIALIZED_LENGTH, }; use crate::{ diff --git a/smart_contracts/contracts/test/contract-context/src/main.rs b/smart_contracts/contracts/test/contract-context/src/main.rs index b959d6caf3..b8351ba18f 100644 --- a/smart_contracts/contracts/test/contract-context/src/main.rs +++ b/smart_contracts/contracts/test/contract-context/src/main.rs @@ -11,8 +11,8 @@ use casper_contract::{ }; use casper_types::{ addressable_entity::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys}, - package::ENTITY_INITIAL_VERSION, runtime_args, AddressableEntityHash, CLType, EntityVersion, Key, PackageHash, + ENTITY_INITIAL_VERSION, }; const PACKAGE_HASH_KEY: &str = "package_hash_key"; diff --git a/smart_contracts/contracts/test/do-nothing-stored-caller/src/main.rs b/smart_contracts/contracts/test/do-nothing-stored-caller/src/main.rs index 98a775116e..aa8fd582c1 100644 --- a/smart_contracts/contracts/test/do-nothing-stored-caller/src/main.rs +++ b/smart_contracts/contracts/test/do-nothing-stored-caller/src/main.rs @@ -6,7 +6,7 @@ extern crate alloc; use alloc::string::String; use casper_contract::contract_api::runtime; -use casper_types::{package::EntityVersion, runtime_args, PackageHash}; +use casper_types::{runtime_args, EntityVersion, PackageHash}; const ENTRY_FUNCTION_NAME: &str = "delegate"; const PURSE_NAME_ARG_NAME: &str = "purse_name"; diff --git a/smart_contracts/contracts/test/groups/src/main.rs b/smart_contracts/contracts/test/groups/src/main.rs index a647b56280..f31d7a756f 100644 --- a/smart_contracts/contracts/test/groups/src/main.rs +++ b/smart_contracts/contracts/test/groups/src/main.rs @@ -12,10 +12,9 @@ use casper_contract::{ }; use casper_types::{ addressable_entity::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys}, - package::ENTITY_INITIAL_VERSION, runtime_args, system::{handle_payment, standard_payment}, - CLType, CLTyped, Key, PackageHash, Parameter, RuntimeArgs, URef, U512, + CLType, CLTyped, Key, PackageHash, Parameter, RuntimeArgs, URef, ENTITY_INITIAL_VERSION, U512, }; const PACKAGE_HASH_KEY: &str = "package_hash_key"; diff --git a/storage/src/data_access_layer.rs b/storage/src/data_access_layer.rs index 6944116db9..89f5e18309 100644 --- a/storage/src/data_access_layer.rs +++ b/storage/src/data_access_layer.rs @@ -10,6 +10,7 @@ use crate::tracking_copy::TrackingCopy; mod addressable_entity; pub mod balance; pub mod era_validators; +mod execute; mod execution_results_checksum; mod flush; mod genesis; diff --git a/storage/src/data_access_layer/execute.rs b/storage/src/data_access_layer/execute.rs new file mode 100644 index 0000000000..e9889caaaa --- /dev/null +++ b/storage/src/data_access_layer/execute.rs @@ -0,0 +1,123 @@ +use std::collections::BTreeSet; + +use serde::Serialize; +use thiserror::Error; + +use casper_types::{ + account::AccountHash, BlockTime, DeployHash, Digest, ExecutableDeployItem, InitiatorAddr, + PublicKey, RuntimeArgs, Transaction, TransactionEntryPoint, TransactionHash, +}; + +/// Error returned if constructing a new [`ExecuteNativeRequest`] fails. +#[derive(Clone, Eq, PartialEq, Error, Serialize, Debug)] +pub enum NewNativeRequestError { + /// Attempted to construct an [`ExecuteNativeRequest`] from a deploy which is not a transfer. + #[error("deploy must be a transfer for native execution: {0}")] + ExpectedTransferDeploy(DeployHash), + /// Attempted to construct an [`ExecuteNativeRequest`] from a transaction with an invalid entry + /// point. + #[error( + "cannot use custom entry point '{entry_point}' for native execution: {transaction_hash}" + )] + InvalidEntryPoint { + transaction_hash: TransactionHash, + entry_point: String, + }, +} + +/// The entry point of the native contract to call. +#[derive(Debug)] +pub enum NativeEntryPoint { + /// The `transfer` entry point, used to transfer `Motes` from a source purse to a target purse. + Transfer, + /// The `add_bid` entry point, used to create or top off a bid purse. + AddBid, + /// The `withdraw_bid` entry point, used to decrease a stake. + WithdrawBid, + /// The `delegate` entry point, used to add a new delegator or increase an existing delegator's + /// stake. + Delegate, + /// The `undelegate` entry point, used to reduce a delegator's stake or remove the delegator if + /// the remaining stake is 0. + Undelegate, + /// The `redelegate` entry point, used to reduce a delegator's stake or remove the delegator if + /// the remaining stake is 0, and after the unbonding delay, automatically delegate to a new + /// validator. + Redelegate, +} + +/// A request to execute the given native transaction. +#[derive(Debug)] +pub struct ExecuteNativeRequest { + /// State root hash of the global state in which the transaction will be executed. + pub parent_state_hash: Digest, + /// Block time represented as a unix timestamp. + pub block_time: BlockTime, + /// The hash identifying the transaction. + pub transaction_hash: TransactionHash, + /// The native contract entry point to call. + pub entry_point: NativeEntryPoint, + /// The runtime args to be used in execution. + pub args: RuntimeArgs, + /// The transaction's initiator. + pub initiator_addr: InitiatorAddr, + /// The account hashes of the signers of the transaction. + pub authorization_keys: BTreeSet, + /// The owner of the node that proposed the block containing this request. + pub proposer: PublicKey, +} + +impl ExecuteNativeRequest { + /// Creates a new execute request. + pub fn new( + parent_state_hash: Digest, + block_time: BlockTime, + txn: Transaction, + proposer: PublicKey, + ) -> Result { + let transaction_hash = txn.hash(); + let initiator_addr = txn.initiator_addr(); + let authorization_keys = txn.signers(); + let entry_point: NativeEntryPoint; + let args: RuntimeArgs; + match txn { + Transaction::Deploy(deploy) => { + let (deploy_hash, _header, _payment, session, _approvals) = deploy.destructure(); + args = match session { + ExecutableDeployItem::Transfer { args } => args, + _ => { + return Err(NewNativeRequestError::ExpectedTransferDeploy(deploy_hash)); + } + }; + entry_point = NativeEntryPoint::Transfer; + } + Transaction::V1(v1_txn) => { + entry_point = match v1_txn.entry_point() { + TransactionEntryPoint::Custom(entry_point) => { + return Err(NewNativeRequestError::InvalidEntryPoint { + transaction_hash, + entry_point: entry_point.clone(), + }) + } + TransactionEntryPoint::Transfer => NativeEntryPoint::Transfer, + TransactionEntryPoint::AddBid => NativeEntryPoint::AddBid, + TransactionEntryPoint::WithdrawBid => NativeEntryPoint::WithdrawBid, + TransactionEntryPoint::Delegate => NativeEntryPoint::Delegate, + TransactionEntryPoint::Undelegate => NativeEntryPoint::Undelegate, + TransactionEntryPoint::Redelegate => NativeEntryPoint::Redelegate, + }; + args = v1_txn.take_args(); + } + }; + Ok(Self { + parent_state_hash, + block_time, + transaction_hash, + entry_point, + args, + initiator_addr, + authorization_keys, + proposer, + }) + } +} diff --git a/storage/src/global_state/state/mod.rs b/storage/src/global_state/state/mod.rs index 69ebe7c875..318d04e9f0 100644 --- a/storage/src/global_state/state/mod.rs +++ b/storage/src/global_state/state/mod.rs @@ -259,8 +259,7 @@ pub trait CommitProvider: StateProvider { &administrative_accounts, ) { Ok((entity, entity_hash)) => { - let entity_addr = - EntityAddr::new_with_tag(entity.entity_kind(), entity_hash.value()); + let entity_addr = EntityAddr::new_of_kind(entity.kind(), entity_hash.value()); (entity, entity_addr) } Err(tce) => return TransferResult::Failure(TransferError::TrackingCopy(tce)), diff --git a/storage/src/system/error.rs b/storage/src/system/error.rs index 6c18a2af9d..8fc7058bf0 100644 --- a/storage/src/system/error.rs +++ b/storage/src/system/error.rs @@ -3,6 +3,6 @@ use casper_types::account::AccountHash; /// Implementation level errors for system contract providers #[derive(Debug)] pub enum ProviderError { - SystemContractRegistry, + SystemEntityRegistry, AddressableEntityByAccountHash(AccountHash), } diff --git a/storage/src/system/genesis.rs b/storage/src/system/genesis.rs index fee953b703..b057ee464c 100644 --- a/storage/src/system/genesis.rs +++ b/storage/src/system/genesis.rs @@ -24,7 +24,6 @@ use casper_types::{ }, bytesrepr, execution::Effects, - package::{EntityVersions, Groups, PackageStatus}, system::{ auction::{ self, BidAddr, BidKind, DelegationRate, Delegator, SeigniorageRecipient, @@ -39,10 +38,10 @@ use casper_types::{ }, AccessRights, AddressableEntity, AddressableEntityHash, AdministratorAccount, ByteCode, ByteCodeAddr, ByteCodeHash, ByteCodeKind, CLValue, Chainspec, ChainspecRegistry, Digest, - EntityAddr, EntryPoints, EraId, FeeHandling, GenesisAccount, GenesisConfig, - GenesisConfigBuilder, Key, Motes, Package, PackageHash, Phase, ProtocolVersion, PublicKey, - RefundHandling, StoredValue, SystemConfig, SystemEntityRegistry, Tagged, URef, WasmConfig, - U512, + EntityAddr, EntityVersions, EntryPoints, EraId, FeeHandling, GenesisAccount, GenesisConfig, + GenesisConfigBuilder, Groups, Key, Motes, Package, PackageHash, PackageStatus, Phase, + ProtocolVersion, PublicKey, RefundHandling, StoredValue, SystemConfig, SystemEntityRegistry, + Tagged, URef, WasmConfig, U512, }; use crate::{ @@ -288,7 +287,7 @@ where EntityKind::System(SystemEntityType::HandlePayment), )?; - self.store_system_contract_registry(HANDLE_PAYMENT, contract_hash)?; + self.store_system_entity_registry(HANDLE_PAYMENT, contract_hash)?; Ok(contract_hash) } @@ -556,7 +555,7 @@ where EntityKind::System(SystemEntityType::Auction), )?; - self.store_system_contract_registry(AUCTION, contract_hash)?; + self.store_system_entity_registry(AUCTION, contract_hash)?; Ok(contract_hash) } @@ -750,11 +749,9 @@ where .write(byte_code_key, StoredValue::ByteCode(byte_code)); let entity_addr = match entity_kind.tag() { - EntityKindTag::System => EntityAddr::new_system_entity_addr(entity_hash.value()), - EntityKindTag::Account => EntityAddr::new_account_entity_addr(entity_hash.value()), - EntityKindTag::SmartContract => { - EntityAddr::new_contract_entity_addr(entity_hash.value()) - } + EntityKindTag::System => EntityAddr::new_system(entity_hash.value()), + EntityKindTag::Account => EntityAddr::new_account(entity_hash.value()), + EntityKindTag::SmartContract => EntityAddr::new_smart_contract(entity_hash.value()), }; let entity_key: Key = entity_addr.into(); @@ -785,7 +782,7 @@ where contract_hash: AddressableEntityHash, named_keys: NamedKeys, ) -> Result<(), Box> { - let entity_addr = EntityAddr::new_system_entity_addr(contract_hash.value()); + let entity_addr = EntityAddr::new_system(contract_hash.value()); for (string, key) in named_keys.iter() { let named_key_entry = NamedKeyAddr::new_from_string(entity_addr, string.clone()) @@ -804,7 +801,7 @@ where Ok(()) } - fn store_system_contract_registry( + fn store_system_entity_registry( &self, contract_name: &str, contract_hash: AddressableEntityHash, diff --git a/storage/src/system/mint/mint_native.rs b/storage/src/system/mint/mint_native.rs index 8c7c30198a..b5de5d1ec5 100644 --- a/storage/src/system/mint/mint_native.rs +++ b/storage/src/system/mint/mint_native.rs @@ -20,8 +20,8 @@ use casper_types::{ bytesrepr::{FromBytes, ToBytes}, system::{mint::Error, Caller}, AccessRights, AddressableEntity, CLTyped, CLValue, ContextAccessRights, DeployHash, Digest, - Key, Phase, ProtocolVersion, PublicKey, StoredValue, SystemEntityRegistry, Transfer, - TransferAddr, URef, U512, + Gas, InitiatorAddr, Key, Phase, ProtocolVersion, PublicKey, StoredValue, SystemEntityRegistry, + TransactionHash, Transfer, TransferAddr, URef, U512, }; pub struct NativeMintRuntime { @@ -105,8 +105,8 @@ where .borrow_mut() .get_system_entity_registry() .map_err(|tce| { - error!(%tce, "unable to obtain system contract registry during transfer"); - ProviderError::SystemContractRegistry + error!(%tce, "unable to obtain system entity registry during transfer"); + ProviderError::SystemEntityRegistry }) } @@ -276,9 +276,9 @@ where let transfer = { // the below line is incorrect; new transaction hash is not currently supported here // ...the transfer struct needs to be upgraded to TransactionHash - let deploy_hash = DeployHash::new(transaction_hash); - let from: AccountHash = self.get_caller(); - let fee: U512 = U512::zero(); + let deploy_hash = TransactionHash::Deploy(DeployHash::new(transaction_hash)); + let from = InitiatorAddr::AccountHash(self.get_caller()); + let fee = Gas::zero(); Transfer::new(deploy_hash, from, maybe_to, source, target, amount, fee, id) }; { diff --git a/storage/src/system/mint/runtime_provider.rs b/storage/src/system/mint/runtime_provider.rs index 8ade0171ec..b20b46491b 100644 --- a/storage/src/system/mint/runtime_provider.rs +++ b/storage/src/system/mint/runtime_provider.rs @@ -14,7 +14,7 @@ pub trait RuntimeProvider { fn is_called_from_standard_payment(&self) -> bool; - /// Get system contract registry. + /// Get system entity registry. fn get_system_entity_registry(&self) -> Result; fn read_addressable_entity_by_account_hash( diff --git a/storage/src/system/protocol_upgrade.rs b/storage/src/system/protocol_upgrade.rs index ed37c65e85..57e7226e5a 100644 --- a/storage/src/system/protocol_upgrade.rs +++ b/storage/src/system/protocol_upgrade.rs @@ -12,7 +12,6 @@ use casper_types::{ }, bytesrepr::{self, ToBytes}, execution::Effects, - package::{EntityVersions, Groups, PackageStatus}, system::{ auction::{ BidAddr, BidKind, ValidatorBid, AUCTION_DELAY_KEY, LOCKED_FUNDS_PERIOD_KEY, @@ -23,9 +22,10 @@ use casper_types::{ SystemEntityType, AUCTION, HANDLE_PAYMENT, MINT, }, AccessRights, AddressableEntity, AddressableEntityHash, ByteCode, ByteCodeAddr, ByteCodeHash, - ByteCodeKind, CLValue, CLValueError, Digest, EntityAddr, EntryPoints, FeeHandling, Key, KeyTag, - Package, PackageHash, Phase, ProtocolUpgradeConfig, ProtocolVersion, PublicKey, StoredValue, - SystemEntityRegistry, URef, U512, + ByteCodeKind, CLValue, CLValueError, Digest, EntityAddr, EntityVersions, EntryPoints, + FeeHandling, Groups, Key, KeyTag, Package, PackageHash, PackageStatus, Phase, + ProtocolUpgradeConfig, ProtocolVersion, PublicKey, StoredValue, SystemEntityRegistry, URef, + U512, }; use crate::{ @@ -73,8 +73,8 @@ pub enum ProtocolUpgradeError { /// (De)serialization error. #[error("Bytesrepr error: {0}")] Bytesrepr(String), - /// Failed to create system contract registry. - #[error("Failed to insert system contract registry")] + /// Failed to create system entity registry. + #[error("Failed to insert system entity registry")] FailedToCreateSystemRegistry, /// Found unexpected variant of a stored value. #[error("Unexpected stored value variant")] @@ -206,8 +206,8 @@ where } } - fn system_contract_registry(&self) -> Result { - debug!("system contract registry"); + fn system_entity_registry(&self) -> Result { + debug!("system entity registry"); let registry = if let Ok(registry) = self.tracking_copy.borrow_mut().get_system_entity_registry() { @@ -240,7 +240,7 @@ where /// Handle system entities. pub fn handle_system_entities(&self) -> Result { debug!("handle system entities"); - let mut registry = self.system_contract_registry()?; + let mut registry = self.system_entity_registry()?; let mint = *registry.get(MINT).ok_or_else(|| { error!("Missing system mint entity hash"); @@ -355,7 +355,7 @@ where .write(entity_key, StoredValue::AddressableEntity(new_entity)); if let Some(named_keys) = maybe_named_keys { - let entity_addr = EntityAddr::new_system_entity_addr(contract_hash.value()); + let entity_addr = EntityAddr::new_system(contract_hash.value()); for (string, key) in named_keys.into_inner().into_iter() { let entry_addr = NamedKeyAddr::new_from_string(entity_addr, string.clone()) @@ -446,7 +446,7 @@ where if let Some(StoredValue::AddressableEntity(system_entity)) = self .tracking_copy .borrow_mut() - .read(&Key::AddressableEntity(EntityAddr::new_system_entity_addr( + .read(&Key::AddressableEntity(EntityAddr::new_system( contract_hash.value(), ))) .map_err(|_| { @@ -598,7 +598,7 @@ where let (addressable_entity, maybe_named_keys, _) = self.retrieve_system_entity(*handle_payment_hash, system_contract)?; - let entity_addr = EntityAddr::new_system_entity_addr(handle_payment_hash.value()); + let entity_addr = EntityAddr::new_system(handle_payment_hash.value()); if let Some(named_keys) = maybe_named_keys { for (string, key) in named_keys.into_inner().into_iter() { @@ -669,7 +669,7 @@ where if let Some(new_validator_slots) = self.config.new_validator_slots() { debug!(%new_validator_slots, "handle new validator slots"); // if new total validator slots is provided, update auction contract state - let auction_addr = EntityAddr::new_system_entity_addr(auction.value()); + let auction_addr = EntityAddr::new_system(auction.value()); let auction_named_keys = self .tracking_copy .borrow_mut() @@ -695,7 +695,7 @@ where ) -> Result<(), ProtocolUpgradeError> { if let Some(new_auction_delay) = self.config.new_auction_delay() { debug!(%new_auction_delay, "handle new auction delay"); - let auction_addr = EntityAddr::new_system_entity_addr(auction.value()); + let auction_addr = EntityAddr::new_system(auction.value()); let auction_named_keys = self .tracking_copy @@ -722,7 +722,7 @@ where ) -> Result<(), ProtocolUpgradeError> { if let Some(new_locked_funds_period) = self.config.new_locked_funds_period_millis() { debug!(%new_locked_funds_period,"handle new locked funds period millis"); - let auction_addr = EntityAddr::new_system_entity_addr(auction.value()); + let auction_addr = EntityAddr::new_system(auction.value()); let auction_named_keys = self .tracking_copy @@ -751,7 +751,7 @@ where // based on the previous unbonding delay. if let Some(new_unbonding_delay) = self.config.new_unbonding_delay() { debug!(%new_unbonding_delay,"handle new unbonding delay"); - let auction_addr = EntityAddr::new_system_entity_addr(auction.value()); + let auction_addr = EntityAddr::new_system(auction.value()); let auction_named_keys = self .tracking_copy @@ -783,7 +783,7 @@ where Ratio::new(numer.into(), denom.into()) }; - let mint_addr = EntityAddr::new_system_entity_addr(mint.value()); + let mint_addr = EntityAddr::new_system(mint.value()); let mint_named_keys = self.tracking_copy.borrow_mut().get_named_keys(mint_addr)?; diff --git a/storage/src/tracking_copy/byte_size.rs b/storage/src/tracking_copy/byte_size.rs index ce45d6cebc..43f4829637 100644 --- a/storage/src/tracking_copy/byte_size.rs +++ b/storage/src/tracking_copy/byte_size.rs @@ -47,6 +47,7 @@ impl ByteSize for StoredValue { } StoredValue::Message(message_summary) => message_summary.serialized_length(), StoredValue::NamedKey(named_key) => named_key.serialized_length(), + StoredValue::TransactionInfo(info) => info.serialized_length(), } } } diff --git a/storage/src/tracking_copy/error.rs b/storage/src/tracking_copy/error.rs index fc4138bbaa..877e6fc0bc 100644 --- a/storage/src/tracking_copy/error.rs +++ b/storage/src/tracking_copy/error.rs @@ -144,9 +144,9 @@ pub enum Error { /// Error writing a dictionary item key which exceeded maximum allowed length. #[error("Dictionary item key exceeded maximum length")] DictionaryItemKeyExceedsLength, - /// Missing system contract registry. - #[error("Missing system contract registry")] - MissingSystemContractRegistry, + /// Missing system entity registry. + #[error("Missing system entity registry")] + MissingSystemEntityRegistry, /// Missing system contract hash. #[error("Missing system contract hash: {0}")] MissingSystemContractHash(String), diff --git a/storage/src/tracking_copy/ext.rs b/storage/src/tracking_copy/ext.rs index 0e59d5c98d..35a0db0bd8 100644 --- a/storage/src/tracking_copy/ext.rs +++ b/storage/src/tracking_copy/ext.rs @@ -44,7 +44,7 @@ pub trait TrackingCopyExt { /// Gets a package by hash. fn get_package(&mut self, package_hash: PackageHash) -> Result; - /// Gets the system contract registry. + /// Gets the system entity registry. fn get_system_entity_registry(&mut self) -> Result; /// Gets the system checksum registry. diff --git a/storage/src/tracking_copy/ext_entity.rs b/storage/src/tracking_copy/ext_entity.rs index 827a2c0d58..994cb784f6 100644 --- a/storage/src/tracking_copy/ext_entity.rs +++ b/storage/src/tracking_copy/ext_entity.rs @@ -6,11 +6,9 @@ use casper_types::{ ActionThresholds, AssociatedKeys, EntityKindTag, MessageTopics, NamedKeyAddr, NamedKeyValue, NamedKeys, Weight, }, - bytesrepr, - package::{EntityVersions, Groups, PackageStatus}, - AccessRights, Account, AddressableEntity, AddressableEntityHash, ByteCodeHash, CLValue, - EntityAddr, EntityKind, EntryPoints, Key, Package, PackageHash, Phase, ProtocolVersion, - StoredValue, StoredValueTypeMismatch, + bytesrepr, AccessRights, Account, AddressableEntity, AddressableEntityHash, ByteCodeHash, + CLValue, EntityAddr, EntityKind, EntityVersions, EntryPoints, Groups, Key, Package, + PackageHash, PackageStatus, Phase, ProtocolVersion, StoredValue, StoredValueTypeMismatch, }; use crate::{ @@ -328,7 +326,7 @@ where .map_err(Self::Error::SetThresholdFailure)? }; - let entity_addr = EntityAddr::new_account_entity_addr(entity_hash.value()); + let entity_addr = EntityAddr::new_account(entity_hash.value()); self.migrate_named_keys(entity_addr, account.named_keys().clone())?; diff --git a/storage/src/tracking_copy/mod.rs b/storage/src/tracking_copy/mod.rs index 218b6c8cf7..b16d58e034 100644 --- a/storage/src/tracking_copy/mod.rs +++ b/storage/src/tracking_copy/mod.rs @@ -659,6 +659,9 @@ where StoredValue::Message(_) => { return Ok(query.into_not_found_result("Message value found.")); } + StoredValue::TransactionInfo(_) => { + return Ok(query.into_not_found_result("TransactionInfo value found.")); + } } } } diff --git a/types/benches/bytesrepr_bench.rs b/types/benches/bytesrepr_bench.rs index ae4ba66f8f..12223c34aa 100644 --- a/types/benches/bytesrepr_bench.rs +++ b/types/benches/bytesrepr_bench.rs @@ -11,13 +11,12 @@ use casper_types::{ ActionThresholds, AddressableEntity, AssociatedKeys, EntityKind, MessageTopics, }, bytesrepr::{self, Bytes, FromBytes, ToBytes}, - package::PackageStatus, system::auction::{Bid, Delegator, EraInfo, SeigniorageAllocation}, AccessRights, AddressableEntityHash, ByteCodeHash, CLType, CLTyped, CLValue, DeployHash, DeployInfo, EntityVersionKey, EntityVersions, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Group, Groups, Key, Package, PackageHash, Parameter, ProtocolVersion, PublicKey, - SecretKey, Transfer, TransferAddr, URef, KEY_HASH_LENGTH, TRANSFER_ADDR_LENGTH, U128, U256, - U512, UREF_ADDR_LENGTH, + EntryPoints, Gas, Group, Groups, InitiatorAddr, Key, Package, PackageHash, PackageStatus, + Parameter, ProtocolVersion, PublicKey, SecretKey, TransactionHash, TransactionV1Hash, Transfer, + TransferAddr, URef, KEY_HASH_LENGTH, TRANSFER_ADDR_LENGTH, U128, U256, U512, UREF_ADDR_LENGTH, }; static KB: usize = 1024; @@ -622,13 +621,13 @@ fn deserialize_bid(delegators_len: u32, b: &mut Bencher) { fn sample_transfer() -> Transfer { Transfer::new( - DeployHash::default(), - AccountHash::default(), + TransactionHash::V1(TransactionV1Hash::default()), + InitiatorAddr::AccountHash(AccountHash::default()), None, URef::default(), URef::default(), U512::MAX, - U512::from_dec_str("123123123123").unwrap(), + Gas::new(U512::from_dec_str("123123123123").unwrap()), Some(1u64), ) } diff --git a/types/src/addressable_entity.rs b/types/src/addressable_entity.rs index 44f22f0b16..8c65ecdd6a 100644 --- a/types/src/addressable_entity.rs +++ b/types/src/addressable_entity.rs @@ -53,7 +53,6 @@ pub use self::{ named_keys::NamedKeys, weight::{Weight, WEIGHT_SERIALIZED_LENGTH}, }; - use crate::{ account::{Account, AccountHash}, byte_code::ByteCodeHash, @@ -61,6 +60,7 @@ use crate::{ checksummed_hex, contract_messages::TopicNameHash, contracts::{Contract, ContractHash}, + serde_helpers, system::SystemEntityType, uref::{self, URef}, AccessRights, ApiError, CLType, CLTyped, CLValue, CLValueError, ContextAccessRights, Group, @@ -73,18 +73,9 @@ pub const MAX_GROUPS: u8 = 10; /// Maximum number of URefs which can be assigned across all user groups. pub const MAX_TOTAL_UREFS: usize = 100; -/// The tag for Contract Packages associated with Wasm stored on chain. -pub const PACKAGE_KIND_WASM_TAG: u8 = 0; -/// The tag for Contract Package associated with a native contract implementation. -pub const PACKAGE_KIND_SYSTEM_CONTRACT_TAG: u8 = 1; -/// The tag for Contract Package associated with an Account hash. -pub const PACKAGE_KIND_ACCOUNT_TAG: u8 = 2; -/// The tag for Contract Packages associated with legacy packages. -pub const PACKAGE_KIND_LEGACY_TAG: u8 = 3; - const ADDRESSABLE_ENTITY_STRING_PREFIX: &str = "addressable-entity-"; -const ENTITY_PREFIX: &str = "addressable-entity-"; +const ENTITY_PREFIX: &str = "entity-addr-"; const ACCOUNT_ENTITY_PREFIX: &str = "account-"; const CONTRACT_ENTITY_PREFIX: &str = "contract-"; const SYSTEM_ENTITY_PREFIX: &str = "system-"; @@ -676,13 +667,16 @@ impl KeyValueJsonSchema for EntryPointLabels { const JSON_SCHEMA_KV_NAME: Option<&'static str> = Some("NamedEntryPoint"); } -#[allow(missing_docs)] +/// Tag for the variants of [`EntityKind`]. #[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize)] #[cfg_attr(feature = "datasize", derive(DataSize))] #[repr(u8)] pub enum EntityKindTag { + /// `EntityKind::System` variant. System = 0, + /// `EntityKind::Account` variant. Account = 1, + /// `EntityKind::SmartContract` variant. SmartContract = 2, } @@ -881,14 +875,14 @@ impl FromBytes for EntityKind { impl Display for EntityKind { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { - EntityKind::SmartContract => { - write!(f, "PackageKind:Wasm") - } EntityKind::System(system_entity) => { - write!(f, "PackageKind:System({})", system_entity) + write!(f, "system-entity-kind({})", system_entity) } EntityKind::Account(account_hash) => { - write!(f, "PackageKind:Account({})", account_hash) + write!(f, "account-entity-kind({})", account_hash) + } + EntityKind::SmartContract => { + write!(f, "smart-contract-entity-kind") } } } @@ -906,44 +900,72 @@ impl Distribution for Standard { } } -/// The address for an AddressableEntity which contains the 32 bytes and tagging information. +/// The address of an [`AddressableEntity`] which contains the 32 bytes and tagging information. #[derive(PartialOrd, Ord, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize)] #[cfg_attr(feature = "datasize", derive(DataSize))] -#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +#[cfg_attr( + feature = "json-schema", + derive(JsonSchema), + schemars(description = "The hex-encoded address and kind of the addressable entity.") +)] pub enum EntityAddr { /// The address for a system entity account or contract. + #[serde(with = "serde_helpers::raw_32_byte_array")] + #[cfg_attr( + feature = "json-schema", + schemars( + with = "String", + description = "Hex-encoded entity address identifying a system contract." + ) + )] System(HashAddr), /// The address of an entity that corresponds to an Account. + #[serde(with = "serde_helpers::raw_32_byte_array")] + #[cfg_attr( + feature = "json-schema", + schemars( + with = "String", + description = "Hex-encoded entity address identifying an account." + ) + )] Account(HashAddr), - /// The address of an entity that corresponds to a Userland smart contract. + /// The address of an entity that corresponds to a smart contract. + #[serde(with = "serde_helpers::raw_32_byte_array")] + #[cfg_attr( + feature = "json-schema", + schemars( + with = "String", + description = "Hex-encoded entity address identifying a smart contract." + ) + )] SmartContract(HashAddr), } impl EntityAddr { - /// The length in bytes of a [`EntityAddr`]. - pub const ENTITY_ADDR_LENGTH: usize = U8_SERIALIZED_LENGTH + KEY_HASH_LENGTH; + /// The length in bytes of an `EntityAddr`. + pub const LENGTH: usize = U8_SERIALIZED_LENGTH + KEY_HASH_LENGTH; - /// Constructs a new [`EntityAddr`] for a system entity. - pub const fn new_system_entity_addr(hash_addr: [u8; KEY_HASH_LENGTH]) -> Self { + /// Constructs a new `EntityAddr` for a system entity. + pub const fn new_system(hash_addr: HashAddr) -> Self { Self::System(hash_addr) } - /// Constructs a new [`EntityAddr`] for an Account entity. - pub const fn new_account_entity_addr(hash_addr: [u8; KEY_HASH_LENGTH]) -> Self { + /// Constructs a new `EntityAddr` for an Account entity. + pub const fn new_account(hash_addr: HashAddr) -> Self { Self::Account(hash_addr) } - /// Constructs a new [`EntityAddr`] for a smart contract. - pub const fn new_contract_entity_addr(hash_addr: [u8; KEY_HASH_LENGTH]) -> Self { + /// Constructs a new `EntityAddr` for a smart contract. + pub const fn new_smart_contract(hash_addr: HashAddr) -> Self { Self::SmartContract(hash_addr) } - /// Constructs a new [`EntityAddr`] based on the supplied tag. - pub fn new_with_tag(entity_kind: EntityKind, hash_addr: [u8; KEY_HASH_LENGTH]) -> Self { + /// Constructs a new `EntityAddr` based on the supplied kind. + pub fn new_of_kind(entity_kind: EntityKind, hash_addr: HashAddr) -> Self { match entity_kind { - EntityKind::System(_) => Self::new_system_entity_addr(hash_addr), - EntityKind::Account(_) => Self::new_account_entity_addr(hash_addr), - EntityKind::SmartContract => Self::new_contract_entity_addr(hash_addr), + EntityKind::System(_) => Self::new_system(hash_addr), + EntityKind::Account(_) => Self::new_account(hash_addr), + EntityKind::SmartContract => Self::new_smart_contract(hash_addr), } } @@ -975,16 +997,41 @@ impl EntityAddr { /// Returns the formatted String representation of the [`EntityAddr`]. pub fn to_formatted_string(&self) -> String { - format!("{}", self) + match self { + EntityAddr::System(addr) => { + format!( + "{}{}{}", + ENTITY_PREFIX, + SYSTEM_ENTITY_PREFIX, + base16::encode_lower(addr) + ) + } + EntityAddr::Account(addr) => { + format!( + "{}{}{}", + ENTITY_PREFIX, + ACCOUNT_ENTITY_PREFIX, + base16::encode_lower(addr) + ) + } + EntityAddr::SmartContract(addr) => { + format!( + "{}{}{}", + ENTITY_PREFIX, + CONTRACT_ENTITY_PREFIX, + base16::encode_lower(addr) + ) + } + } } /// Constructs an [`EntityAddr`] from a formatted String. pub fn from_formatted_str(input: &str) -> Result { if let Some(entity) = input.strip_prefix(ENTITY_PREFIX) { - let (addr_str, tag) = if let Some(str) = entity.strip_prefix(ACCOUNT_ENTITY_PREFIX) { - (str, EntityKindTag::Account) - } else if let Some(str) = entity.strip_prefix(SYSTEM_ENTITY_PREFIX) { + let (addr_str, tag) = if let Some(str) = entity.strip_prefix(SYSTEM_ENTITY_PREFIX) { (str, EntityKindTag::System) + } else if let Some(str) = entity.strip_prefix(ACCOUNT_ENTITY_PREFIX) { + (str, EntityKindTag::Account) } else if let Some(str) = entity.strip_prefix(CONTRACT_ENTITY_PREFIX) { (str, EntityKindTag::SmartContract) } else { @@ -993,9 +1040,9 @@ impl EntityAddr { let addr = checksummed_hex::decode(addr_str).map_err(FromStrError::Hex)?; let hash_addr = HashAddr::try_from(addr.as_ref()).map_err(FromStrError::Hash)?; let entity_addr = match tag { - EntityKindTag::System => EntityAddr::new_system_entity_addr(hash_addr), - EntityKindTag::Account => EntityAddr::new_account_entity_addr(hash_addr), - EntityKindTag::SmartContract => EntityAddr::new_contract_entity_addr(hash_addr), + EntityKindTag::System => EntityAddr::new_system(hash_addr), + EntityKindTag::Account => EntityAddr::new_account(hash_addr), + EntityKindTag::SmartContract => EntityAddr::new_smart_contract(hash_addr), }; return Ok(entity_addr); @@ -1008,39 +1055,45 @@ impl EntityAddr { impl ToBytes for EntityAddr { fn to_bytes(&self) -> Result, bytesrepr::Error> { let mut buffer = bytesrepr::allocate_buffer(self)?; - buffer.push(self.tag() as u8); - buffer.append(&mut self.value().to_bytes()?); + self.write_bytes(&mut buffer)?; Ok(buffer) } fn serialized_length(&self) -> usize { - EntityAddr::ENTITY_ADDR_LENGTH + EntityAddr::LENGTH } -} -impl FromBytes for EntityAddr { - fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (tag, remainder): (EntityKindTag, &[u8]) = FromBytes::from_bytes(bytes)?; - match tag { - EntityKindTag::System => { - HashAddr::from_bytes(remainder).map(|(hash_addr, remainder)| { - (EntityAddr::new_system_entity_addr(hash_addr), remainder) - }) + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + match self { + EntityAddr::System(addr) => { + EntityKindTag::System.write_bytes(writer)?; + addr.write_bytes(writer) } - EntityKindTag::Account => { - HashAddr::from_bytes(remainder).map(|(hash_addr, remainder)| { - (EntityAddr::new_account_entity_addr(hash_addr), remainder) - }) + EntityAddr::Account(addr) => { + EntityKindTag::Account.write_bytes(writer)?; + addr.write_bytes(writer) } - EntityKindTag::SmartContract => { - HashAddr::from_bytes(remainder).map(|(hash_addr, remainder)| { - (EntityAddr::new_contract_entity_addr(hash_addr), remainder) - }) + EntityAddr::SmartContract(addr) => { + EntityKindTag::SmartContract.write_bytes(writer)?; + addr.write_bytes(writer) } } } } +impl FromBytes for EntityAddr { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (tag, remainder) = EntityKindTag::from_bytes(bytes)?; + let (addr, remainder) = HashAddr::from_bytes(remainder)?; + let entity_addr = match tag { + EntityKindTag::System => EntityAddr::System(addr), + EntityKindTag::Account => EntityAddr::Account(addr), + EntityKindTag::SmartContract => EntityAddr::SmartContract(addr), + }; + Ok((entity_addr, remainder)) + } +} + impl From for AddressableEntityHash { fn from(entity_addr: EntityAddr) -> Self { AddressableEntityHash::new(entity_addr.value()) @@ -1049,13 +1102,7 @@ impl From for AddressableEntityHash { impl Display for EntityAddr { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!( - f, - "{}{}-{}", - ADDRESSABLE_ENTITY_STRING_PREFIX, - self.tag(), - base16::encode_lower(&self.value()) - ) + f.write_str(&self.to_formatted_string()) } } @@ -1063,13 +1110,21 @@ impl Debug for EntityAddr { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { EntityAddr::System(hash_addr) => { - write!(f, "EntityAddr::System({:?})", hash_addr) + write!(f, "EntityAddr::System({})", base16::encode_lower(hash_addr)) } EntityAddr::Account(hash_addr) => { - write!(f, "EntityAddr::Account({:?})", hash_addr) + write!( + f, + "EntityAddr::Account({})", + base16::encode_lower(hash_addr) + ) } EntityAddr::SmartContract(hash_addr) => { - write!(f, "EntityAddr::SmartContract({:?})", hash_addr) + write!( + f, + "EntityAddr::SmartContract({})", + base16::encode_lower(hash_addr) + ) } } } @@ -1101,7 +1156,7 @@ pub struct NamedKeyAddr { impl NamedKeyAddr { /// The length in bytes of a [`NamedKeyAddr`]. - pub const NAMED_KEY_ADDR_BASE_LENGTH: usize = 1 + EntityAddr::ENTITY_ADDR_LENGTH; + pub const NAMED_KEY_ADDR_BASE_LENGTH: usize = 1 + EntityAddr::LENGTH; /// Constructs a new [`NamedKeyAddr`] based on the supplied bytes. pub const fn new_named_key_entry( @@ -1686,8 +1741,8 @@ impl AddressableEntity { self.protocol_version.value().major == protocol_version.value().major } - /// Returns the kind of Package. - pub fn entity_kind(&self) -> EntityKind { + /// Returns the kind of `AddressableEntity`. + pub fn kind(&self) -> EntityKind { self.entity_kind } @@ -1755,7 +1810,7 @@ impl ToBytes for AddressableEntity { self.associated_keys().write_bytes(&mut result)?; self.action_thresholds().write_bytes(&mut result)?; self.message_topics().write_bytes(&mut result)?; - self.entity_kind().write_bytes(&mut result)?; + self.kind().write_bytes(&mut result)?; Ok(result) } @@ -1780,7 +1835,7 @@ impl ToBytes for AddressableEntity { self.associated_keys().write_bytes(writer)?; self.action_thresholds().write_bytes(writer)?; self.message_topics().write_bytes(writer)?; - self.entity_kind().write_bytes(writer)?; + self.kind().write_bytes(writer)?; Ok(()) } } @@ -2269,10 +2324,8 @@ mod tests { #[test] fn named_key_addr_from_str() { - let named_key_addr = NamedKeyAddr::new_named_key_entry( - EntityAddr::new_contract_entity_addr([3; 32]), - [4; 32], - ); + let named_key_addr = + NamedKeyAddr::new_named_key_entry(EntityAddr::new_smart_contract([3; 32]), [4; 32]); let encoded = named_key_addr.to_formatted_string(); let decoded = NamedKeyAddr::from_formatted_str(&encoded).unwrap(); assert_eq!(named_key_addr, decoded); @@ -2304,11 +2357,11 @@ mod tests { #[test] fn serialization_roundtrip() { - let entity_addr = EntityAddr::new_system_entity_addr([1; 32]); + let entity_addr = EntityAddr::new_system([1; 32]); bytesrepr::test_serialization_roundtrip(&entity_addr); - let entity_addr = EntityAddr::new_account_entity_addr([1; 32]); + let entity_addr = EntityAddr::new_account([1; 32]); bytesrepr::test_serialization_roundtrip(&entity_addr); - let entity_addr = EntityAddr::new_contract_entity_addr([1; 32]); + let entity_addr = EntityAddr::new_smart_contract([1; 32]); bytesrepr::test_serialization_roundtrip(&entity_addr); } diff --git a/types/src/byte_code.rs b/types/src/byte_code.rs index 773102c28a..a09d1db6db 100644 --- a/types/src/byte_code.rs +++ b/types/src/byte_code.rs @@ -30,6 +30,9 @@ const BYTE_CODE_PREFIX: &str = "byte-code-"; const V1_WASM_PREFIX: &str = "v1-wasm-"; const EMPTY_PREFIX: &str = "empty-"; +/// A special contract wasm hash for contracts representing Accounts. +pub const ACCOUNT_BYTE_CODE_HASH: ByteCodeHash = ByteCodeHash::new([0; 32]); + /// Associated error type of `TryFrom<&[u8]>` for `ByteCodeHash`. #[derive(Debug)] pub struct TryFromSliceForContractHashError(()); diff --git a/types/src/chainspec.rs b/types/src/chainspec.rs index 2cb3a7f2ef..4c710499bc 100644 --- a/types/src/chainspec.rs +++ b/types/src/chainspec.rs @@ -40,9 +40,9 @@ pub use chainspec_raw_bytes::ChainspecRawBytes; pub use core_config::{ConsensusProtocolName, CoreConfig, LegacyRequiredFinality}; pub use fee_handling::FeeHandling; #[cfg(any(feature = "std", test))] -pub use genesis_config::{GenesisConfig, GenesisConfigBuilder}; +pub use genesis_config::{GenesisConfig, GenesisConfigBuilder, DEFAULT_REFUND_HANDLING}; #[cfg(any(feature = "testing", test))] -pub use genesis_config::{DEFAULT_AUCTION_DELAY, DEFAULT_FEE_HANDLING, DEFAULT_REFUND_HANDLING}; +pub use genesis_config::{DEFAULT_AUCTION_DELAY, DEFAULT_FEE_HANDLING}; pub use global_state_update::{GlobalStateUpdate, GlobalStateUpdateConfig, GlobalStateUpdateError}; pub use highway_config::HighwayConfig; pub use network_config::NetworkConfig; diff --git a/types/src/chainspec/vm_config/host_function_costs.rs b/types/src/chainspec/vm_config/host_function_costs.rs index ddb1c68de7..5892c797f4 100644 --- a/types/src/chainspec/vm_config/host_function_costs.rs +++ b/types/src/chainspec/vm_config/host_function_costs.rs @@ -152,10 +152,10 @@ where /// Calculate gas cost for a host function pub fn calculate_gas_cost(&self, weights: T) -> Gas { - let mut gas = Gas::new(self.cost.into()); + let mut gas = Gas::new(self.cost); for (argument, weight) in self.arguments.as_ref().iter().zip(weights.as_ref()) { - let lhs = Gas::new((*argument).into()); - let rhs = Gas::new((*weight).into()); + let lhs = Gas::new(*argument); + let rhs = Gas::new(*weight); gas += lhs * rhs; } gas @@ -1035,7 +1035,7 @@ mod tests { + (ARGUMENT_COSTS[2] * WEIGHTS[2]); assert_eq!( host_function.calculate_gas_cost(WEIGHTS), - Gas::new(expected_cost.into()) + Gas::new(expected_cost) ); } diff --git a/types/src/cl_value.rs b/types/src/cl_value.rs index 65a8c05885..5d0e10ec73 100644 --- a/types/src/cl_value.rs +++ b/types/src/cl_value.rs @@ -16,11 +16,11 @@ use crate::{ mod checksum_registry; mod dictionary; mod jsonrepr; -mod system_contract_registry; +mod system_entity_registry; pub use checksum_registry::ChecksumRegistry; pub use dictionary::{handle_stored_dictionary_value, DictionaryValue}; -pub use system_contract_registry::SystemEntityRegistry; +pub use system_entity_registry::SystemEntityRegistry; /// Error while converting a [`CLValue`] into a given type. #[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)] diff --git a/types/src/cl_value/system_contract_registry.rs b/types/src/cl_value/system_entity_registry.rs similarity index 87% rename from types/src/cl_value/system_contract_registry.rs rename to types/src/cl_value/system_entity_registry.rs index 96dea57dd6..1599f1584d 100644 --- a/types/src/cl_value/system_contract_registry.rs +++ b/types/src/cl_value/system_entity_registry.rs @@ -12,12 +12,12 @@ use crate::{ AddressableEntityHash, CLType, CLTyped, }; -/// The system contract registry. +/// The system entity registry. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Debug)] pub struct SystemEntityRegistry(BTreeMap); impl SystemEntityRegistry { - /// Returns a new `SystemContractRegistry`. + /// Returns a new `SystemEntityRegistry`. #[allow(clippy::new_without_default)] // This empty `new()` will be replaced in the future. pub fn new() -> Self { SystemEntityRegistry(BTreeMap::new()) @@ -80,8 +80,8 @@ mod tests { #[test] fn bytesrepr_roundtrip() { - let mut system_contract_registry = SystemEntityRegistry::new(); - system_contract_registry.insert("a".to_string(), AddressableEntityHash::new([9; 32])); - bytesrepr::test_serialization_roundtrip(&system_contract_registry); + let mut system_entity_registry = SystemEntityRegistry::new(); + system_entity_registry.insert("a".to_string(), AddressableEntityHash::new([9; 32])); + bytesrepr::test_serialization_roundtrip(&system_entity_registry); } } diff --git a/types/src/contracts.rs b/types/src/contracts.rs index 576bf64300..df590c7a48 100644 --- a/types/src/contracts.rs +++ b/types/src/contracts.rs @@ -33,11 +33,6 @@ use crate::{ HashAddr, Key, Package, ProtocolVersion, KEY_HASH_LENGTH, }; -/// Maximum number of distinct user groups. -pub const MAX_GROUPS: u8 = 10; -/// Maximum number of URefs which can be assigned across all user groups. -pub const MAX_TOTAL_UREFS: usize = 100; - const CONTRACT_STRING_PREFIX: &str = "contract-"; const PACKAGE_STRING_PREFIX: &str = "contract-package-"; // We need to support the legacy prefix of "contract-package-wasm". diff --git a/types/src/deploy_info.rs b/types/src/deploy_info.rs index faa51e7442..6f4da83582 100644 --- a/types/src/deploy_info.rs +++ b/types/src/deploy_info.rs @@ -104,40 +104,17 @@ impl ToBytes for DeployInfo { } } -/// Generators for a `Deploy` +/// Generators for a `DeployInfo` #[cfg(any(feature = "testing", feature = "gens", test))] pub(crate) mod gens { - use alloc::vec::Vec; - - use proptest::{ - array, - collection::{self, SizeRange}, - prelude::{Arbitrary, Strategy}, - }; + use proptest::prelude::Strategy; use crate::{ - account::AccountHash, gens::{u512_arb, uref_arb}, - DeployHash, DeployInfo, TransferAddr, + transaction_info::gens::{account_hash_arb, deploy_hash_arb, transfers_arb}, + DeployInfo, }; - pub fn deploy_hash_arb() -> impl Strategy { - array::uniform32(::arbitrary()).prop_map(DeployHash::from_raw) - } - - pub fn transfer_addr_arb() -> impl Strategy { - array::uniform32(::arbitrary()).prop_map(TransferAddr::new) - } - - pub fn transfers_arb(size: impl Into) -> impl Strategy> { - collection::vec(transfer_addr_arb(), size) - } - - pub fn account_hash_arb() -> impl Strategy { - array::uniform32(::arbitrary()).prop_map(AccountHash::new) - } - - /// Creates an arbitrary `Deploy` pub fn deploy_info_arb() -> impl Strategy { let transfers_length_range = 0..5; ( diff --git a/types/src/execution/execution_result_v2.rs b/types/src/execution/execution_result_v2.rs index 9470c13345..e1c9318fb8 100644 --- a/types/src/execution/execution_result_v2.rs +++ b/types/src/execution/execution_result_v2.rs @@ -1,7 +1,7 @@ //! This file provides types to allow conversion from an EE `ExecutionResult` into a similar type //! which can be serialized to a valid binary or JSON representation. //! -//! It is stored as metadata related to a given deploy, and made available to clients via the +//! It is stored as metadata related to a given transaction, and made available to clients via the //! JSON-RPC API. #[cfg(any(feature = "testing", test))] @@ -25,7 +25,7 @@ use super::{Transform, TransformKind}; use crate::testing::TestRng; use crate::{ bytesrepr::{self, FromBytes, ToBytes, RESULT_ERR_TAG, RESULT_OK_TAG, U8_SERIALIZED_LENGTH}, - TransferAddr, U512, + Gas, TransferAddr, }; #[cfg(feature = "json-schema")] use crate::{Key, KEY_HASH_LENGTH}; @@ -52,11 +52,11 @@ static EXECUTION_RESULT: Lazy = Lazy::new(|| { ExecutionResultV2::Success { effects, transfers, - cost: U512::from(123_456), + gas: Gas::new(123_456), } }); -/// The result of executing a single deploy. +/// The result of executing a single transaction. #[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Debug)] #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] @@ -64,23 +64,23 @@ static EXECUTION_RESULT: Lazy = Lazy::new(|| { pub enum ExecutionResultV2 { /// The result of a failed execution. Failure { - /// The effects of executing the deploy. + /// The effects of executing the transaction. effects: Effects, - /// A record of transfers performed while executing the deploy. + /// A record of transfers performed while executing the transaction. transfers: Vec, - /// The cost in Motes of executing the deploy. - cost: U512, - /// The error message associated with executing the deploy. + /// The gas consumed executing the transaction. + gas: Gas, + /// The error message associated with executing the transaction. error_message: String, }, /// The result of a successful execution. Success { - /// The effects of executing the deploy. + /// The effects of executing the transaction. effects: Effects, - /// A record of transfers performed while executing the deploy. + /// A record of transfers performed while executing the transaction. transfers: Vec, - /// The cost in Motes of executing the deploy. - cost: U512, + /// The gas consumed executing the transaction. + gas: Gas, }, } @@ -99,14 +99,14 @@ impl Distribution for Standard { ExecutionResultV2::Failure { effects, transfers, - cost: rng.gen::().into(), + gas: Gas::new(rng.gen::()), error_message: format!("Error message {}", rng.gen::()), } } else { ExecutionResultV2::Success { effects, transfers, - cost: rng.gen::().into(), + gas: Gas::new(rng.gen::()), } } } @@ -131,20 +131,20 @@ impl ExecutionResultV2 { transfers.push(TransferAddr::new(rng.gen())) } - let cost = U512::from(rng.gen::()); + let gas = Gas::new(rng.gen::()); if rng.gen() { ExecutionResultV2::Failure { effects, transfers, - cost, + gas, error_message: format!("Error message {}", rng.gen::()), } } else { ExecutionResultV2::Success { effects, transfers, - cost, + gas, } } } @@ -156,24 +156,24 @@ impl ToBytes for ExecutionResultV2 { ExecutionResultV2::Failure { effects, transfers, - cost, + gas, error_message, } => { RESULT_ERR_TAG.write_bytes(writer)?; effects.write_bytes(writer)?; transfers.write_bytes(writer)?; - cost.write_bytes(writer)?; + gas.write_bytes(writer)?; error_message.write_bytes(writer) } ExecutionResultV2::Success { effects, transfers, - cost, + gas, } => { RESULT_OK_TAG.write_bytes(writer)?; effects.write_bytes(writer)?; transfers.write_bytes(writer)?; - cost.write_bytes(writer) + gas.write_bytes(writer) } } } @@ -190,22 +190,22 @@ impl ToBytes for ExecutionResultV2 { ExecutionResultV2::Failure { effects, transfers, - cost, + gas, error_message, } => { effects.serialized_length() + transfers.serialized_length() - + cost.serialized_length() + + gas.serialized_length() + error_message.serialized_length() } ExecutionResultV2::Success { effects, transfers, - cost, + gas, } => { effects.serialized_length() + transfers.serialized_length() - + cost.serialized_length() + + gas.serialized_length() } } } @@ -218,12 +218,12 @@ impl FromBytes for ExecutionResultV2 { RESULT_ERR_TAG => { let (effects, remainder) = Effects::from_bytes(remainder)?; let (transfers, remainder) = Vec::::from_bytes(remainder)?; - let (cost, remainder) = U512::from_bytes(remainder)?; + let (gas, remainder) = Gas::from_bytes(remainder)?; let (error_message, remainder) = String::from_bytes(remainder)?; let execution_result = ExecutionResultV2::Failure { effects, transfers, - cost, + gas, error_message, }; Ok((execution_result, remainder)) @@ -231,11 +231,11 @@ impl FromBytes for ExecutionResultV2 { RESULT_OK_TAG => { let (effects, remainder) = Effects::from_bytes(remainder)?; let (transfers, remainder) = Vec::::from_bytes(remainder)?; - let (cost, remainder) = U512::from_bytes(remainder)?; + let (gas, remainder) = Gas::from_bytes(remainder)?; let execution_result = ExecutionResultV2::Success { effects, transfers, - cost, + gas, }; Ok((execution_result, remainder)) } diff --git a/types/src/execution/transform_kind.rs b/types/src/execution/transform_kind.rs index 77ead5919a..f324aa4783 100644 --- a/types/src/execution/transform_kind.rs +++ b/types/src/execution/transform_kind.rs @@ -183,6 +183,11 @@ impl TransformKind { let found = "Message".to_string(); Err(StoredValueTypeMismatch::new(expected, found).into()) } + StoredValue::TransactionInfo(_) => { + let expected = "Contract or Account".to_string(); + let found = "TransactionInfo".to_string(); + Err(StoredValueTypeMismatch::new(expected, found).into()) + } }, TransformKind::Failure(error) => Err(error), } diff --git a/types/src/gas.rs b/types/src/gas.rs index 7689849e5f..30c7ba0c8b 100644 --- a/types/src/gas.rs +++ b/types/src/gas.rs @@ -1,5 +1,6 @@ //! The `gas` module is used for working with Gas including converting to and from Motes. +use alloc::vec::Vec; use core::{ fmt, iter::Sum, @@ -9,19 +10,30 @@ use core::{ #[cfg(feature = "datasize")] use datasize::DataSize; use num::Zero; +#[cfg(feature = "json-schema")] +use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use crate::{Motes, U512}; +use crate::{ + bytesrepr::{self, FromBytes, ToBytes}, + Motes, U512, +}; /// The `Gas` struct represents a `U512` amount of gas. #[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] #[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] pub struct Gas(U512); impl Gas { /// Constructs a new `Gas`. - pub fn new(value: U512) -> Self { - Gas(value) + pub fn new>(value: T) -> Self { + Gas(value.into()) + } + + /// Constructs a new `Gas` with value `0`. + pub const fn zero() -> Self { + Gas(U512::zero()) } /// Returns the inner `U512` value. @@ -37,13 +49,14 @@ impl Gas { *self } - /// Converts the given `motes` to `Gas` by dividing them by `conv_rate`. + /// Converts the given `Motes` to `Gas` by dividing them by `motes_per_unit_of_gas`, rounding + /// down. /// - /// Returns `None` if `conv_rate == 0`. - pub fn from_motes(motes: Motes, conv_rate: u64) -> Option { + /// Returns `None` if `motes_per_unit_of_gas == 0`. + pub fn from_motes(motes: Motes, motes_per_unit_of_gas: u64) -> Option { motes .value() - .checked_div(U512::from(conv_rate)) + .checked_div(U512::from(motes_per_unit_of_gas)) .map(Self::new) } @@ -58,6 +71,27 @@ impl Gas { } } +impl ToBytes for Gas { + fn to_bytes(&self) -> Result, bytesrepr::Error> { + self.0.to_bytes() + } + + fn serialized_length(&self) -> usize { + self.0.serialized_length() + } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + self.0.write_bytes(writer) + } +} + +impl FromBytes for Gas { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (value, remainder) = U512::from_bytes(bytes)?; + Ok((Gas(value), remainder)) + } +} + impl fmt::Display for Gas { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self.0) @@ -205,7 +239,7 @@ mod tests { #[test] fn should_be_able_to_default() { let gas = Gas::default(); - let expected_gas = Gas::new(U512::from(0)); + let expected_gas = Gas::zero(); assert_eq!(gas, expected_gas, "should be equal") } @@ -221,15 +255,6 @@ mod tests { assert!(left_gas < right_gas, "should be lt"); } - #[test] - fn should_default() { - let left_gas = Gas::new(U512::from(0)); - let right_gas = Gas::default(); - assert_eq!(left_gas, right_gas, "should be equal"); - let u512 = U512::zero(); - assert_eq!(left_gas.value(), u512, "should be equal"); - } - #[test] fn should_support_checked_div_from_motes() { let motes = Motes::new(U512::zero()); diff --git a/types/src/gens.rs b/types/src/gens.rs index 6783774a66..aeed707c3c 100644 --- a/types/src/gens.rs +++ b/types/src/gens.rs @@ -18,37 +18,34 @@ use proptest::{ }; use crate::{ - account::{self, action_thresholds::gens::account_action_thresholds_arb, AccountHash}, - addressable_entity::{MessageTopics, NamedKeys, Parameters, Weight}, - contract_messages::{MessageChecksum, MessageTopicSummary, TopicNameHash}, - crypto::{self, gens::public_key_arb_no_system}, - package::{EntityVersionKey, EntityVersions, Groups, PackageStatus}, - system::auction::{ - gens::era_info_arb, DelegationRate, Delegator, UnbondingPurse, WithdrawPurse, - DELEGATION_RATE_DENOMINATOR, + account::{ + self, action_thresholds::gens::account_action_thresholds_arb, + associated_keys::gens::account_associated_keys_arb, Account, AccountHash, }, - transfer::TransferAddr, - AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, ByteCode, CLType, CLValue, - EntityKind, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, EraId, Group, Key, - NamedArg, Package, Parameter, Phase, ProtocolVersion, SemVer, StoredValue, URef, U128, U256, - U512, -}; - -use crate::{ - account::{associated_keys::gens::account_associated_keys_arb, Account}, addressable_entity::{ action_thresholds::gens::action_thresholds_arb, associated_keys::gens::associated_keys_arb, - NamedKeyValue, + MessageTopics, NamedKeyValue, NamedKeys, Parameters, Weight, }, byte_code::ByteCodeKind, + contract_messages::{MessageChecksum, MessageTopicSummary, TopicNameHash}, contracts::{ Contract, ContractHash, ContractPackage, ContractPackageStatus, ContractVersionKey, ContractVersions, }, - deploy_info::gens::{deploy_hash_arb, transfer_addr_arb}, - system::auction::{Bid, BidAddr, BidKind, ValidatorBid}, + crypto::{self, gens::public_key_arb_no_system}, + deploy_info::gens::deploy_info_arb, + package::{EntityVersionKey, EntityVersions, Groups, PackageStatus}, + system::auction::{ + gens::era_info_arb, Bid, BidAddr, BidKind, DelegationRate, Delegator, UnbondingPurse, + ValidatorBid, WithdrawPurse, DELEGATION_RATE_DENOMINATOR, + }, + transaction_info::gens::{deploy_hash_arb, transfer_addr_arb, txn_info_arb}, + transfer::{gens::transfer_arb, TransferAddr}, + AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, ByteCode, CLType, CLValue, + EntityKind, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, EraId, Group, Key, + NamedArg, Package, Parameter, Phase, ProtocolVersion, SemVer, StoredValue, URef, U128, U256, + U512, }; -pub use crate::{deploy_info::gens::deploy_info_arb, transfer::gens::transfer_arb}; pub fn u8_slice_32() -> impl Strategy { collection::vec(any::(), 32).prop_map(|b| { @@ -718,29 +715,31 @@ pub fn stored_value_arb() -> impl Strategy { unbondings_arb(1..50).prop_map(StoredValue::Unbonding), message_topic_summary_arb().prop_map(StoredValue::MessageTopic), message_summary_arb().prop_map(StoredValue::Message), - named_key_value_arb().prop_map(StoredValue::NamedKey) + named_key_value_arb().prop_map(StoredValue::NamedKey), + txn_info_arb().prop_map(StoredValue::TransactionInfo), ] .prop_map(|stored_value| - // The following match statement is here only to make sure - // we don't forget to update the generator when a new variant is added. - match stored_value { - StoredValue::CLValue(_) => stored_value, - StoredValue::Account(_) => stored_value, - StoredValue::ContractWasm(_) => stored_value, - StoredValue::Contract(_) => stored_value, - StoredValue::ContractPackage(_) => stored_value, - StoredValue::Transfer(_) => stored_value, - StoredValue::DeployInfo(_) => stored_value, - StoredValue::EraInfo(_) => stored_value, - StoredValue::Bid(_) => stored_value, - StoredValue::Withdraw(_) => stored_value, - StoredValue::Unbonding(_) => stored_value, - StoredValue::AddressableEntity(_) => stored_value, - StoredValue::BidKind(_) => stored_value, - StoredValue::Package(_) => stored_value, - StoredValue::ByteCode(_) => stored_value, - StoredValue::MessageTopic(_) => stored_value, - StoredValue::Message(_) => stored_value, - StoredValue::NamedKey(_) => stored_value, - }) + // The following match statement is here only to make sure + // we don't forget to update the generator when a new variant is added. + match stored_value { + StoredValue::CLValue(_) => stored_value, + StoredValue::Account(_) => stored_value, + StoredValue::ContractWasm(_) => stored_value, + StoredValue::Contract(_) => stored_value, + StoredValue::ContractPackage(_) => stored_value, + StoredValue::Transfer(_) => stored_value, + StoredValue::DeployInfo(_) => stored_value, + StoredValue::EraInfo(_) => stored_value, + StoredValue::Bid(_) => stored_value, + StoredValue::Withdraw(_) => stored_value, + StoredValue::Unbonding(_) => stored_value, + StoredValue::AddressableEntity(_) => stored_value, + StoredValue::BidKind(_) => stored_value, + StoredValue::Package(_) => stored_value, + StoredValue::ByteCode(_) => stored_value, + StoredValue::MessageTopic(_) => stored_value, + StoredValue::Message(_) => stored_value, + StoredValue::NamedKey(_) => stored_value, + StoredValue::TransactionInfo(_) => stored_value, + }) } diff --git a/types/src/key.rs b/types/src/key.rs index 5d69897c6f..18a5d33cc1 100644 --- a/types/src/key.rs +++ b/types/src/key.rs @@ -45,8 +45,8 @@ use crate::{ package::PackageHash, system::auction::{BidAddr, BidAddrTag}, uref::{self, URef, URefAddr, UREF_SERIALIZED_LENGTH}, - ByteCodeAddr, DeployHash, Digest, EraId, Tagged, TransferAddr, TransferFromStrError, - TRANSFER_ADDR_LENGTH, UREF_ADDR_LENGTH, + ByteCodeAddr, DeployHash, Digest, EraId, Tagged, TransactionHash, TransactionV1Hash, + TransferAddr, TransferFromStrError, TRANSFER_ADDR_LENGTH, UREF_ADDR_LENGTH, }; const HASH_PREFIX: &str = "hash-"; @@ -57,12 +57,15 @@ const BID_PREFIX: &str = "bid-"; const WITHDRAW_PREFIX: &str = "withdraw-"; const DICTIONARY_PREFIX: &str = "dictionary-"; const UNBOND_PREFIX: &str = "unbond-"; -const SYSTEM_CONTRACT_REGISTRY_PREFIX: &str = "system-contract-registry-"; +const SYSTEM_ENTITY_REGISTRY_PREFIX: &str = "system-entity-registry-"; const ERA_SUMMARY_PREFIX: &str = "era-summary-"; const CHAINSPEC_REGISTRY_PREFIX: &str = "chainspec-registry-"; const CHECKSUM_REGISTRY_PREFIX: &str = "checksum-registry-"; const BID_ADDR_PREFIX: &str = "bid-addr-"; const PACKAGE_PREFIX: &str = "package-"; +const TXN_INFO_PREFIX: &str = "txn-"; +const TXN_INFO_DEPLOY_PREFIX: &str = "d-"; +const TXN_INFO_V1_PREFIX: &str = "v1-"; /// The number of bytes in a Blake2b hash pub const BLAKE2B_DIGEST_LENGTH: usize = 32; @@ -91,7 +94,7 @@ const KEY_BID_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_HASH_LEN const KEY_WITHDRAW_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_HASH_LENGTH; const KEY_UNBOND_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_HASH_LENGTH; const KEY_DICTIONARY_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_DICTIONARY_LENGTH; -const KEY_SYSTEM_CONTRACT_REGISTRY_SERIALIZED_LENGTH: usize = +const KEY_SYSTEM_ENTITY_REGISTRY_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + PADDING_BYTES.len(); const KEY_ERA_SUMMARY_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + PADDING_BYTES.len(); const KEY_CHAINSPEC_REGISTRY_SERIALIZED_LENGTH: usize = @@ -130,7 +133,7 @@ pub enum KeyTag { Bid = 7, Withdraw = 8, Dictionary = 9, - SystemContractRegistry = 10, + SystemEntityRegistry = 10, EraSummary = 11, Unbond = 12, ChainspecRegistry = 13, @@ -141,6 +144,7 @@ pub enum KeyTag { ByteCode = 18, Message = 19, NamedKey = 20, + TransactionInfo = 21, } impl Display for KeyTag { @@ -156,7 +160,7 @@ impl Display for KeyTag { KeyTag::Bid => write!(f, "Bid"), KeyTag::Withdraw => write!(f, "Withdraw"), KeyTag::Dictionary => write!(f, "Dictionary"), - KeyTag::SystemContractRegistry => write!(f, "SystemContractRegistry"), + KeyTag::SystemEntityRegistry => write!(f, "SystemEntityRegistry"), KeyTag::EraSummary => write!(f, "EraSummary"), KeyTag::Unbond => write!(f, "Unbond"), KeyTag::ChainspecRegistry => write!(f, "ChainspecRegistry"), @@ -167,6 +171,7 @@ impl Display for KeyTag { KeyTag::ByteCode => write!(f, "ByteCode"), KeyTag::Message => write!(f, "Message"), KeyTag::NamedKey => write!(f, "NamedKey"), + KeyTag::TransactionInfo => write!(f, "TransactionInfo"), } } } @@ -199,7 +204,7 @@ pub enum Key { /// A `Key` whose value is derived by hashing a [`URef`] address and arbitrary data, under /// which a dictionary is stored. Dictionary(DictionaryAddr), - /// A `Key` under which system contract hashes are stored. + /// A `Key` under which system entity hashes are stored. SystemEntityRegistry, /// A `Key` under which current era info is stored. EraSummary, @@ -221,6 +226,8 @@ pub enum Key { Message(MessageAddr), /// A `Key` under which a single named key entry is stored. NamedKey(NamedKeyAddr), + /// A `Key` under which info about a transaction is stored. + TransactionInfo(TransactionHash), } #[cfg(feature = "json-schema")] @@ -265,8 +272,8 @@ pub enum FromStrError { Withdraw(String), /// Dictionary parse error. Dictionary(String), - /// System contract registry parse error. - SystemContractRegistry(String), + /// System entity registry parse error. + SystemEntityRegistry(String), /// Era summary parse error. EraSummary(String), /// Unbond parse error. @@ -287,6 +294,8 @@ pub enum FromStrError { Message(contract_messages::FromStrError), /// Named key parse error. NamedKey(String), + /// TransactionInfo parse error. + TransactionInfo(String), /// Unknown prefix. UnknownPrefix, } @@ -332,7 +341,7 @@ impl Display for FromStrError { FromStrError::Dictionary(error) => { write!(f, "dictionary-key from string error: {}", error) } - FromStrError::SystemContractRegistry(error) => { + FromStrError::SystemEntityRegistry(error) => { write!( f, "system-contract-registry-key from string error: {}", @@ -365,6 +374,9 @@ impl Display for FromStrError { FromStrError::NamedKey(error) => { write!(f, "named-key from string error: {}", error) } + FromStrError::TransactionInfo(error) => { + write!(f, "transaction-info-key from string error: {}", error) + } FromStrError::UnknownPrefix => write!(f, "unknown prefix for key"), } } @@ -385,17 +397,18 @@ impl Key { Key::Bid(_) => String::from("Key::Bid"), Key::Withdraw(_) => String::from("Key::Unbond"), Key::Dictionary(_) => String::from("Key::Dictionary"), - Key::SystemEntityRegistry => String::from("Key::SystemContractRegistry"), + Key::SystemEntityRegistry => String::from("Key::SystemEntityRegistry"), Key::EraSummary => String::from("Key::EraSummary"), Key::Unbond(_) => String::from("Key::Unbond"), Key::ChainspecRegistry => String::from("Key::ChainspecRegistry"), Key::ChecksumRegistry => String::from("Key::ChecksumRegistry"), Key::BidAddr(_) => String::from("Key::BidAddr"), Key::Package(_) => String::from("Key::Package"), - Key::AddressableEntity(..) => String::from("Key::AddressableEntity"), - Key::ByteCode(..) => String::from("Key::ByteCode"), + Key::AddressableEntity(_) => String::from("Key::AddressableEntity"), + Key::ByteCode(_) => String::from("Key::ByteCode"), Key::Message(_) => String::from("Key::Message"), Key::NamedKey(_) => String::from("Key::NamedKey"), + Key::TransactionInfo(_) => String::from("Key::TransactionInfo"), } } @@ -422,11 +435,11 @@ impl Key { Key::Hash(addr) => format!("{}{}", HASH_PREFIX, base16::encode_lower(&addr)), Key::URef(uref) => uref.to_formatted_string(), Key::Transfer(transfer_addr) => transfer_addr.to_formatted_string(), - Key::DeployInfo(addr) => { + Key::DeployInfo(deploy_hash) => { format!( "{}{}", DEPLOY_INFO_PREFIX, - base16::encode_lower(addr.as_ref()) + base16::encode_lower(deploy_hash.as_ref()) ) } Key::EraInfo(era_id) => { @@ -451,7 +464,7 @@ impl Key { Key::SystemEntityRegistry => { format!( "{}{}", - SYSTEM_CONTRACT_REGISTRY_PREFIX, + SYSTEM_ENTITY_REGISTRY_PREFIX, base16::encode_lower(&PADDING_BYTES) ) } @@ -495,6 +508,24 @@ impl Key { Key::NamedKey(named_key) => { format!("{}", named_key) } + Key::TransactionInfo(txn_hash) => match txn_hash { + TransactionHash::Deploy(deploy_hash) => { + format!( + "{}{}{}", + TXN_INFO_PREFIX, + TXN_INFO_DEPLOY_PREFIX, + base16::encode_lower(deploy_hash.as_ref()) + ) + } + TransactionHash::V1(txn_v1_hash) => { + format!( + "{}{}{}", + TXN_INFO_PREFIX, + TXN_INFO_V1_PREFIX, + base16::encode_lower(txn_v1_hash.as_ref()) + ) + } + }, } } @@ -625,11 +656,11 @@ impl Key { return Ok(Key::Dictionary(addr)); } - if let Some(registry_address) = input.strip_prefix(SYSTEM_CONTRACT_REGISTRY_PREFIX) { + if let Some(registry_address) = input.strip_prefix(SYSTEM_ENTITY_REGISTRY_PREFIX) { let padded_bytes = checksummed_hex::decode(registry_address) - .map_err(|error| FromStrError::SystemContractRegistry(error.to_string()))?; + .map_err(|error| FromStrError::SystemEntityRegistry(error.to_string()))?; let _padding: [u8; 32] = TryFrom::try_from(padded_bytes.as_ref()).map_err(|_| { - FromStrError::SystemContractRegistry( + FromStrError::SystemEntityRegistry( "Failed to deserialize system registry key".to_string(), ) })?; @@ -690,6 +721,28 @@ impl Key { Err(error) => return Err(FromStrError::NamedKey(error.to_string())), } + if let Some(txn_hash) = input.strip_prefix(TXN_INFO_PREFIX) { + let txn_hash = if let Some(deploy_hash) = txn_hash.strip_prefix(TXN_INFO_DEPLOY_PREFIX) + { + let hash_bytes = checksummed_hex::decode(deploy_hash) + .map_err(|error| FromStrError::TransactionInfo(error.to_string()))?; + let hash = Digest::try_from(hash_bytes.as_slice()) + .map_err(|error| FromStrError::TransactionInfo(error.to_string()))?; + TransactionHash::from(DeployHash::new(hash)) + } else if let Some(txn_v1_hash) = txn_hash.strip_prefix(TXN_INFO_V1_PREFIX) { + let hash_bytes = checksummed_hex::decode(txn_v1_hash) + .map_err(|error| FromStrError::TransactionInfo(error.to_string()))?; + let hash = Digest::try_from(hash_bytes.as_slice()) + .map_err(|error| FromStrError::TransactionInfo(error.to_string()))?; + TransactionHash::from(TransactionV1Hash::new(hash)) + } else { + return Err(FromStrError::TransactionInfo( + "invalid transaction info prefix".to_string(), + )); + }; + return Ok(Key::TransactionInfo(txn_hash)); + } + Err(FromStrError::UnknownPrefix) } @@ -841,11 +894,9 @@ impl Key { entity_hash: AddressableEntityHash, ) -> Self { let entity_addr = match entity_kind_tag { - EntityKindTag::System => EntityAddr::new_system_entity_addr(entity_hash.value()), - EntityKindTag::Account => EntityAddr::new_account_entity_addr(entity_hash.value()), - EntityKindTag::SmartContract => { - EntityAddr::new_contract_entity_addr(entity_hash.value()) - } + EntityKindTag::System => EntityAddr::new_system(entity_hash.value()), + EntityKindTag::Account => EntityAddr::new_account(entity_hash.value()), + EntityKindTag::SmartContract => EntityAddr::new_smart_contract(entity_hash.value()), }; Key::AddressableEntity(entity_addr) @@ -986,7 +1037,7 @@ impl Display for Key { } Key::SystemEntityRegistry => write!( f, - "Key::SystemContractRegistry({})", + "Key::SystemEntityRegistry({})", base16::encode_lower(&PADDING_BYTES) ), Key::EraSummary => write!( @@ -1026,6 +1077,16 @@ impl Display for Key { Key::NamedKey(named_key_addr) => { write!(f, "Key::NamedKey({})", named_key_addr) } + Key::TransactionInfo(TransactionHash::Deploy(deploy_hash)) => write!( + f, + "Key::TransactionInfo(deploy-{})", + base16::encode_lower(deploy_hash.as_ref()) + ), + Key::TransactionInfo(TransactionHash::V1(txn_v1_hash)) => write!( + f, + "Key::TransactionInfo(txn-v1-{})", + base16::encode_lower(txn_v1_hash.as_ref()) + ), } } } @@ -1049,7 +1110,7 @@ impl Tagged for Key { Key::Bid(_) => KeyTag::Bid, Key::Withdraw(_) => KeyTag::Withdraw, Key::Dictionary(_) => KeyTag::Dictionary, - Key::SystemEntityRegistry => KeyTag::SystemContractRegistry, + Key::SystemEntityRegistry => KeyTag::SystemEntityRegistry, Key::EraSummary => KeyTag::EraSummary, Key::Unbond(_) => KeyTag::Unbond, Key::ChainspecRegistry => KeyTag::ChainspecRegistry, @@ -1060,6 +1121,7 @@ impl Tagged for Key { Key::ByteCode(..) => KeyTag::ByteCode, Key::Message(_) => KeyTag::Message, Key::NamedKey(_) => KeyTag::NamedKey, + Key::TransactionInfo(_) => KeyTag::TransactionInfo, } } } @@ -1152,7 +1214,7 @@ impl ToBytes for Key { Key::Bid(_) => KEY_BID_SERIALIZED_LENGTH, Key::Withdraw(_) => KEY_WITHDRAW_SERIALIZED_LENGTH, Key::Dictionary(_) => KEY_DICTIONARY_SERIALIZED_LENGTH, - Key::SystemEntityRegistry => KEY_SYSTEM_CONTRACT_REGISTRY_SERIALIZED_LENGTH, + Key::SystemEntityRegistry => KEY_SYSTEM_ENTITY_REGISTRY_SERIALIZED_LENGTH, Key::EraSummary => KEY_ERA_SUMMARY_SERIALIZED_LENGTH, Key::Unbond(_) => KEY_UNBOND_SERIALIZED_LENGTH, Key::ChainspecRegistry => KEY_CHAINSPEC_REGISTRY_SERIALIZED_LENGTH, @@ -1164,16 +1226,21 @@ impl ToBytes for Key { } }, Key::Package(_) => KEY_PACKAGE_SERIALIZED_LENGTH, - Key::AddressableEntity(..) => { - U8_SERIALIZED_LENGTH + KEY_ID_SERIALIZED_LENGTH + ADDR_LENGTH + Key::AddressableEntity(entity_addr) => { + KEY_ID_SERIALIZED_LENGTH + entity_addr.serialized_length() } Key::ByteCode(byte_code_addr) => { - U8_SERIALIZED_LENGTH + byte_code_addr.serialized_length() + KEY_ID_SERIALIZED_LENGTH + byte_code_addr.serialized_length() } Key::Message(message_addr) => { KEY_ID_SERIALIZED_LENGTH + message_addr.serialized_length() } - Key::NamedKey(named_key) => U8_SERIALIZED_LENGTH + named_key.serialized_length(), + Key::NamedKey(named_key_addr) => { + KEY_ID_SERIALIZED_LENGTH + named_key_addr.serialized_length() + } + Key::TransactionInfo(txn_hash) => { + KEY_ID_SERIALIZED_LENGTH + txn_hash.serialized_length() + } } } @@ -1208,6 +1275,7 @@ impl ToBytes for Key { Key::ByteCode(byte_code_addr) => byte_code_addr.write_bytes(writer), Key::Message(message_addr) => message_addr.write_bytes(writer), Key::NamedKey(named_key_addr) => named_key_addr.write_bytes(writer), + Key::TransactionInfo(txn_hash) => txn_hash.write_bytes(writer), } } } @@ -1256,7 +1324,7 @@ impl FromBytes for Key { let (addr, rem) = DictionaryAddr::from_bytes(remainder)?; Ok((Key::Dictionary(addr), rem)) } - tag if tag == KeyTag::SystemContractRegistry as u8 => { + tag if tag == KeyTag::SystemEntityRegistry as u8 => { let (_, rem) = <[u8; 32]>::from_bytes(remainder)?; Ok((Key::SystemEntityRegistry, rem)) } @@ -1300,6 +1368,10 @@ impl FromBytes for Key { let (named_key_addr, rem) = NamedKeyAddr::from_bytes(remainder)?; Ok((Key::NamedKey(named_key_addr), rem)) } + tag if tag == KeyTag::TransactionInfo as u8 => { + let (txn_hash, rem) = TransactionHash::from_bytes(remainder)?; + Ok((Key::TransactionInfo(txn_hash), rem)) + } _ => Err(Error::Formatting), } } @@ -1331,13 +1403,14 @@ fn please_add_to_distribution_impl(key: Key) { Key::ByteCode(..) => unimplemented!(), Key::Message(_) => unimplemented!(), Key::NamedKey(_) => unimplemented!(), + Key::TransactionInfo(_) => unimplemented!(), } } #[cfg(any(feature = "testing", test))] impl Distribution for Standard { fn sample(&self, rng: &mut R) -> Key { - match rng.gen_range(0..=18) { + match rng.gen_range(0..=21) { 0 => Key::Account(rng.gen()), 1 => Key::Hash(rng.gen()), 2 => Key::URef(rng.gen()), @@ -1358,6 +1431,12 @@ impl Distribution for Standard { 17 => Key::AddressableEntity(rng.gen()), 18 => Key::ByteCode(rng.gen()), 19 => Key::Message(rng.gen()), + 20 => Key::NamedKey(NamedKeyAddr::new_named_key_entry(rng.gen(), rng.gen())), + 21 => Key::TransactionInfo(if rng.gen() { + TransactionHash::Deploy(DeployHash::from_raw(rng.gen())) + } else { + TransactionHash::V1(TransactionV1Hash::from_raw(rng.gen())) + }), _ => unreachable!(), } } @@ -1379,7 +1458,7 @@ mod serde_helpers { Bid(&'a AccountHash), Withdraw(&'a AccountHash), Dictionary(&'a HashAddr), - SystemContractRegistry, + SystemEntityRegistry, EraSummary, Unbond(&'a AccountHash), ChainspecRegistry, @@ -1390,6 +1469,7 @@ mod serde_helpers { ByteCode(&'a ByteCodeAddr), Message(&'a MessageAddr), NamedKey(&'a NamedKeyAddr), + TransactionInfo(&'a TransactionHash), } #[derive(Deserialize)] @@ -1405,7 +1485,7 @@ mod serde_helpers { Bid(AccountHash), Withdraw(AccountHash), Dictionary(DictionaryAddr), - SystemContractRegistry, + SystemEntityRegistry, EraSummary, Unbond(AccountHash), ChainspecRegistry, @@ -1416,6 +1496,7 @@ mod serde_helpers { ByteCode(ByteCodeAddr), Message(MessageAddr), NamedKey(NamedKeyAddr), + TransactionInfo(TransactionHash), } impl<'a> From<&'a Key> for BinarySerHelper<'a> { @@ -1431,7 +1512,7 @@ mod serde_helpers { Key::Bid(account_hash) => BinarySerHelper::Bid(account_hash), Key::Withdraw(account_hash) => BinarySerHelper::Withdraw(account_hash), Key::Dictionary(addr) => BinarySerHelper::Dictionary(addr), - Key::SystemEntityRegistry => BinarySerHelper::SystemContractRegistry, + Key::SystemEntityRegistry => BinarySerHelper::SystemEntityRegistry, Key::EraSummary => BinarySerHelper::EraSummary, Key::Unbond(account_hash) => BinarySerHelper::Unbond(account_hash), Key::ChainspecRegistry => BinarySerHelper::ChainspecRegistry, @@ -1443,7 +1524,8 @@ mod serde_helpers { BinarySerHelper::AddressableEntity(entity_addr) } Key::ByteCode(byte_code_addr) => BinarySerHelper::ByteCode(byte_code_addr), - Key::NamedKey(named_key) => BinarySerHelper::NamedKey(named_key), + Key::NamedKey(named_key_addr) => BinarySerHelper::NamedKey(named_key_addr), + Key::TransactionInfo(txn_hash) => BinarySerHelper::TransactionInfo(txn_hash), } } } @@ -1461,7 +1543,7 @@ mod serde_helpers { BinaryDeserHelper::Bid(account_hash) => Key::Bid(account_hash), BinaryDeserHelper::Withdraw(account_hash) => Key::Withdraw(account_hash), BinaryDeserHelper::Dictionary(addr) => Key::Dictionary(addr), - BinaryDeserHelper::SystemContractRegistry => Key::SystemEntityRegistry, + BinaryDeserHelper::SystemEntityRegistry => Key::SystemEntityRegistry, BinaryDeserHelper::EraSummary => Key::EraSummary, BinaryDeserHelper::Unbond(account_hash) => Key::Unbond(account_hash), BinaryDeserHelper::ChainspecRegistry => Key::ChainspecRegistry, @@ -1474,6 +1556,7 @@ mod serde_helpers { } BinaryDeserHelper::ByteCode(byte_code_addr) => Key::ByteCode(byte_code_addr), BinaryDeserHelper::NamedKey(named_key_addr) => Key::NamedKey(named_key_addr), + BinaryDeserHelper::TransactionInfo(txn_hash) => Key::TransactionInfo(txn_hash), } } } @@ -1514,7 +1597,7 @@ mod tests { AccessRights, URef, }; - const ENTITY_PREFIX: &str = "addressable-entity-"; + const ENTITY_PREFIX: &str = "entity-addr-"; const ACCOUNT_ENTITY_PREFIX: &str = "account-"; const BYTE_CODE_PREFIX: &str = "byte-code-"; @@ -1533,22 +1616,22 @@ mod tests { const DELEGATOR_BID_KEY: Key = Key::BidAddr(BidAddr::new_delegator_addr(([2; 32], [9; 32]))); const WITHDRAW_KEY: Key = Key::Withdraw(AccountHash::new([42; 32])); const DICTIONARY_KEY: Key = Key::Dictionary([42; 32]); - const SYSTEM_CONTRACT_REGISTRY_KEY: Key = Key::SystemEntityRegistry; + const SYSTEM_ENTITY_REGISTRY_KEY: Key = Key::SystemEntityRegistry; const ERA_SUMMARY_KEY: Key = Key::EraSummary; const UNBOND_KEY: Key = Key::Unbond(AccountHash::new([42; 32])); const CHAINSPEC_REGISTRY_KEY: Key = Key::ChainspecRegistry; const CHECKSUM_REGISTRY_KEY: Key = Key::ChecksumRegistry; const PACKAGE_KEY: Key = Key::Package([42; 32]); const ADDRESSABLE_ENTITY_SYSTEM_KEY: Key = - Key::AddressableEntity(EntityAddr::new_system_entity_addr([42; 32])); + Key::AddressableEntity(EntityAddr::new_system([42; 32])); const ADDRESSABLE_ENTITY_ACCOUNT_KEY: Key = - Key::AddressableEntity(EntityAddr::new_account_entity_addr([42; 32])); + Key::AddressableEntity(EntityAddr::new_account([42; 32])); const ADDRESSABLE_ENTITY_SMART_CONTRACT_KEY: Key = - Key::AddressableEntity(EntityAddr::new_contract_entity_addr([42; 32])); + Key::AddressableEntity(EntityAddr::new_smart_contract([42; 32])); const BYTE_CODE_EMPTY_KEY: Key = Key::ByteCode(ByteCodeAddr::Empty); const BYTE_CODE_V1_WASM_KEY: Key = Key::ByteCode(ByteCodeAddr::V1CasperWasm([42; 32])); const MESSAGE_TOPIC_KEY: Key = Key::Message(MessageAddr::new_topic_addr( - AddressableEntityHash::new([42u8; 32]), + AddressableEntityHash::new([42; 32]), TopicNameHash::new([42; 32]), )); const MESSAGE_KEY: Key = Key::Message(MessageAddr::new_message_addr( @@ -1557,9 +1640,13 @@ mod tests { 15, )); const NAMED_KEY: Key = Key::NamedKey(NamedKeyAddr::new_named_key_entry( - EntityAddr::new_contract_entity_addr([42; 32]), + EntityAddr::new_smart_contract([42; 32]), [43; 32], )); + const TRANSACTION_INFO_DEPLOY_KEY: Key = + Key::TransactionInfo(TransactionHash::Deploy(DeployHash::from_raw([42; 32]))); + const TRANSACTION_INFO_V1_KEY: Key = + Key::TransactionInfo(TransactionHash::V1(TransactionV1Hash::from_raw([42; 32]))); const KEYS: &[Key] = &[ ACCOUNT_KEY, HASH_KEY, @@ -1571,7 +1658,7 @@ mod tests { BID_KEY, WITHDRAW_KEY, DICTIONARY_KEY, - SYSTEM_CONTRACT_REGISTRY_KEY, + SYSTEM_ENTITY_REGISTRY_KEY, ERA_SUMMARY_KEY, UNBOND_KEY, CHAINSPEC_REGISTRY_KEY, @@ -1588,6 +1675,7 @@ mod tests { MESSAGE_TOPIC_KEY, MESSAGE_KEY, NAMED_KEY, + TRANSACTION_INFO_V1_KEY, ]; const HEX_STRING: &str = "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"; const TOPIC_NAME_HEX_STRING: &str = @@ -1697,9 +1785,9 @@ mod tests { format!("Key::Dictionary({})", HEX_STRING) ); assert_eq!( - format!("{}", SYSTEM_CONTRACT_REGISTRY_KEY), + format!("{}", SYSTEM_ENTITY_REGISTRY_KEY), format!( - "Key::SystemContractRegistry({})", + "Key::SystemEntityRegistry({})", base16::encode_lower(&PADDING_BYTES) ) ); @@ -1756,14 +1844,21 @@ mod tests { format!("{}", MESSAGE_TOPIC_KEY), format!("Key::Message({}-{})", HEX_STRING, HEX_STRING) ); - assert_eq!( format!("{}", MESSAGE_KEY), format!( "Key::Message({}-{}-{})", HEX_STRING, TOPIC_NAME_HEX_STRING, MESSAGE_INDEX_HEX_STRING ) - ) + ); + assert_eq!( + format!("{}", TRANSACTION_INFO_DEPLOY_KEY), + format!("Key::TransactionInfo(deploy-{})", HEX_STRING) + ); + assert_eq!( + format!("{}", TRANSACTION_INFO_V1_KEY), + format!("Key::TransactionInfo(txn-v1-{})", HEX_STRING) + ); } #[test] @@ -1979,7 +2074,7 @@ mod tests { .unwrap_err() .to_string() .starts_with("dictionary-key from string error: ")); - assert!(Key::from_formatted_str(SYSTEM_CONTRACT_REGISTRY_PREFIX) + assert!(Key::from_formatted_str(SYSTEM_ENTITY_REGISTRY_PREFIX) .unwrap_err() .to_string() .starts_with("system-contract-registry-key from string error: ")); @@ -2023,6 +2118,11 @@ mod tests { .to_string() .starts_with("byte-code-key from string error: ") ); + println!("{}", Key::from_formatted_str(TXN_INFO_PREFIX).unwrap_err()); + assert!(Key::from_formatted_str(TXN_INFO_PREFIX) + .unwrap_err() + .to_string() + .starts_with("transaction-info-key from string error: ")); let invalid_prefix = "a-0000000000000000000000000000000000000000000000000000000000000000"; assert_eq!( Key::from_formatted_str(invalid_prefix) @@ -2097,15 +2197,11 @@ mod tests { round_trip(&Key::Dictionary(zeros)); round_trip(&Key::Unbond(AccountHash::new(zeros))); round_trip(&Key::Package(zeros)); - round_trip(&Key::AddressableEntity(EntityAddr::new_system_entity_addr( + round_trip(&Key::AddressableEntity(EntityAddr::new_system(zeros))); + round_trip(&Key::AddressableEntity(EntityAddr::new_account(zeros))); + round_trip(&Key::AddressableEntity(EntityAddr::new_smart_contract( zeros, ))); - round_trip(&Key::AddressableEntity( - EntityAddr::new_account_entity_addr(zeros), - )); - round_trip(&Key::AddressableEntity( - EntityAddr::new_contract_entity_addr(zeros), - )); round_trip(&Key::ByteCode(ByteCodeAddr::Empty)); round_trip(&Key::ByteCode(ByteCodeAddr::V1CasperWasm(zeros))); round_trip(&Key::Message(MessageAddr::new_topic_addr( @@ -2117,5 +2213,11 @@ mod tests { nines.into(), 1, ))); + round_trip(&Key::TransactionInfo(TransactionHash::Deploy( + DeployHash::from_raw(zeros), + ))); + round_trip(&Key::TransactionInfo(TransactionHash::V1( + TransactionV1Hash::from_raw(zeros), + ))); } } diff --git a/types/src/lib.rs b/types/src/lib.rs index f2ebb42973..f0b85a088e 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -52,7 +52,7 @@ pub mod gens; mod json_pretty_printer; mod key; mod motes; -pub mod package; +mod package; mod phase; mod protocol_version; mod semver; @@ -64,6 +64,7 @@ mod tagged; pub mod testing; mod timestamp; mod transaction; +mod transaction_info; mod transfer; mod transfer_result; mod uint; @@ -98,9 +99,8 @@ pub use block::{ }; #[cfg(any(all(feature = "std", feature = "testing"), test))] pub use block::{TestBlockBuilder, TestBlockV1Builder}; - pub use block_time::{BlockTime, BLOCKTIME_SERIALIZED_LENGTH}; -pub use byte_code::{ByteCode, ByteCodeAddr, ByteCodeHash, ByteCodeKind}; +pub use byte_code::{ByteCode, ByteCodeAddr, ByteCodeHash, ByteCodeKind, ACCOUNT_BYTE_CODE_HASH}; #[cfg(any(feature = "std", test))] pub use chainspec::{ AccountConfig, AccountsConfig, ActivationPoint, AdministratorAccount, AuctionCosts, @@ -111,7 +111,7 @@ pub use chainspec::{ HostFunction, HostFunctionCost, HostFunctionCosts, LegacyRequiredFinality, MessageLimits, MintCosts, NetworkConfig, OpcodeCosts, ProtocolConfig, ProtocolUpgradeConfig, RefundHandling, StandardPaymentCosts, StorageCosts, SystemConfig, TransactionConfig, TransactionV1Config, - ValidatorConfig, WasmConfig, DEFAULT_HOST_FUNCTION_NEW_DICTIONARY, + ValidatorConfig, WasmConfig, DEFAULT_HOST_FUNCTION_NEW_DICTIONARY, DEFAULT_REFUND_HANDLING, }; #[cfg(any(all(feature = "std", feature = "testing"), test))] pub use chainspec::{ @@ -124,15 +124,13 @@ pub use chainspec::{ DEFAULT_CONTROL_FLOW_IF_OPCODE, DEFAULT_CONTROL_FLOW_LOOP_OPCODE, DEFAULT_CONTROL_FLOW_RETURN_OPCODE, DEFAULT_CONTROL_FLOW_SELECT_OPCODE, DEFAULT_CONVERSION_COST, DEFAULT_CURRENT_MEMORY_COST, DEFAULT_DELEGATE_COST, DEFAULT_DIV_COST, - DEFAULT_FEE_HANDLING, DEFAULT_GLOBAL_COST, DEFAULT_GROW_MEMORY_COST, - DEFAULT_INTEGER_COMPARISON_COST, DEFAULT_LOAD_COST, DEFAULT_LOCAL_COST, - DEFAULT_MAX_PAYMENT_MOTES, DEFAULT_MAX_STACK_HEIGHT, DEFAULT_MIN_TRANSFER_MOTES, - DEFAULT_MUL_COST, DEFAULT_NEW_DICTIONARY_COST, DEFAULT_NOP_COST, DEFAULT_REFUND_HANDLING, + DEFAULT_GLOBAL_COST, DEFAULT_GROW_MEMORY_COST, DEFAULT_INTEGER_COMPARISON_COST, + DEFAULT_LOAD_COST, DEFAULT_LOCAL_COST, DEFAULT_MAX_PAYMENT_MOTES, DEFAULT_MAX_STACK_HEIGHT, + DEFAULT_MIN_TRANSFER_MOTES, DEFAULT_MUL_COST, DEFAULT_NEW_DICTIONARY_COST, DEFAULT_NOP_COST, DEFAULT_STORE_COST, DEFAULT_TRANSFER_COST, DEFAULT_UNREACHABLE_COST, DEFAULT_WASMLESS_TRANSFER_COST, DEFAULT_WASM_MAX_MEMORY, }; pub use cl_type::{named_key_type, CLType, CLTyped}; - pub use cl_value::{ handle_stored_dictionary_value, CLTypeMismatch, CLValue, CLValueError, ChecksumRegistry, DictionaryValue as CLValueDictionary, SystemEntityRegistry, @@ -159,6 +157,7 @@ pub use motes::Motes; #[doc(inline)] pub use package::{ EntityVersion, EntityVersionKey, EntityVersions, Group, Groups, Package, PackageHash, + PackageStatus, ENTITY_INITIAL_VERSION, }; pub use phase::{Phase, PHASE_SERIALIZED_LENGTH}; pub use protocol_version::{ProtocolVersion, VersionCheckResult}; @@ -184,6 +183,7 @@ pub use transaction::{ pub use transaction::{ DeployBuilder, DeployBuilderError, TransactionV1Builder, TransactionV1BuilderError, }; +pub use transaction_info::TransactionInfo; pub use transfer::{ FromStrError as TransferFromStrError, Transfer, TransferAddr, TRANSFER_ADDR_LENGTH, }; diff --git a/types/src/package.rs b/types/src/package.rs index 7353cec2d3..84bae3c0c6 100644 --- a/types/src/package.rs +++ b/types/src/package.rs @@ -29,20 +29,6 @@ use crate::{ AddressableEntityHash, CLType, CLTyped, HashAddr, BLAKE2B_DIGEST_LENGTH, KEY_HASH_LENGTH, }; -/// Maximum number of distinct user groups. -pub const MAX_GROUPS: u8 = 10; -/// Maximum number of URefs which can be assigned across all user groups. -pub const MAX_TOTAL_UREFS: usize = 100; - -/// The tag for Contract Packages associated with Wasm stored on chain. -pub const PACKAGE_KIND_WASM_TAG: u8 = 0; -/// The tag for Contract Package associated with a native contract implementation. -pub const PACKAGE_KIND_SYSTEM_CONTRACT_TAG: u8 = 1; -/// The tag for Contract Package associated with an Account hash. -pub const PACKAGE_KIND_ACCOUNT_TAG: u8 = 2; -/// The tag for Contract Packages associated with legacy packages. -pub const PACKAGE_KIND_LEGACY_TAG: u8 = 3; - const PACKAGE_STRING_PREFIX: &str = "contract-package-"; // We need to support the legacy prefix of "contract-package-wasm". const PACKAGE_STRING_LEGACY_EXTRA_PREFIX: &str = "wasm"; diff --git a/types/src/stored_value.rs b/types/src/stored_value.rs index d18295d78f..944d014fda 100644 --- a/types/src/stored_value.rs +++ b/types/src/stored_value.rs @@ -23,7 +23,7 @@ use crate::{ contracts::{Contract, ContractPackage}, package::Package, system::auction::{Bid, BidKind, EraInfo, UnbondingPurse, WithdrawPurse}, - AddressableEntity, ByteCode, CLValue, DeployInfo, Transfer, + AddressableEntity, ByteCode, CLValue, DeployInfo, TransactionInfo, Transfer, }; pub use type_mismatch::TypeMismatch; @@ -47,7 +47,8 @@ enum Tag { ByteCode = 14, MessageTopic = 15, Message = 16, - NamedKeyValue = 17, + NamedKey = 17, + TransactionInfo = 18, } /// A value stored in Global State. @@ -96,6 +97,8 @@ pub enum StoredValue { Message(MessageChecksum), /// A NamedKey record. NamedKey(NamedKeyValue), + /// Info about a transaction. + TransactionInfo(TransactionInfo), } impl StoredValue { @@ -223,6 +226,14 @@ impl StoredValue { } } + /// Returns a reference to the wrapped `TransactionInfo` if this is a `TransactionInfo` variant. + pub fn as_transaction_info(&self) -> Option<&TransactionInfo> { + match self { + StoredValue::TransactionInfo(txn_info) => Some(txn_info), + _ => None, + } + } + /// Returns the `CLValue` if this is a `CLValue` variant. pub fn into_cl_value(self) -> Option { match self { @@ -335,6 +346,14 @@ impl StoredValue { } } + /// Returns the `TransactionInfo` if this is a `TransactionInfo` variant. + pub fn into_transaction_info(self) -> Option { + match self { + StoredValue::TransactionInfo(txn_info) => Some(txn_info), + _ => None, + } + } + /// Returns the type name of the [`StoredValue`] enum variant. /// /// For [`CLValue`] variants it will return the name of the [`CLType`](crate::cl_type::CLType) @@ -357,7 +376,8 @@ impl StoredValue { StoredValue::Package(_) => "Package".to_string(), StoredValue::MessageTopic(_) => "MessageTopic".to_string(), StoredValue::Message(_) => "Message".to_string(), - StoredValue::NamedKey(_) => "NamedKeyValue".to_string(), + StoredValue::NamedKey(_) => "NamedKey".to_string(), + StoredValue::TransactionInfo(_) => "TransactionInfo".to_string(), } } @@ -380,7 +400,8 @@ impl StoredValue { StoredValue::ByteCode(_) => Tag::ByteCode, StoredValue::MessageTopic(_) => Tag::MessageTopic, StoredValue::Message(_) => Tag::Message, - StoredValue::NamedKey(_) => Tag::NamedKeyValue, + StoredValue::NamedKey(_) => Tag::NamedKey, + StoredValue::TransactionInfo(_) => Tag::TransactionInfo, } } } @@ -627,8 +648,22 @@ impl TryFrom for NamedKeyValue { } } +impl TryFrom for TransactionInfo { + type Error = TypeMismatch; + + fn try_from(value: StoredValue) -> Result { + match value { + StoredValue::TransactionInfo(txn_info) => Ok(txn_info), + _ => Err(TypeMismatch::new( + "TransactionInfo".to_string(), + value.type_name(), + )), + } + } +} + impl ToBytes for StoredValue { - fn to_bytes(&self) -> Result, bytesrepr::Error> { + fn to_bytes(&self) -> Result, Error> { let mut buffer = bytesrepr::allocate_buffer(self)?; self.write_bytes(&mut buffer)?; Ok(buffer) @@ -659,36 +694,35 @@ impl ToBytes for StoredValue { } StoredValue::Message(message_digest) => message_digest.serialized_length(), StoredValue::NamedKey(named_key_value) => named_key_value.serialized_length(), + StoredValue::TransactionInfo(txn_info) => txn_info.serialized_length(), } } - fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + fn write_bytes(&self, writer: &mut Vec) -> Result<(), Error> { writer.push(self.tag() as u8); match self { - StoredValue::CLValue(cl_value) => cl_value.write_bytes(writer)?, - StoredValue::Account(account) => account.write_bytes(writer)?, - StoredValue::ContractWasm(contract_wasm) => contract_wasm.write_bytes(writer)?, - StoredValue::Contract(contract_header) => contract_header.write_bytes(writer)?, - StoredValue::ContractPackage(contract_package) => { - contract_package.write_bytes(writer)? - } - StoredValue::Transfer(transfer) => transfer.write_bytes(writer)?, - StoredValue::DeployInfo(deploy_info) => deploy_info.write_bytes(writer)?, - StoredValue::EraInfo(era_info) => era_info.write_bytes(writer)?, - StoredValue::Bid(bid) => bid.write_bytes(writer)?, - StoredValue::Withdraw(unbonding_purses) => unbonding_purses.write_bytes(writer)?, - StoredValue::Unbonding(unbonding_purses) => unbonding_purses.write_bytes(writer)?, - StoredValue::AddressableEntity(entity) => entity.write_bytes(writer)?, - StoredValue::BidKind(bid_kind) => bid_kind.write_bytes(writer)?, - StoredValue::Package(package) => package.write_bytes(writer)?, - StoredValue::ByteCode(byte_code) => byte_code.write_bytes(writer)?, + StoredValue::CLValue(cl_value) => cl_value.write_bytes(writer), + StoredValue::Account(account) => account.write_bytes(writer), + StoredValue::ContractWasm(contract_wasm) => contract_wasm.write_bytes(writer), + StoredValue::Contract(contract_header) => contract_header.write_bytes(writer), + StoredValue::ContractPackage(contract_package) => contract_package.write_bytes(writer), + StoredValue::Transfer(transfer) => transfer.write_bytes(writer), + StoredValue::DeployInfo(deploy_info) => deploy_info.write_bytes(writer), + StoredValue::EraInfo(era_info) => era_info.write_bytes(writer), + StoredValue::Bid(bid) => bid.write_bytes(writer), + StoredValue::Withdraw(unbonding_purses) => unbonding_purses.write_bytes(writer), + StoredValue::Unbonding(unbonding_purses) => unbonding_purses.write_bytes(writer), + StoredValue::AddressableEntity(entity) => entity.write_bytes(writer), + StoredValue::BidKind(bid_kind) => bid_kind.write_bytes(writer), + StoredValue::Package(package) => package.write_bytes(writer), + StoredValue::ByteCode(byte_code) => byte_code.write_bytes(writer), StoredValue::MessageTopic(message_topic_summary) => { - message_topic_summary.write_bytes(writer)? + message_topic_summary.write_bytes(writer) } - StoredValue::Message(message_digest) => message_digest.write_bytes(writer)?, - StoredValue::NamedKey(named_key_value) => named_key_value.write_bytes(writer)?, - }; - Ok(()) + StoredValue::Message(message_digest) => message_digest.write_bytes(writer), + StoredValue::NamedKey(named_key_value) => named_key_value.write_bytes(writer), + StoredValue::TransactionInfo(txn_info) => txn_info.write_bytes(writer), + } } } @@ -744,11 +778,13 @@ impl FromBytes for StoredValue { }), tag if tag == Tag::Message as u8 => MessageChecksum::from_bytes(remainder) .map(|(checksum, remainder)| (StoredValue::Message(checksum), remainder)), - tag if tag == Tag::NamedKeyValue as u8 => { + tag if tag == Tag::NamedKey as u8 => { NamedKeyValue::from_bytes(remainder).map(|(named_key_value, remainder)| { (StoredValue::NamedKey(named_key_value), remainder) }) } + tag if tag == Tag::TransactionInfo as u8 => TransactionInfo::from_bytes(remainder) + .map(|(txn_info, remainder)| (StoredValue::TransactionInfo(txn_info), remainder)), _ => Err(Error::Formatting), } } @@ -794,6 +830,8 @@ mod serde_helpers { Message(&'a MessageChecksum), /// A record for NamedKey. NamedKey(&'a NamedKeyValue), + /// Info about a transaction. + TransactionInfo(&'a TransactionInfo), } #[derive(Deserialize)] @@ -834,6 +872,8 @@ mod serde_helpers { Message(MessageChecksum), /// A record for NamedKey. NamedKey(NamedKeyValue), + /// Info about a transaction. + TransactionInfo(TransactionInfo), } impl<'a> From<&'a StoredValue> for BinarySerHelper<'a> { @@ -861,6 +901,7 @@ mod serde_helpers { } StoredValue::Message(message_digest) => BinarySerHelper::Message(message_digest), StoredValue::NamedKey(payload) => BinarySerHelper::NamedKey(payload), + StoredValue::TransactionInfo(payload) => BinarySerHelper::TransactionInfo(payload), } } } @@ -892,6 +933,9 @@ mod serde_helpers { } BinaryDeserHelper::Message(message_digest) => StoredValue::Message(message_digest), BinaryDeserHelper::NamedKey(payload) => StoredValue::NamedKey(payload), + BinaryDeserHelper::TransactionInfo(payload) => { + StoredValue::TransactionInfo(payload) + } } } } diff --git a/types/src/transaction.rs b/types/src/transaction.rs index 20f6deefdd..6b4046f171 100644 --- a/types/src/transaction.rs +++ b/types/src/transaction.rs @@ -17,6 +17,7 @@ mod transaction_scheduling; mod transaction_session_kind; mod transaction_target; mod transaction_v1; +mod transfer_target; use alloc::{collections::BTreeSet, vec::Vec}; use core::fmt::{self, Debug, Display, Formatter}; @@ -41,12 +42,12 @@ use crate::{ Digest, Timestamp, }; #[cfg(feature = "json-schema")] -use crate::{account::ACCOUNT_HASH_LENGTH, SecretKey, TimeDiff, URef}; +use crate::{SecretKey, TimeDiff, URef}; pub use addressable_entity_identifier::AddressableEntityIdentifier; pub use deploy::{ Deploy, DeployApproval, DeployApprovalsHash, DeployConfigFailure, DeployDecodeFromJsonError, DeployError, DeployExcessiveSizeError, DeployFootprint, DeployHash, DeployHeader, DeployId, - ExecutableDeployItem, ExecutableDeployItemIdentifier, TransferTarget, + ExecutableDeployItem, ExecutableDeployItemIdentifier, }; #[cfg(any(feature = "std", test))] pub use deploy::{DeployBuilder, DeployBuilderError}; @@ -73,6 +74,7 @@ pub use transaction_v1::{ }; #[cfg(any(feature = "std", test))] pub use transaction_v1::{TransactionV1Builder, TransactionV1BuilderError}; +pub use transfer_target::TransferTarget; const DEPLOY_TAG: u8 = 0; const V1_TAG: u8 = 1; @@ -88,10 +90,9 @@ pub(super) static TRANSACTION: Lazy = Lazy::new(|| { "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000", ) .unwrap(); - let to = Some(AccountHash::new([40; ACCOUNT_HASH_LENGTH])); let id = Some(999); - let v1_txn = TransactionV1Builder::new_transfer(source, target, 30_000_000_000_u64, to, id) + let v1_txn = TransactionV1Builder::new_transfer(30_000_000_000_u64, Some(source), target, id) .unwrap() .with_chain_name("casper-example") .with_timestamp(*Timestamp::example()) @@ -170,6 +171,17 @@ impl Transaction { } } + /// Returns the number of Motes per unit of Gas the transaction will pay for execution. + pub fn gas_price(&self) -> u64 { + match self { + Transaction::Deploy(deploy) => deploy.gas_price(), + Transaction::V1(v1_txn) => match v1_txn.header().pricing_mode() { + PricingMode::GasPriceMultiplier(price) => *price, + PricingMode::Fixed | PricingMode::Reserved => 1, + }, + } + } + /// Returns `true` if the transaction has expired. pub fn expired(&self, current_instant: Timestamp) -> bool { match self { @@ -202,6 +214,14 @@ impl Transaction { } } + /// Returns `true` if `self` represents a native transfer deploy or a native V1 transaction. + pub fn is_native(&self) -> bool { + match self { + Transaction::Deploy(deploy) => deploy.session().is_transfer(), + Transaction::V1(v1_txn) => *v1_txn.target() == TransactionTarget::Native, + } + } + // This method is not intended to be used by third party crates. #[doc(hidden)] #[cfg(feature = "json-schema")] diff --git a/types/src/transaction/deploy.rs b/types/src/transaction/deploy.rs index 88397c8282..d4e9c558c0 100644 --- a/types/src/transaction/deploy.rs +++ b/types/src/transaction/deploy.rs @@ -70,9 +70,7 @@ pub use error::{ DecodeFromJsonError as DeployDecodeFromJsonError, DeployConfigFailure, Error as DeployError, ExcessiveSizeError as DeployExcessiveSizeError, }; -pub use executable_deploy_item::{ - ExecutableDeployItem, ExecutableDeployItemIdentifier, TransferTarget, -}; +pub use executable_deploy_item::{ExecutableDeployItem, ExecutableDeployItemIdentifier}; #[cfg(feature = "json-schema")] static DEPLOY: Lazy = Lazy::new(|| { @@ -301,6 +299,25 @@ impl Deploy { &self.approvals } + /// Consumes `self`, returning a tuple of its constituent parts. + pub fn destructure( + self, + ) -> ( + DeployHash, + DeployHeader, + ExecutableDeployItem, + ExecutableDeployItem, + BTreeSet, + ) { + ( + self.hash, + self.header, + self.payment, + self.session, + self.approvals, + ) + } + /// Adds a signature of this `Deploy`'s hash to its approvals. pub fn sign(&mut self, secret_key: &SecretKey) { let approval = DeployApproval::create(&self.hash, secret_key); diff --git a/types/src/transaction/deploy/deploy_builder.rs b/types/src/transaction/deploy/deploy_builder.rs index 7c79e0defa..b2c7c021e8 100644 --- a/types/src/transaction/deploy/deploy_builder.rs +++ b/types/src/transaction/deploy/deploy_builder.rs @@ -1,8 +1,8 @@ mod error; use super::{ - super::{InitiatorAddr, InitiatorAddrAndSecretKey}, - Deploy, DeployHash, ExecutableDeployItem, TransferTarget, + super::{InitiatorAddr, InitiatorAddrAndSecretKey, TransferTarget}, + Deploy, DeployHash, ExecutableDeployItem, }; use crate::{PublicKey, SecretKey, TimeDiff, Timestamp, URef, U512}; pub use error::DeployBuilderError; @@ -62,11 +62,11 @@ impl<'a> DeployBuilder<'a> { /// * that payment code is provided by either calling /// [`with_standard_payment`](Self::with_standard_payment) or /// [`with_payment`](Self::with_payment) - pub fn new_transfer, A: Into>( + pub fn new_transfer, A: Into, T: Into>( chain_name: C, amount: A, maybe_source: Option, - target: TransferTarget, + target: T, maybe_transfer_id: Option, ) -> Self { let session = diff --git a/types/src/transaction/deploy/executable_deploy_item.rs b/types/src/transaction/deploy/executable_deploy_item.rs index e553a87c9d..283c2ad45e 100644 --- a/types/src/transaction/deploy/executable_deploy_item.rs +++ b/types/src/transaction/deploy/executable_deploy_item.rs @@ -16,14 +16,13 @@ use serde::{Deserialize, Serialize}; #[cfg(doc)] use super::Deploy; use crate::{ - account::AccountHash, addressable_entity::DEFAULT_ENTRY_POINT_NAME, bytesrepr::{self, Bytes, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, package::{EntityVersion, PackageHash}, runtime_args, serde_helpers, system::mint::ARG_AMOUNT, AddressableEntityHash, AddressableEntityIdentifier, Gas, Motes, PackageIdentifier, Phase, - PublicKey, RuntimeArgs, URef, U512, + RuntimeArgs, TransferTarget, URef, U512, }; #[cfg(any(feature = "testing", test))] use crate::{testing::TestRng, CLValue}; @@ -218,10 +217,10 @@ impl ExecutableDeployItem { /// Returns a new `ExecutableDeployItem` suitable for use as session code for a transfer. /// /// If `maybe_source` is None, the account's main purse is used as the source. - pub fn new_transfer>( + pub fn new_transfer, T: Into>( amount: A, maybe_source: Option, - target: TransferTarget, + target: T, maybe_transfer_id: Option, ) -> Self { let mut args = RuntimeArgs::new(); @@ -233,7 +232,7 @@ impl ExecutableDeployItem { .expect("should serialize source arg"); } - match target { + match target.into() { TransferTarget::PublicKey(public_key) => args .insert(TRANSFER_ARG_TARGET, public_key) .expect("should serialize public key target arg"), @@ -801,17 +800,6 @@ impl Distribution for Standard { } } -/// The various types which can be used as the `target` runtime argument of a native transfer. -#[derive(Clone, Ord, PartialOrd, Eq, PartialEq)] -pub enum TransferTarget { - /// A public key. - PublicKey(PublicKey), - /// An account hash. - AccountHash(AccountHash), - /// A URef. - URef(URef), -} - #[cfg(test)] mod tests { use super::*; diff --git a/types/src/transaction/initiator_addr.rs b/types/src/transaction/initiator_addr.rs index 56cd96410a..373050b365 100644 --- a/types/src/transaction/initiator_addr.rs +++ b/types/src/transaction/initiator_addr.rs @@ -58,6 +58,18 @@ impl InitiatorAddr { } } +impl From for InitiatorAddr { + fn from(public_key: PublicKey) -> Self { + InitiatorAddr::PublicKey(public_key) + } +} + +impl From for InitiatorAddr { + fn from(account_hash: AccountHash) -> Self { + InitiatorAddr::AccountHash(account_hash) + } +} + impl Display for InitiatorAddr { fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { match self { diff --git a/types/src/transaction/transaction_header.rs b/types/src/transaction/transaction_header.rs index d1a864bb84..588d84bd03 100644 --- a/types/src/transaction/transaction_header.rs +++ b/types/src/transaction/transaction_header.rs @@ -32,14 +32,14 @@ pub enum TransactionHeader { } impl From for TransactionHeader { - fn from(hash: DeployHeader) -> Self { - Self::Deploy(hash) + fn from(header: DeployHeader) -> Self { + Self::Deploy(header) } } impl From for TransactionHeader { - fn from(hash: TransactionV1Header) -> Self { - Self::V1(hash) + fn from(header: TransactionV1Header) -> Self { + Self::V1(header) } } diff --git a/types/src/transaction/transaction_invocation_target.rs b/types/src/transaction/transaction_invocation_target.rs index 89de3655a5..565680b661 100644 --- a/types/src/transaction/transaction_invocation_target.rs +++ b/types/src/transaction/transaction_invocation_target.rs @@ -75,8 +75,8 @@ pub enum TransactionInvocationTarget { impl TransactionInvocationTarget { /// Returns a new `TransactionInvocationTarget::InvocableEntity`. - pub fn new_invocable_entity(addr: HashAddr) -> Self { - TransactionInvocationTarget::InvocableEntity(addr) + pub fn new_invocable_entity(hash: AddressableEntityHash) -> Self { + TransactionInvocationTarget::InvocableEntity(hash.value()) } /// Returns a new `TransactionInvocationTarget::InvocableEntityAlias`. @@ -85,8 +85,11 @@ impl TransactionInvocationTarget { } /// Returns a new `TransactionInvocationTarget::Package`. - pub fn new_package(addr: PackageAddr, version: Option) -> Self { - TransactionInvocationTarget::Package { addr, version } + pub fn new_package(hash: PackageHash, version: Option) -> Self { + TransactionInvocationTarget::Package { + addr: hash.value(), + version, + } } /// Returns a new `TransactionInvocationTarget::PackageAlias`. diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index 3e7f141773..61cc1bfe62 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -184,6 +184,11 @@ impl TransactionV1 { self.body.args() } + /// Consumes `self`, returning the runtime args of the transaction. + pub fn take_args(self) -> RuntimeArgs { + self.body.take_args() + } + /// Returns the target of the transaction. pub fn target(&self) -> &TransactionTarget { self.body.target() @@ -209,6 +214,18 @@ impl TransactionV1 { &self.approvals } + /// Consumes `self`, returning a tuple of its constituent parts. + pub fn destructure( + self, + ) -> ( + TransactionV1Hash, + TransactionV1Header, + TransactionV1Body, + BTreeSet, + ) { + (self.hash, self.header, self.body, self.approvals) + } + /// Adds a signature of this transaction's hash to its approvals. pub fn sign(&mut self, secret_key: &SecretKey) { let approval = TransactionV1Approval::create(&self.hash, secret_key); diff --git a/types/src/transaction/transaction_v1/errors_v1.rs b/types/src/transaction/transaction_v1/errors_v1.rs index d41cedc092..affc2e932f 100644 --- a/types/src/transaction/transaction_v1/errors_v1.rs +++ b/types/src/transaction/transaction_v1/errors_v1.rs @@ -1,4 +1,4 @@ -use alloc::string::String; +use alloc::{string::String, vec::Vec}; use core::{ array::TryFromSliceError, fmt::{self, Display, Formatter}, @@ -13,7 +13,7 @@ use serde::Serialize; use super::super::TransactionEntryPoint; #[cfg(doc)] use super::TransactionV1; -use crate::{crypto, CLType, TimeDiff, Timestamp, U512}; +use crate::{bytesrepr, crypto, CLType, DisplayIter, TimeDiff, Timestamp, U512}; /// Returned when a [`TransactionV1`] fails validation. #[derive(Clone, Eq, PartialEq, Debug)] @@ -97,16 +97,24 @@ pub enum TransactionV1ConfigFailure { arg_name: String, }, - /// Given runtime arg is not expected type. + /// Given runtime arg is not one of the expected types. UnexpectedArgType { /// The name of the invalid arg. arg_name: String, - /// The expected type for the given runtime arg. - expected: CLType, + /// The choice of valid types for the given runtime arg. + expected: Vec, /// The provided type of the given runtime arg. got: CLType, }, + /// Failed to deserialize the given runtime arg. + InvalidArg { + /// The name of the invalid arg. + arg_name: String, + /// The deserialization error. + error: bytesrepr::Error, + }, + /// Insufficient transfer amount. InsufficientTransferAmount { /// The minimum transfer amount. @@ -217,9 +225,13 @@ impl Display for TransactionV1ConfigFailure { } => { write!( formatter, - "expected type of '{arg_name}' runtime argument to be {expected}, but got {got}" + "expected type of '{arg_name}' runtime argument to be one of {}, but got {got}", + DisplayIter::new(expected) ) } + TransactionV1ConfigFailure::InvalidArg { arg_name, error } => { + write!(formatter, "invalid runtime argument '{arg_name}': {error}") + } TransactionV1ConfigFailure::InsufficientTransferAmount { minimum, attempted } => { write!( formatter, @@ -250,6 +262,7 @@ impl StdError for TransactionV1ConfigFailure { fn source(&self) -> Option<&(dyn StdError + 'static)> { match self { TransactionV1ConfigFailure::InvalidApproval { error, .. } => Some(error), + TransactionV1ConfigFailure::InvalidArg { error, .. } => Some(error), TransactionV1ConfigFailure::InvalidChainName { .. } | TransactionV1ConfigFailure::ExcessiveSize(_) | TransactionV1ConfigFailure::ExcessiveTimeToLive { .. } diff --git a/types/src/transaction/transaction_v1/transaction_v1_body.rs b/types/src/transaction/transaction_v1/transaction_v1_body.rs index 1c11f62853..b10a0a0883 100644 --- a/types/src/transaction/transaction_v1/transaction_v1_body.rs +++ b/types/src/transaction/transaction_v1/transaction_v1_body.rs @@ -24,7 +24,7 @@ use crate::bytesrepr::{self, FromBytes, ToBytes}; #[cfg(any(all(feature = "std", feature = "testing"), test))] use crate::{ bytesrepr::Bytes, testing::TestRng, PublicKey, TransactionInvocationTarget, TransactionRuntime, - TransactionSessionKind, + TransactionSessionKind, TransferTarget, }; /// The body of a [`TransactionV1`]. @@ -68,6 +68,11 @@ impl TransactionV1Body { &self.args } + /// Consumes `self`, returning the runtime args of the transaction. + pub fn take_args(self) -> RuntimeArgs { + self.args + } + /// Returns the target of the transaction. pub fn target(&self) -> &TransactionTarget { &self.target @@ -83,6 +88,18 @@ impl TransactionV1Body { &self.scheduling } + /// Consumes `self`, returning its constituent parts. + pub fn destructure( + self, + ) -> ( + RuntimeArgs, + TransactionTarget, + TransactionEntryPoint, + TransactionScheduling, + ) { + (self.args, self.target, self.entry_point, self.scheduling) + } + #[cfg(any(feature = "std", test))] pub(super) fn is_valid( &self, @@ -178,16 +195,14 @@ impl TransactionV1Body { pub fn random(rng: &mut TestRng) -> Self { match rng.gen_range(0..8) { 0 => { - let source = rng.gen(); - let target = rng.gen(); let amount = rng.gen_range( TransactionConfig::default().native_transfer_minimum_motes..=u64::MAX, ); - let maybe_to = rng.gen::().then(|| rng.gen()); + let maybe_source = if rng.gen() { Some(rng.gen()) } else { None }; + let target = TransferTarget::random(rng); let maybe_id = rng.gen::().then(|| rng.gen()); - let args = - arg_handling::new_transfer_args(source, target, amount, maybe_to, maybe_id) - .unwrap(); + let args = arg_handling::new_transfer_args(amount, maybe_source, target, maybe_id) + .unwrap(); TransactionV1Body::new( args, TransactionTarget::Native, diff --git a/types/src/transaction/transaction_v1/transaction_v1_body/arg_handling.rs b/types/src/transaction/transaction_v1/transaction_v1_body/arg_handling.rs index bc0ac80ae6..f7d4fc7bf8 100644 --- a/types/src/transaction/transaction_v1/transaction_v1_body/arg_handling.rs +++ b/types/src/transaction/transaction_v1/transaction_v1_body/arg_handling.rs @@ -6,13 +6,12 @@ use super::super::TransactionV1ConfigFailure; use crate::{ account::AccountHash, bytesrepr::{FromBytes, ToBytes}, - CLTyped, CLValue, CLValueError, PublicKey, RuntimeArgs, URef, U512, + CLType, CLTyped, CLValue, CLValueError, PublicKey, RuntimeArgs, TransferTarget, URef, U512, }; -const TRANSFER_ARG_SOURCE: RequiredArg = RequiredArg::new("source"); -const TRANSFER_ARG_TARGET: RequiredArg = RequiredArg::new("target"); const TRANSFER_ARG_AMOUNT: RequiredArg = RequiredArg::new("amount"); -const TRANSFER_ARG_TO: OptionalArg = OptionalArg::new("to"); +const TRANSFER_ARG_SOURCE: OptionalArg = OptionalArg::new("source"); +const TRANSFER_ARG_TARGET: &str = "target"; const TRANSFER_ARG_ID: OptionalArg = OptionalArg::new("id"); const ADD_BID_ARG_PUBLIC_KEY: RequiredArg = RequiredArg::new("public_key"); @@ -106,35 +105,48 @@ fn parse_cl_value( cl_value: &CLValue, arg_name: &str, ) -> Result { - cl_value.to_t::().map_err(|_| { - debug!( - "expected runtime argument '{arg_name}' to be of type {}, but is {}", - T::cl_type(), - cl_value.cl_type() - ); - TransactionV1ConfigFailure::UnexpectedArgType { + cl_value.to_t::().map_err(|error| match error { + CLValueError::Serialization(error) => TransactionV1ConfigFailure::InvalidArg { arg_name: arg_name.to_string(), - expected: T::cl_type(), - got: cl_value.cl_type().clone(), + error, + }, + CLValueError::Type(_) => { + debug!( + "expected runtime argument '{arg_name}' to be of type {}, but is {}", + T::cl_type(), + cl_value.cl_type() + ); + TransactionV1ConfigFailure::UnexpectedArgType { + arg_name: arg_name.to_string(), + expected: vec![T::cl_type()], + got: cl_value.cl_type().clone(), + } } }) } /// Creates a `RuntimeArgs` suitable for use in a transfer transaction. -pub(in crate::transaction::transaction_v1) fn new_transfer_args>( - source: URef, - target: URef, +pub(in crate::transaction::transaction_v1) fn new_transfer_args< + A: Into, + T: Into, +>( amount: A, - maybe_to: Option, + maybe_source: Option, + target: T, maybe_id: Option, ) -> Result { let mut args = RuntimeArgs::new(); - TRANSFER_ARG_SOURCE.insert(&mut args, source)?; - TRANSFER_ARG_TARGET.insert(&mut args, target)?; - TRANSFER_ARG_AMOUNT.insert(&mut args, amount.into())?; - if let Some(to) = maybe_to { - TRANSFER_ARG_TO.insert(&mut args, to)?; + if let Some(source) = maybe_source { + TRANSFER_ARG_SOURCE.insert(&mut args, source)?; } + match target.into() { + TransferTarget::PublicKey(public_key) => args.insert(TRANSFER_ARG_TARGET, public_key)?, + TransferTarget::AccountHash(account_hash) => { + args.insert(TRANSFER_ARG_TARGET, account_hash)? + } + TransferTarget::URef(uref) => args.insert(TRANSFER_ARG_TARGET, uref)?, + } + TRANSFER_ARG_AMOUNT.insert(&mut args, amount.into())?; if let Some(id) = maybe_id { TRANSFER_ARG_ID.insert(&mut args, id)?; } @@ -146,8 +158,6 @@ pub(in crate::transaction::transaction_v1) fn has_valid_transfer_args( args: &RuntimeArgs, native_transfer_minimum_motes: u64, ) -> Result<(), TransactionV1ConfigFailure> { - let _source = TRANSFER_ARG_SOURCE.get(args)?; - let _target = TRANSFER_ARG_TARGET.get(args)?; let amount = TRANSFER_ARG_AMOUNT.get(args)?; if amount < U512::from(native_transfer_minimum_motes) { debug!( @@ -160,7 +170,41 @@ pub(in crate::transaction::transaction_v1) fn has_valid_transfer_args( attempted: amount, }); } - let _maybe_to = TRANSFER_ARG_TO.get(args)?; + let _source = TRANSFER_ARG_SOURCE.get(args)?; + + let target_cl_value = args.get(TRANSFER_ARG_TARGET).ok_or_else(|| { + debug!("missing required runtime argument '{TRANSFER_ARG_TARGET}'"); + TransactionV1ConfigFailure::MissingArg { + arg_name: TRANSFER_ARG_TARGET.to_string(), + } + })?; + match target_cl_value.cl_type() { + CLType::PublicKey => { + let _ = parse_cl_value::(target_cl_value, TRANSFER_ARG_TARGET); + } + CLType::ByteArray(32) => { + let _ = parse_cl_value::(target_cl_value, TRANSFER_ARG_TARGET); + } + CLType::URef => { + let _ = parse_cl_value::(target_cl_value, TRANSFER_ARG_TARGET); + } + _ => { + debug!( + "expected runtime argument '{TRANSFER_ARG_TARGET}' to be of type {}, {} or {}, + but is {}", + CLType::PublicKey, + CLType::ByteArray(32), + CLType::URef, + target_cl_value.cl_type() + ); + return Err(TransactionV1ConfigFailure::UnexpectedArgType { + arg_name: TRANSFER_ARG_TARGET.to_string(), + expected: vec![CLType::PublicKey, CLType::ByteArray(32), CLType::URef], + got: target_cl_value.cl_type().clone(), + }); + } + } + let _maybe_id = TRANSFER_ARG_ID.get(args)?; Ok(()) } @@ -291,12 +335,31 @@ mod tests { fn should_validate_transfer_args() { let rng = &mut TestRng::new(); let min_motes = 10_u64; - // Check random args, within motes limit. + // Check random args, PublicKey target, within motes limit. let args = new_transfer_args( - rng.gen(), - rng.gen(), U512::from(rng.gen_range(min_motes..=u64::MAX)), rng.gen::().then(|| rng.gen()), + PublicKey::random(rng), + rng.gen::().then(|| rng.gen()), + ) + .unwrap(); + has_valid_transfer_args(&args, min_motes).unwrap(); + + // Check random args, AccountHash target, within motes limit. + let args = new_transfer_args( + U512::from(rng.gen_range(min_motes..=u64::MAX)), + rng.gen::().then(|| rng.gen()), + rng.gen::(), + rng.gen::().then(|| rng.gen()), + ) + .unwrap(); + has_valid_transfer_args(&args, min_motes).unwrap(); + + // Check random args, URef target, within motes limit. + let args = new_transfer_args( + U512::from(rng.gen_range(min_motes..=u64::MAX)), + rng.gen::().then(|| rng.gen()), + rng.gen::(), rng.gen::().then(|| rng.gen()), ) .unwrap(); @@ -304,10 +367,9 @@ mod tests { // Check at minimum motes limit. let args = new_transfer_args( - rng.gen(), - rng.gen(), U512::from(min_motes), rng.gen::().then(|| rng.gen()), + PublicKey::random(rng), rng.gen::().then(|| rng.gen()), ) .unwrap(); @@ -315,10 +377,9 @@ mod tests { // Check with extra arg. let mut args = new_transfer_args( - rng.gen(), - rng.gen(), U512::from(min_motes), rng.gen::().then(|| rng.gen()), + PublicKey::random(rng), rng.gen::().then(|| rng.gen()), ) .unwrap(); @@ -332,9 +393,8 @@ mod tests { let min_motes = 10_u64; let args = runtime_args! { - TRANSFER_ARG_SOURCE.name => rng.gen::(), - TRANSFER_ARG_TARGET.name => rng.gen::(), - TRANSFER_ARG_AMOUNT.name => U512::from(min_motes - 1) + TRANSFER_ARG_AMOUNT.name => U512::from(min_motes - 1), + TRANSFER_ARG_TARGET => PublicKey::random(rng) }; let expected_error = TransactionV1ConfigFailure::InsufficientTransferAmount { @@ -353,26 +413,12 @@ mod tests { let rng = &mut TestRng::new(); let min_motes = 10_u64; - // Missing "source". - let args = runtime_args! { - TRANSFER_ARG_TARGET.name => rng.gen::(), - TRANSFER_ARG_AMOUNT.name => U512::from(min_motes) - }; - let expected_error = TransactionV1ConfigFailure::MissingArg { - arg_name: TRANSFER_ARG_SOURCE.name.to_string(), - }; - assert_eq!( - has_valid_transfer_args(&args, min_motes), - Err(expected_error) - ); - // Missing "target". let args = runtime_args! { - TRANSFER_ARG_SOURCE.name => rng.gen::(), - TRANSFER_ARG_AMOUNT.name => U512::from(min_motes) + TRANSFER_ARG_AMOUNT.name => U512::from(min_motes), }; let expected_error = TransactionV1ConfigFailure::MissingArg { - arg_name: TRANSFER_ARG_TARGET.name.to_string(), + arg_name: TRANSFER_ARG_TARGET.to_string(), }; assert_eq!( has_valid_transfer_args(&args, min_motes), @@ -381,8 +427,7 @@ mod tests { // Missing "amount". let args = runtime_args! { - TRANSFER_ARG_SOURCE.name => rng.gen::(), - TRANSFER_ARG_TARGET.name => rng.gen::() + TRANSFER_ARG_TARGET => PublicKey::random(rng) }; let expected_error = TransactionV1ConfigFailure::MissingArg { arg_name: TRANSFER_ARG_AMOUNT.name.to_string(), @@ -398,32 +443,30 @@ mod tests { let rng = &mut TestRng::new(); let min_motes = 10_u64; - // Wrong "source" type (a required arg). + // Wrong "target" type (a required arg). let args = runtime_args! { - TRANSFER_ARG_SOURCE.name => 1_u8, - TRANSFER_ARG_TARGET.name => rng.gen::(), - TRANSFER_ARG_AMOUNT.name => U512::from(min_motes) + TRANSFER_ARG_AMOUNT.name => U512::from(min_motes), + TRANSFER_ARG_TARGET => "wrong" }; let expected_error = TransactionV1ConfigFailure::UnexpectedArgType { - arg_name: TRANSFER_ARG_SOURCE.name.to_string(), - expected: CLType::URef, - got: CLType::U8, + arg_name: TRANSFER_ARG_TARGET.to_string(), + expected: vec![CLType::PublicKey, CLType::ByteArray(32), CLType::URef], + got: CLType::String, }; assert_eq!( has_valid_transfer_args(&args, min_motes), Err(expected_error) ); - // Wrong "to" type (an optional arg). + // Wrong "source" type (an optional arg). let args = runtime_args! { - TRANSFER_ARG_SOURCE.name => rng.gen::(), - TRANSFER_ARG_TARGET.name => rng.gen::(), TRANSFER_ARG_AMOUNT.name => U512::from(min_motes), - TRANSFER_ARG_TO.name => 1_u8 + TRANSFER_ARG_SOURCE.name => 1_u8, + TRANSFER_ARG_TARGET => PublicKey::random(rng) }; let expected_error = TransactionV1ConfigFailure::UnexpectedArgType { - arg_name: TRANSFER_ARG_TO.name.to_string(), - expected: Option::::cl_type(), + arg_name: TRANSFER_ARG_SOURCE.name.to_string(), + expected: vec![Option::::cl_type()], got: CLType::U8, }; assert_eq!( @@ -493,7 +536,7 @@ mod tests { }; let expected_error = TransactionV1ConfigFailure::UnexpectedArgType { arg_name: ADD_BID_ARG_AMOUNT.name.to_string(), - expected: CLType::U512, + expected: vec![CLType::U512], got: CLType::U64, }; assert_eq!(has_valid_add_bid_args(&args), Err(expected_error)); @@ -546,7 +589,7 @@ mod tests { }; let expected_error = TransactionV1ConfigFailure::UnexpectedArgType { arg_name: WITHDRAW_BID_ARG_AMOUNT.name.to_string(), - expected: CLType::U512, + expected: vec![CLType::U512], got: CLType::U64, }; assert_eq!(has_valid_withdraw_bid_args(&args), Err(expected_error)); @@ -617,7 +660,7 @@ mod tests { }; let expected_error = TransactionV1ConfigFailure::UnexpectedArgType { arg_name: DELEGATE_ARG_AMOUNT.name.to_string(), - expected: CLType::U512, + expected: vec![CLType::U512], got: CLType::U64, }; assert_eq!(has_valid_delegate_args(&args), Err(expected_error)); @@ -688,7 +731,7 @@ mod tests { }; let expected_error = TransactionV1ConfigFailure::UnexpectedArgType { arg_name: UNDELEGATE_ARG_AMOUNT.name.to_string(), - expected: CLType::U512, + expected: vec![CLType::U512], got: CLType::U64, }; assert_eq!(has_valid_undelegate_args(&args), Err(expected_error)); @@ -775,7 +818,7 @@ mod tests { }; let expected_error = TransactionV1ConfigFailure::UnexpectedArgType { arg_name: REDELEGATE_ARG_AMOUNT.name.to_string(), - expected: CLType::U512, + expected: vec![CLType::U512], got: CLType::U64, }; assert_eq!(has_valid_redelegate_args(&args), Err(expected_error)); diff --git a/types/src/transaction/transaction_v1/transaction_v1_builder.rs b/types/src/transaction/transaction_v1/transaction_v1_builder.rs index 1f4e8ed19b..e1897aa9e3 100644 --- a/types/src/transaction/transaction_v1/transaction_v1_builder.rs +++ b/types/src/transaction/transaction_v1/transaction_v1_builder.rs @@ -14,8 +14,8 @@ use super::{ InitiatorAddrAndSecretKey, PricingMode, TransactionV1, TransactionV1Body, }; use crate::{ - account::AccountHash, bytesrepr::Bytes, CLValue, CLValueError, EntityAddr, EntityVersion, - PackageAddr, PublicKey, RuntimeArgs, SecretKey, TimeDiff, Timestamp, URef, U512, + bytesrepr::Bytes, AddressableEntityHash, CLValue, CLValueError, EntityVersion, PackageHash, + PublicKey, RuntimeArgs, SecretKey, TimeDiff, Timestamp, TransferTarget, URef, U512, }; #[cfg(any(feature = "testing", test))] use crate::{testing::TestRng, TransactionConfig, TransactionV1Approval, TransactionV1Hash}; @@ -78,14 +78,13 @@ impl<'a> TransactionV1Builder<'a> { } /// Returns a new `TransactionV1Builder` suitable for building a native transfer transaction. - pub fn new_transfer>( - source: URef, - target: URef, + pub fn new_transfer, T: Into>( amount: A, - maybe_to: Option, + maybe_source: Option, + target: T, maybe_id: Option, ) -> Result { - let args = arg_handling::new_transfer_args(source, target, amount, maybe_to, maybe_id)?; + let args = arg_handling::new_transfer_args(amount, maybe_source, target, maybe_id)?; let body = TransactionV1Body::new( args, TransactionTarget::Native, @@ -196,10 +195,10 @@ impl<'a> TransactionV1Builder<'a> { /// Returns a new `TransactionV1Builder` suitable for building a transaction targeting a stored /// entity. pub fn new_targeting_invocable_entity>( - addr: EntityAddr, + hash: AddressableEntityHash, entry_point: E, ) -> Self { - let id = TransactionInvocationTarget::new_invocable_entity(addr.value()); + let id = TransactionInvocationTarget::new_invocable_entity(hash); Self::new_targeting_stored(id, entry_point) } @@ -216,11 +215,11 @@ impl<'a> TransactionV1Builder<'a> { /// Returns a new `TransactionV1Builder` suitable for building a transaction targeting a /// package. pub fn new_targeting_package>( - addr: PackageAddr, + hash: PackageHash, version: Option, entry_point: E, ) -> Self { - let id = TransactionInvocationTarget::new_package(addr, version); + let id = TransactionInvocationTarget::new_package(hash, version); Self::new_targeting_stored(id, entry_point) } @@ -327,8 +326,8 @@ impl<'a> TransactionV1Builder<'a> { /// /// If not provided, the public key derived from the secret key used in the builder will be /// used as the `InitiatorAddr::PublicKey` in the transaction. - pub fn with_initiator_addr(mut self, initiator_addr: InitiatorAddr) -> Self { - self.initiator_addr = Some(initiator_addr); + pub fn with_initiator_addr>(mut self, initiator_addr: I) -> Self { + self.initiator_addr = Some(initiator_addr.into()); self } diff --git a/types/src/transaction/transfer_target.rs b/types/src/transaction/transfer_target.rs new file mode 100644 index 0000000000..ba38a93e3d --- /dev/null +++ b/types/src/transaction/transfer_target.rs @@ -0,0 +1,48 @@ +#[cfg(any(feature = "testing", test))] +use rand::Rng; + +#[cfg(any(feature = "testing", test))] +use crate::testing::TestRng; +use crate::{account::AccountHash, PublicKey, URef}; + +/// The various types which can be used as the `target` runtime argument of a native transfer. +#[derive(Clone, Ord, PartialOrd, Eq, PartialEq)] +pub enum TransferTarget { + /// A public key. + PublicKey(PublicKey), + /// An account hash. + AccountHash(AccountHash), + /// A URef. + URef(URef), +} + +impl TransferTarget { + /// Returns a random `TransferTarget`. + #[cfg(any(feature = "testing", test))] + pub fn random(rng: &mut TestRng) -> Self { + match rng.gen_range(0..3) { + 0 => TransferTarget::PublicKey(PublicKey::random(rng)), + 1 => TransferTarget::AccountHash(rng.gen()), + 2 => TransferTarget::URef(rng.gen()), + _ => unreachable!(), + } + } +} + +impl From for TransferTarget { + fn from(public_key: PublicKey) -> Self { + Self::PublicKey(public_key) + } +} + +impl From for TransferTarget { + fn from(account_hash: AccountHash) -> Self { + Self::AccountHash(account_hash) + } +} + +impl From for TransferTarget { + fn from(uref: URef) -> Self { + Self::URef(uref) + } +} diff --git a/types/src/transaction_info.rs b/types/src/transaction_info.rs new file mode 100644 index 0000000000..4f536077b3 --- /dev/null +++ b/types/src/transaction_info.rs @@ -0,0 +1,185 @@ +use alloc::vec::Vec; + +#[cfg(feature = "datasize")] +use datasize::DataSize; +#[cfg(feature = "json-schema")] +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use crate::{ + bytesrepr::{self, FromBytes, ToBytes}, + Gas, InitiatorAddr, TransactionHash, TransferAddr, URef, +}; + +/// Information relating to the given Transaction, stored in global state under . +#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +#[serde(deny_unknown_fields)] +pub struct TransactionInfo { + /// The transaction hash. + pub transaction_hash: TransactionHash, + /// Transfers done during execution of the transaction. + pub transfers: Vec, + /// Identifier of the initiator of the transaction. + pub from: InitiatorAddr, + /// Source purse used for payment of the transaction. + pub source: URef, + /// Gas used in executing the transaction. + pub gas: Gas, +} + +impl TransactionInfo { + /// Returns a new `TransactionInfo`. + pub fn new( + transaction_hash: TransactionHash, + transfers: Vec, + from: InitiatorAddr, + source: URef, + gas: Gas, + ) -> Self { + TransactionInfo { + transaction_hash, + transfers, + from, + source, + gas, + } + } +} + +impl ToBytes for TransactionInfo { + fn to_bytes(&self) -> Result, bytesrepr::Error> { + let mut buf = Vec::new(); + self.write_bytes(&mut buf)?; + Ok(buf) + } + + fn serialized_length(&self) -> usize { + self.transaction_hash.serialized_length() + + self.transfers.serialized_length() + + self.from.serialized_length() + + self.source.serialized_length() + + self.gas.serialized_length() + } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + self.transaction_hash.write_bytes(writer)?; + self.transfers.write_bytes(writer)?; + self.from.write_bytes(writer)?; + self.source.write_bytes(writer)?; + self.gas.write_bytes(writer) + } +} + +impl FromBytes for TransactionInfo { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (transaction_hash, remainder) = TransactionHash::from_bytes(bytes)?; + let (transfers, remainder) = Vec::::from_bytes(remainder)?; + let (from, remainder) = InitiatorAddr::from_bytes(remainder)?; + let (source, remainder) = URef::from_bytes(remainder)?; + let (gas, remainder) = Gas::from_bytes(remainder)?; + Ok(( + TransactionInfo { + transaction_hash, + transfers, + from, + source, + gas, + }, + remainder, + )) + } +} + +/// Generators for a `TransactionInfo`. +#[cfg(any(feature = "testing", feature = "gens", test))] +pub(crate) mod gens { + use alloc::vec::Vec; + + use proptest::{ + array, + collection::{self, SizeRange}, + prelude::{Arbitrary, Strategy}, + prop_oneof, + }; + + use crate::{ + account::AccountHash, + crypto::gens::public_key_arb_no_system, + gens::{u512_arb, uref_arb}, + DeployHash, Gas, InitiatorAddr, TransactionHash, TransactionInfo, TransactionV1Hash, + TransferAddr, + }; + + pub fn deploy_hash_arb() -> impl Strategy { + array::uniform32(::arbitrary()).prop_map(DeployHash::from_raw) + } + + pub fn txn_v1_hash_arb() -> impl Strategy { + array::uniform32(::arbitrary()).prop_map(TransactionV1Hash::from_raw) + } + + pub fn txn_hash_arb() -> impl Strategy { + prop_oneof![ + deploy_hash_arb().prop_map(TransactionHash::from), + txn_v1_hash_arb().prop_map(TransactionHash::from) + ] + } + + pub fn transfer_addr_arb() -> impl Strategy { + array::uniform32(::arbitrary()).prop_map(TransferAddr::new) + } + + pub fn transfers_arb(size: impl Into) -> impl Strategy> { + collection::vec(transfer_addr_arb(), size) + } + + pub fn account_hash_arb() -> impl Strategy { + array::uniform32(::arbitrary()).prop_map(AccountHash::new) + } + + pub fn initiator_addr_arb() -> impl Strategy { + prop_oneof![ + public_key_arb_no_system().prop_map(InitiatorAddr::from), + account_hash_arb().prop_map(InitiatorAddr::from), + ] + } + + /// Arbitrary `TransactionInfo`. + pub fn txn_info_arb() -> impl Strategy { + let transfers_length_range = 0..5; + ( + txn_hash_arb(), + transfers_arb(transfers_length_range), + initiator_addr_arb(), + uref_arb(), + u512_arb(), + ) + .prop_map( + |(transaction_hash, transfers, from, source, gas)| TransactionInfo { + transaction_hash, + transfers, + from, + source, + gas: Gas::new(gas), + }, + ) + } +} + +#[cfg(test)] +mod tests { + use proptest::prelude::*; + + use crate::bytesrepr; + + use super::gens; + + proptest! { + #[test] + fn test_serialization_roundtrip(txn_info in gens::txn_info_arb()) { + bytesrepr::test_serialization_roundtrip(&txn_info) + } + } +} diff --git a/types/src/transfer.rs b/types/src/transfer.rs index 60f859aa7d..10d0a3fb3f 100644 --- a/types/src/transfer.rs +++ b/types/src/transfer.rs @@ -19,7 +19,7 @@ use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Seria use crate::{ account::AccountHash, bytesrepr::{self, FromBytes, ToBytes}, - checksummed_hex, serde_helpers, CLType, CLTyped, DeployHash, URef, U512, + checksummed_hex, CLType, CLTyped, Gas, InitiatorAddr, TransactionHash, URef, U512, }; /// The length of a transfer address. @@ -27,34 +27,26 @@ pub const TRANSFER_ADDR_LENGTH: usize = 32; pub(super) const TRANSFER_ADDR_FORMATTED_STRING_PREFIX: &str = "transfer-"; /// Represents a transfer from one purse to another -#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize, Default)] +#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] #[serde(deny_unknown_fields)] pub struct Transfer { - /// Deploy that created the transfer - #[serde(with = "serde_helpers::deploy_hash_as_array")] - #[cfg_attr( - feature = "json-schema", - schemars( - with = "DeployHash", - description = "Hex-encoded Deploy hash of Deploy that created the transfer." - ) - )] - pub deploy_hash: DeployHash, - /// Account from which transfer was executed - pub from: AccountHash, - /// Account to which funds are transferred + /// Transaction that created the transfer. + pub transaction_hash: TransactionHash, + /// Entity from which transfer was executed. + pub from: InitiatorAddr, + /// Account to which funds are transferred. pub to: Option, - /// Source purse + /// Source purse. pub source: URef, - /// Target purse + /// Target purse. pub target: URef, - /// Transfer amount + /// Transfer amount. pub amount: U512, - /// Gas - pub gas: U512, - /// User-defined id + /// Gas. + pub gas: Gas, + /// User-defined ID. pub id: Option, } @@ -62,17 +54,17 @@ impl Transfer { /// Creates a [`Transfer`]. #[allow(clippy::too_many_arguments)] pub fn new( - deploy_hash: DeployHash, - from: AccountHash, + transaction_hash: TransactionHash, + from: InitiatorAddr, to: Option, source: URef, target: URef, amount: U512, - gas: U512, + gas: Gas, id: Option, ) -> Self { Transfer { - deploy_hash, + transaction_hash, from, to, source, @@ -84,48 +76,15 @@ impl Transfer { } } -impl FromBytes for Transfer { - fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (deploy_hash, rem) = FromBytes::from_bytes(bytes)?; - let (from, rem) = AccountHash::from_bytes(rem)?; - let (to, rem) = >::from_bytes(rem)?; - let (source, rem) = URef::from_bytes(rem)?; - let (target, rem) = URef::from_bytes(rem)?; - let (amount, rem) = U512::from_bytes(rem)?; - let (gas, rem) = U512::from_bytes(rem)?; - let (id, rem) = >::from_bytes(rem)?; - Ok(( - Transfer { - deploy_hash, - from, - to, - source, - target, - amount, - gas, - id, - }, - rem, - )) - } -} - impl ToBytes for Transfer { fn to_bytes(&self) -> Result, bytesrepr::Error> { - let mut result = bytesrepr::allocate_buffer(self)?; - self.deploy_hash.write_bytes(&mut result)?; - self.from.write_bytes(&mut result)?; - self.to.write_bytes(&mut result)?; - self.source.write_bytes(&mut result)?; - self.target.write_bytes(&mut result)?; - self.amount.write_bytes(&mut result)?; - self.gas.write_bytes(&mut result)?; - self.id.write_bytes(&mut result)?; - Ok(result) + let mut buf = Vec::new(); + self.write_bytes(&mut buf)?; + Ok(buf) } fn serialized_length(&self) -> usize { - self.deploy_hash.serialized_length() + self.transaction_hash.serialized_length() + self.from.serialized_length() + self.to.serialized_length() + self.source.serialized_length() @@ -136,15 +95,40 @@ impl ToBytes for Transfer { } fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - self.deploy_hash.write_bytes(writer)?; + self.transaction_hash.write_bytes(writer)?; self.from.write_bytes(writer)?; self.to.write_bytes(writer)?; self.source.write_bytes(writer)?; self.target.write_bytes(writer)?; self.amount.write_bytes(writer)?; self.gas.write_bytes(writer)?; - self.id.write_bytes(writer)?; - Ok(()) + self.id.write_bytes(writer) + } +} + +impl FromBytes for Transfer { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (transaction_hash, remainder) = TransactionHash::from_bytes(bytes)?; + let (from, remainder) = InitiatorAddr::from_bytes(remainder)?; + let (to, remainder) = >::from_bytes(remainder)?; + let (source, remainder) = URef::from_bytes(remainder)?; + let (target, remainder) = URef::from_bytes(remainder)?; + let (amount, remainder) = U512::from_bytes(remainder)?; + let (gas, remainder) = Gas::from_bytes(remainder)?; + let (id, remainder) = >::from_bytes(remainder)?; + Ok(( + Transfer { + transaction_hash, + from, + to, + source, + target, + amount, + gas, + id, + }, + remainder, + )) } } @@ -263,13 +247,13 @@ impl<'de> Deserialize<'de> for TransferAddr { } impl Display for TransferAddr { - fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "{}", base16::encode_lower(&self.0)) } } impl Debug for TransferAddr { - fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "TransferAddr({})", base16::encode_lower(&self.0)) } } @@ -293,8 +277,7 @@ impl ToBytes for TransferAddr { #[inline(always)] fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - self.0.write_bytes(writer)?; - Ok(()) + self.0.write_bytes(writer) } } @@ -324,16 +307,16 @@ pub mod gens { use proptest::prelude::{prop::option, Arbitrary, Strategy}; use crate::{ - deploy_info::gens::{account_hash_arb, deploy_hash_arb}, gens::{u512_arb, uref_arb}, - Transfer, + transaction_info::gens::{account_hash_arb, initiator_addr_arb, txn_hash_arb}, + Gas, Transfer, }; /// Creates an arbitrary [`Transfer`] pub fn transfer_arb() -> impl Strategy { ( - deploy_hash_arb(), - account_hash_arb(), + txn_hash_arb(), + initiator_addr_arb(), option::of(account_hash_arb()), uref_arb(), uref_arb(), @@ -341,18 +324,18 @@ pub mod gens { u512_arb(), option::of(::arbitrary()), ) - .prop_map(|(deploy_hash, from, to, source, target, amount, gas, id)| { - Transfer { - deploy_hash, + .prop_map( + |(transaction_hash, from, to, source, target, amount, gas, id)| Transfer { + transaction_hash, from, to, source, target, amount, - gas, + gas: Gas::new(gas), id, - } - }) + }, + ) } } diff --git a/utils/global-state-update-gen/src/generic/state_tracker.rs b/utils/global-state-update-gen/src/generic/state_tracker.rs index 88d9026607..888bbd97f5 100644 --- a/utils/global-state-update-gen/src/generic/state_tracker.rs +++ b/utils/global-state-update-gen/src/generic/state_tracker.rs @@ -9,10 +9,10 @@ use rand::Rng; use casper_types::{ account::AccountHash, addressable_entity::{ActionThresholds, AssociatedKeys, MessageTopics, Weight}, - package::{EntityVersions, Groups, PackageStatus}, system::auction::{BidAddr, BidKind, BidsExt, SeigniorageRecipientsSnapshot, UnbondingPurse}, AccessRights, AddressableEntity, AddressableEntityHash, ByteCodeHash, CLValue, EntityKind, - EntryPoints, Key, Package, PackageHash, ProtocolVersion, PublicKey, StoredValue, URef, U512, + EntityVersions, EntryPoints, Groups, Key, Package, PackageHash, PackageStatus, ProtocolVersion, + PublicKey, StoredValue, URef, U512, }; use super::{config::Transfer, state_reader::StateReader}; diff --git a/utils/global-state-update-gen/src/main.rs b/utils/global-state-update-gen/src/main.rs index cb651851cb..85e150b72f 100644 --- a/utils/global-state-update-gen/src/main.rs +++ b/utils/global-state-update-gen/src/main.rs @@ -1,7 +1,7 @@ mod admins; mod balances; mod generic; -mod system_contract_registry; +mod system_entity_registry; mod utils; mod validators; @@ -10,7 +10,7 @@ use clap::{crate_version, App, Arg, SubCommand}; use crate::{ balances::generate_balances_update, generic::generate_generic_update, - system_contract_registry::generate_system_contract_registry, + system_entity_registry::generate_system_entity_registry, validators::generate_validators_update, }; @@ -102,7 +102,7 @@ fn main() { ) .subcommand( SubCommand::with_name("migrate-into-system-contract-registry") - .about("Generates an update creating the system contract registry") + .about("Generates an update creating the system entity registry") .arg( Arg::with_name("data_dir") .short("d") @@ -190,7 +190,7 @@ fn main() { ("change-validators", Some(sub_matches)) => generate_validators_update(sub_matches), ("balances", Some(sub_matches)) => generate_balances_update(sub_matches), ("migrate-into-system-contract-registry", Some(sub_matches)) => { - generate_system_contract_registry(sub_matches) + generate_system_entity_registry(sub_matches) } ("generic", Some(sub_matches)) => generate_generic_update(sub_matches), ("generate-admins", Some(sub_matches)) => generate_admins(sub_matches), diff --git a/utils/global-state-update-gen/src/system_contract_registry.rs b/utils/global-state-update-gen/src/system_entity_registry.rs similarity index 91% rename from utils/global-state-update-gen/src/system_contract_registry.rs rename to utils/global-state-update-gen/src/system_entity_registry.rs index df25cf75e6..d9cc4b8fb6 100644 --- a/utils/global-state-update-gen/src/system_contract_registry.rs +++ b/utils/global-state-update-gen/src/system_entity_registry.rs @@ -14,15 +14,15 @@ use crate::utils::{hash_from_str, print_entry}; const DATABASE_NAME: &str = "PROTOCOL_DATA_STORE"; -pub(crate) fn generate_system_contract_registry(matches: &ArgMatches<'_>) { +pub(crate) fn generate_system_entity_registry(matches: &ArgMatches<'_>) { let data_dir = Path::new(matches.value_of("data_dir").unwrap_or(".")); match matches.value_of("hash") { - None => generate_system_contract_registry_using_protocol_data(data_dir), - Some(hash) => generate_system_contract_registry_using_global_state(data_dir, hash), + None => generate_system_entity_registry_using_protocol_data(data_dir), + Some(hash) => generate_system_entity_registry_using_global_state(data_dir, hash), } } -fn generate_system_contract_registry_using_protocol_data(data_dir: &Path) { +fn generate_system_entity_registry_using_protocol_data(data_dir: &Path) { let database_path = data_dir.join("data.lmdb"); let env = Environment::new() @@ -103,7 +103,7 @@ fn generate_system_contract_registry_using_protocol_data(data_dir: &Path) { ); } -fn generate_system_contract_registry_using_global_state(data_dir: &Path, state_hash: &str) { +fn generate_system_entity_registry_using_global_state(data_dir: &Path, state_hash: &str) { let builder = LmdbWasmTestBuilder::open_raw(data_dir, Default::default(), hash_from_str(state_hash)); diff --git a/utils/validation/src/generators.rs b/utils/validation/src/generators.rs index a1c33ebf8e..46bf00833a 100644 --- a/utils/validation/src/generators.rs +++ b/utils/validation/src/generators.rs @@ -11,15 +11,15 @@ use casper_types::{ addressable_entity::{ ActionThresholds, AddressableEntity, AssociatedKeys, EntityKind, MessageTopics, NamedKeys, }, - package::{EntityVersions, Groups, Package, PackageStatus}, system::auction::{ Bid, BidAddr, BidKind, Delegator, EraInfo, SeigniorageAllocation, UnbondingPurse, ValidatorBid, WithdrawPurse, }, AccessRights, AddressableEntityHash, ByteCode, ByteCodeHash, ByteCodeKind, CLType, CLTyped, - CLValue, DeployHash, DeployInfo, EntityVersionKey, EntryPoint, EntryPointAccess, - EntryPointType, EntryPoints, EraId, Group, Key, PackageHash, Parameter, ProtocolVersion, - PublicKey, SecretKey, StoredValue, Transfer, TransferAddr, URef, U512, + CLValue, DeployHash, DeployInfo, EntityVersionKey, EntityVersions, EntryPoint, + EntryPointAccess, EntryPointType, EntryPoints, EraId, Gas, Group, Groups, InitiatorAddr, Key, + Package, PackageHash, PackageStatus, Parameter, ProtocolVersion, PublicKey, SecretKey, + StoredValue, TransactionHash, Transfer, TransferAddr, URef, U512, }; use casper_validation::{ abi::{ABIFixture, ABITestCase}, @@ -67,13 +67,13 @@ pub fn make_abi_test_fixtures() -> Result { }; let transfer = Transfer::new( - DeployHash::from_raw([44; 32]), - AccountHash::new([100; 32]), + TransactionHash::from(DeployHash::from_raw([44; 32])), + InitiatorAddr::from(AccountHash::new([100; 32])), Some(AccountHash::new([101; 32])), URef::new([10; 32], AccessRights::WRITE), URef::new([11; 32], AccessRights::WRITE), U512::from(15_000_000_000u64), - U512::from(2_500_000_000u64), + Gas::new(2_500_000_000u64), Some(1), ); let deploy_info = DeployInfo::new( @@ -208,7 +208,7 @@ pub fn make_abi_test_fixtures() -> Result { const BALANCE_KEY: Key = Key::Balance([42; 32]); const WITHDRAW_KEY: Key = Key::Withdraw(AccountHash::new([42; 32])); const DICTIONARY_KEY: Key = Key::Dictionary([42; 32]); - const SYSTEM_CONTRACT_REGISTRY_KEY: Key = Key::SystemEntityRegistry; + const SYSTEM_ENTITY_REGISTRY_KEY: Key = Key::SystemEntityRegistry; const ERA_SUMMARY_KEY: Key = Key::EraSummary; const UNBOND_KEY: Key = Key::Unbond(AccountHash::new([42; 32])); const CHAINSPEC_REGISTRY_KEY: Key = Key::ChainspecRegistry; @@ -269,8 +269,8 @@ pub fn make_abi_test_fixtures() -> Result { ABITestCase::from_inputs(vec![DICTIONARY_KEY.into()])?, ); keys.insert( - "SystemContractRegistry".to_string(), - ABITestCase::from_inputs(vec![SYSTEM_CONTRACT_REGISTRY_KEY.into()])?, + "SystemEntityRegistry".to_string(), + ABITestCase::from_inputs(vec![SYSTEM_ENTITY_REGISTRY_KEY.into()])?, ); keys.insert( "EraSummary".to_string(), From 0766b32d23a3828998cb9eb9833ec2f1b0788684 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Mon, 19 Feb 2024 23:31:43 +0000 Subject: [PATCH 02/70] version Transfer type --- execution_engine/src/engine_state/mod.rs | 15 +- execution_engine/src/runtime/mod.rs | 21 +- execution_engine/src/runtime_context/mod.rs | 58 +-- .../test_support/src/wasm_test_builder.rs | 4 +- .../tests/src/test/deploy/receipts.rs | 56 ++- .../components/contract_runtime/operations.rs | 12 +- node/src/components/rpc_server/rpcs/chain.rs | 6 +- node/src/components/storage.rs | 58 ++- node/src/components/storage/tests.rs | 68 ++- node/src/components/storage/transfers.rs | 39 ++ .../components/storage/versioned_databases.rs | 8 +- .../block/block_execution_results_or_chunk.rs | 4 +- resources/test/rpc_schema.json | 278 +++++++++-- resources/test/sse_data_schema.json | 101 ++-- storage/src/data_access_layer.rs | 1 + storage/src/data_access_layer/transfer.rs | 42 +- storage/src/global_state/state/mod.rs | 33 +- storage/src/system/mint/mint_native.rs | 43 +- storage/src/tracking_copy/byte_size.rs | 3 +- storage/src/tracking_copy/mod.rs | 7 +- types/benches/bytesrepr_bench.rs | 17 +- types/src/cl_value.rs | 10 +- types/src/deploy_info.rs | 16 +- types/src/execution/execution_result_v1.rs | 20 +- types/src/execution/execution_result_v2.rs | 10 +- types/src/execution/transform_kind.rs | 9 +- types/src/gas.rs | 4 +- types/src/gens.rs | 17 +- types/src/key.rs | 150 ++++-- types/src/lib.rs | 3 +- types/src/stored_value.rs | 129 ++--- types/src/transaction/transaction_hash.rs | 2 - types/src/transaction_info.rs | 20 +- types/src/transfer.rs | 453 ++++++------------ types/src/transfer/error.rs | 63 +++ types/src/transfer/transfer_addr.rs | 254 ++++++++++ types/src/transfer/transfer_v1.rs | 132 +++++ .../transfer/transfer_v1/transfer_v1_addr.rs | 225 +++++++++ types/src/transfer/transfer_v2.rs | 123 +++++ .../transfer/transfer_v2/transfer_v2_addr.rs | 225 +++++++++ utils/validation/src/generators.rs | 37 +- utils/validation/tests/fixtures/ABI/key.json | 12 +- .../tests/fixtures/ABI/stored_value.json | 56 ++- 43 files changed, 2036 insertions(+), 808 deletions(-) create mode 100644 node/src/components/storage/transfers.rs create mode 100644 types/src/transfer/error.rs create mode 100644 types/src/transfer/transfer_addr.rs create mode 100644 types/src/transfer/transfer_v1.rs create mode 100644 types/src/transfer/transfer_v1/transfer_v1_addr.rs create mode 100644 types/src/transfer/transfer_v2.rs create mode 100644 types/src/transfer/transfer_v2/transfer_v2_addr.rs diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index cebc6f4db3..44bb84daad 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -56,8 +56,8 @@ use casper_types::{ handle_payment::{self, ACCUMULATION_PURSE_KEY}, AUCTION, HANDLE_PAYMENT, MINT, }, - AddressableEntity, AddressableEntityHash, BlockTime, Digest, EntityAddr, FeeHandling, Gas, Key, - KeyTag, Motes, Phase, ProtocolVersion, PublicKey, RuntimeArgs, StoredValue, + AddressableEntity, AddressableEntityHash, BlockTime, Digest, EntityAddr, FeeHandling, Gas, + InitiatorAddr, Key, KeyTag, Motes, Phase, ProtocolVersion, PublicKey, RuntimeArgs, StoredValue, SystemEntityRegistry, TransactionHash, TransactionInfo, TransactionSessionKind, TransactionV1Hash, URef, U512, }; @@ -359,20 +359,19 @@ where self.config.administrative_accounts.clone(), self.config.allow_unrestricted_transfers, ); - let wasmless_transfer_gas = Gas::new(U512::from( - self.config().system_config().wasmless_transfer_cost(), - )); + let wasmless_transfer_gas = + Gas::new(self.config().system_config().wasmless_transfer_cost()); let transfer_req = TransferRequest::with_runtime_args( transfer_config, prestate_hash, blocktime.value(), protocol_version, proposer, - *deploy_hash.inner(), - deploy_item.address, + TransactionHash::Deploy(deploy_hash), // TODO - should have this passed in + InitiatorAddr::AccountHash(deploy_item.address), // TODO - should have this passed in deploy_item.authorization_keys, deploy_item.session.args().clone(), - wasmless_transfer_gas.value(), + wasmless_transfer_gas, ); let transfer_result = self.state.transfer(transfer_req); ExecutionResult::from_transfer_result(transfer_result, wasmless_transfer_gas) diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index 2caa4dc011..4811fb5465 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -52,7 +52,7 @@ use casper_types::{ ContextAccessRights, ContractWasm, EntityAddr, EntityKind, EntityVersion, EntityVersionKey, EntityVersions, Gas, GrantedAccess, Group, Groups, HostFunction, HostFunctionCost, InitiatorAddr, Key, NamedArg, Package, PackageHash, PackageStatus, Phase, PublicKey, - RuntimeArgs, StoredValue, Tagged, Transfer, TransferResult, TransferredTo, URef, + RuntimeArgs, StoredValue, Tagged, Transfer, TransferResult, TransferV2, TransferredTo, URef, DICTIONARY_ITEM_KEY_MAX_LENGTH, U512, }; @@ -2054,17 +2054,14 @@ where } let transfer_addr = self.context.new_transfer_addr()?; - let transfer = { - // TODO - update once decision is made on recording transfers. - let txn_hash = self.context.get_transaction_hash(); - let from = InitiatorAddr::AccountHash(self.context.get_caller()); - let fee = Gas::zero(); // TODO - Transfer::new(txn_hash, from, maybe_to, source, target, amount, fee, id) - }; - { - let transfers = self.context.transfers_mut(); - transfers.push(transfer_addr); - } + // TODO - update once decision is made on recording transfers. + let txn_hash = self.context.get_transaction_hash(); + let from = InitiatorAddr::AccountHash(self.context.get_caller()); + let fee = Gas::zero(); // TODO + let transfer = Transfer::V2(TransferV2::new( + txn_hash, from, maybe_to, source, target, amount, fee, id, + )); + self.context.transfers_mut().push(transfer_addr); self.context .write_transfer(Key::Transfer(transfer_addr), transfer); Ok(()) diff --git a/execution_engine/src/runtime_context/mod.rs b/execution_engine/src/runtime_context/mod.rs index 1690952cc5..9a1502f2ae 100644 --- a/execution_engine/src/runtime_context/mod.rs +++ b/execution_engine/src/runtime_context/mod.rs @@ -35,8 +35,8 @@ use casper_types::{ AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, CLType, CLValue, CLValueDictionary, ContextAccessRights, EntityAddr, EntryPointType, Gas, GrantedAccess, Key, KeyTag, Package, PackageHash, Phase, ProtocolVersion, PublicKey, RuntimeArgs, StoredValue, - StoredValueTypeMismatch, SystemEntityRegistry, TransactionHash, Transfer, TransferAddr, URef, - URefAddr, DICTIONARY_ITEM_KEY_MAX_LENGTH, KEY_HASH_LENGTH, U512, + StoredValueTypeMismatch, SystemEntityRegistry, TransactionHash, Transfer, TransferAddr, + TransferV2Addr, URef, URefAddr, DICTIONARY_ITEM_KEY_MAX_LENGTH, KEY_HASH_LENGTH, U512, }; use crate::{engine_state::EngineConfig, execution::Error}; @@ -367,7 +367,7 @@ where /// Creates a new transfer address using a transfer address generator. pub fn new_transfer_addr(&mut self) -> Result { let transfer_addr = self.address_generator.borrow_mut().create_address(); - Ok(TransferAddr::new(transfer_addr)) + Ok(TransferAddr::V2(TransferV2Addr::new(transfer_addr))) } /// Puts `key` to the map of named keys of current context. @@ -516,7 +516,6 @@ where /// Write a transfer instance to the global state. pub fn write_transfer(&mut self, key: Key, value: Transfer) { if let Key::Transfer(_) = key { - // Writing a `Transfer` will not exceed write size limit. self.tracking_copy .borrow_mut() .write(key, StoredValue::Transfer(value)); @@ -669,28 +668,28 @@ where fn validate_value(&self, value: &StoredValue) -> Result<(), Error> { match value { StoredValue::CLValue(cl_value) => self.validate_cl_value(cl_value), - StoredValue::Account(_) => Ok(()), - StoredValue::ByteCode(_) => Ok(()), - StoredValue::Contract(_) => Ok(()), - StoredValue::AddressableEntity(_) => Ok(()), - // TODO: anything to validate here? - StoredValue::Package(_) => Ok(()), - StoredValue::Transfer(_) => Ok(()), - StoredValue::DeployInfo(_) => Ok(()), - StoredValue::EraInfo(_) => Ok(()), - StoredValue::Bid(_) => Ok(()), - StoredValue::BidKind(_) => Ok(()), - StoredValue::Withdraw(_) => Ok(()), - StoredValue::Unbonding(_) => Ok(()), - StoredValue::ContractPackage(_) => Ok(()), - StoredValue::ContractWasm(_) => Ok(()), - StoredValue::MessageTopic(_) => Ok(()), - StoredValue::Message(_) => Ok(()), StoredValue::NamedKey(named_key_value) => { self.validate_cl_value(named_key_value.get_key_as_cl_value())?; self.validate_cl_value(named_key_value.get_name_as_cl_value()) } - StoredValue::TransactionInfo(_) => Ok(()), + StoredValue::Account(_) + | StoredValue::ByteCode(_) + | StoredValue::Contract(_) + | StoredValue::AddressableEntity(_) + | StoredValue::Package(_) + | StoredValue::LegacyTransfer(_) + | StoredValue::DeployInfo(_) + | StoredValue::EraInfo(_) + | StoredValue::Bid(_) + | StoredValue::BidKind(_) + | StoredValue::Withdraw(_) + | StoredValue::Unbonding(_) + | StoredValue::ContractPackage(_) + | StoredValue::ContractWasm(_) + | StoredValue::MessageTopic(_) + | StoredValue::Message(_) + | StoredValue::TransactionInfo(_) + | StoredValue::Transfer(_) => Ok(()), } } @@ -758,7 +757,7 @@ where Key::Balance(_) => false, Key::Account(_) | Key::Hash(_) - | Key::Transfer(_) + | Key::LegacyTransfer(_) | Key::DeployInfo(_) | Key::EraInfo(_) | Key::Bid(_) @@ -775,7 +774,8 @@ where | Key::ByteCode(_) | Key::Message(_) | Key::NamedKey(_) - | Key::TransactionInfo(_) => true, + | Key::TransactionInfo(_) + | Key::Transfer(_) => true, } } @@ -796,7 +796,7 @@ where } Key::Hash(_) | Key::Account(_) - | Key::Transfer(_) + | Key::LegacyTransfer(_) | Key::DeployInfo(_) | Key::EraInfo(_) | Key::Balance(_) @@ -812,7 +812,8 @@ where | Key::Package(_) | Key::ByteCode(..) | Key::Message(_) - | Key::TransactionInfo(_) => false, + | Key::TransactionInfo(_) + | Key::Transfer(_) => false, } } @@ -829,7 +830,7 @@ where } Key::Account(_) | Key::Hash(_) - | Key::Transfer(_) + | Key::LegacyTransfer(_) | Key::DeployInfo(_) | Key::EraInfo(_) | Key::Balance(_) @@ -846,7 +847,8 @@ where | Key::AddressableEntity(..) | Key::ByteCode(..) | Key::Message(_) - | Key::TransactionInfo(_) => false, + | Key::TransactionInfo(_) + | Key::Transfer(_) => false, } } diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index b80ebc237b..f6fdca20cb 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -1218,9 +1218,9 @@ where } /// Queries for a transfer by `TransferAddr`. - pub fn get_transfer(&self, transfer: TransferAddr) -> Option { + pub fn get_transfer(&self, transfer_addr: TransferAddr) -> Option { let transfer_value: StoredValue = self - .query(None, Key::Transfer(transfer), &[]) + .query(None, Key::Transfer(transfer_addr), &[]) .expect("should have transfer value"); if let StoredValue::Transfer(transfer) = transfer_value { diff --git a/execution_engine_testing/tests/src/test/deploy/receipts.rs b/execution_engine_testing/tests/src/test/deploy/receipts.rs index 403c2cd36d..ed53694719 100644 --- a/execution_engine_testing/tests/src/test/deploy/receipts.rs +++ b/execution_engine_testing/tests/src/test/deploy/receipts.rs @@ -8,7 +8,7 @@ use casper_engine_test_support::{ }; use casper_types::{ account::AccountHash, runtime_args, system::mint, AccessRights, Gas, InitiatorAddr, PublicKey, - SecretKey, Transfer, TransferAddr, U512, + SecretKey, Transfer, TransferAddr, TransferV2, U512, }; const CONTRACT_TRANSFER_PURSE_TO_ACCOUNT: &str = "transfer_purse_to_account.wasm"; @@ -98,9 +98,11 @@ fn should_record_wasmless_transfer() { let transfers = txn_info.transfers; assert_eq!(transfers.len(), 1); - let transfer = builder + let Transfer::V2(transfer) = builder .get_transfer(transfers[0]) - .expect("should have transfer"); + .expect("should have transfer") else { + panic!("wrong transfer variant"); + }; assert_eq!(transfer.transaction_hash, txn_hash); assert_eq!( @@ -162,9 +164,11 @@ fn should_record_wasm_transfer() { let transfers = txn_info.transfers; assert_eq!(transfers.len(), 1); - let transfer = builder + let Transfer::V2(transfer) = builder .get_transfer(transfers[0]) - .expect("should have transfer"); + .expect("should have transfer") else { + panic!("wrong transfer variant"); + }; assert_eq!(transfer.transaction_hash, txn_hash); assert_eq!( @@ -227,9 +231,11 @@ fn should_record_wasm_transfer_with_id() { let transfers = txn_info.transfers; assert_eq!(transfers.len(), 1); - let transfer = builder + let Transfer::V2(transfer) = builder .get_transfer(transfers[0]) - .expect("should have transfer"); + .expect("should have transfer") else { + panic!("wrong transfer variant"); + }; assert_eq!(transfer.transaction_hash, txn_hash); assert_eq!( @@ -340,7 +346,7 @@ fn should_record_wasm_transfers() { assert_eq!(transfers.len(), EXPECTED_LENGTH); - assert!(transfers.contains(&Transfer { + assert!(transfers.contains(&Transfer::V2(TransferV2 { transaction_hash: txn_hash, from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*ALICE_ADDR), @@ -349,9 +355,9 @@ fn should_record_wasm_transfers() { amount: *TRANSFER_AMOUNT_1, gas: Gas::zero(), id: alice_id, - })); + }))); - assert!(transfers.contains(&Transfer { + assert!(transfers.contains(&Transfer::V2(TransferV2 { transaction_hash: txn_hash, from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*BOB_ADDR), @@ -360,9 +366,9 @@ fn should_record_wasm_transfers() { amount: *TRANSFER_AMOUNT_2, gas: Gas::zero(), id: bob_id, - })); + }))); - assert!(transfers.contains(&Transfer { + assert!(transfers.contains(&Transfer::V2(TransferV2 { transaction_hash: txn_hash, from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*CAROL_ADDR), @@ -371,7 +377,7 @@ fn should_record_wasm_transfers() { amount: *TRANSFER_AMOUNT_3, gas: Gas::zero(), id: carol_id, - })); + }))); } #[ignore] @@ -499,7 +505,7 @@ fn should_record_wasm_transfers_with_subcall() { tmp }; - let session_expected_alice = Transfer { + let session_expected_alice = Transfer::V2(TransferV2 { transaction_hash: transfer_txn_hash, from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*ALICE_ADDR), @@ -508,9 +514,9 @@ fn should_record_wasm_transfers_with_subcall() { amount: *TRANSFER_AMOUNT_1, gas: Gas::zero(), id: alice_id, - }; + }); - let session_expected_bob = Transfer { + let session_expected_bob = Transfer::V2(TransferV2 { transaction_hash: transfer_txn_hash, from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*BOB_ADDR), @@ -519,9 +525,9 @@ fn should_record_wasm_transfers_with_subcall() { amount: *TRANSFER_AMOUNT_2, gas: Gas::zero(), id: bob_id, - }; + }); - let session_expected_carol = Transfer { + let session_expected_carol = Transfer::V2(TransferV2 { transaction_hash: transfer_txn_hash, from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*CAROL_ADDR), @@ -530,7 +536,7 @@ fn should_record_wasm_transfers_with_subcall() { amount: *TRANSFER_AMOUNT_3, gas: Gas::zero(), id: carol_id, - }; + }); const SESSION_EXPECTED_COUNT: Option = Some(1); for (i, expected) in [ @@ -549,7 +555,7 @@ fn should_record_wasm_transfers_with_subcall() { ); } - let stored_expected_alice = Transfer { + let stored_expected_alice = Transfer::V2(TransferV2 { transaction_hash: transfer_txn_hash, from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*ALICE_ADDR), @@ -558,9 +564,9 @@ fn should_record_wasm_transfers_with_subcall() { amount: *TRANSFER_AMOUNT_1, gas: Gas::zero(), id: alice_id, - }; + }); - let stored_expected_bob = Transfer { + let stored_expected_bob = Transfer::V2(TransferV2 { transaction_hash: transfer_txn_hash, from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*BOB_ADDR), @@ -569,9 +575,9 @@ fn should_record_wasm_transfers_with_subcall() { amount: *TRANSFER_AMOUNT_2, gas: Gas::zero(), id: bob_id, - }; + }); - let stored_expected_carol = Transfer { + let stored_expected_carol = Transfer::V2(TransferV2 { transaction_hash: transfer_txn_hash, from: InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR), to: Some(*CAROL_ADDR), @@ -580,7 +586,7 @@ fn should_record_wasm_transfers_with_subcall() { amount: *TRANSFER_AMOUNT_3, gas: Gas::zero(), id: carol_id, - }; + }); const STORED_EXPECTED_COUNT: Option = Some(1); for (i, expected) in [ diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index cd86080906..a4edf18e1b 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -20,8 +20,8 @@ use casper_types::{ bytesrepr::{self, ToBytes, U32_SERIALIZED_LENGTH}, contract_messages::Messages, execution::{Effects, ExecutionResult, ExecutionResultV2, Transform, TransformKind}, - BlockTime, BlockV2, CLValue, ChecksumRegistry, Digest, EraEndV2, EraId, Gas, Key, - ProtocolVersion, PublicKey, Transaction, TransactionHash, TransactionHeader, U512, + BlockTime, BlockV2, CLValue, ChecksumRegistry, Digest, EraEndV2, EraId, Gas, InitiatorAddr, + Key, ProtocolVersion, PublicKey, Transaction, TransactionHash, TransactionHeader, U512, }; use crate::{ @@ -112,12 +112,12 @@ pub fn execute_finalized_block( block_time, protocol_version, PublicKey::clone(&executable_block.proposer), - deploy_hash.into(), - deploy.header().account().to_account_hash(), + txn_hash, + InitiatorAddr::PublicKey(deploy.header().account().clone()), authorization_keys, deploy.session().args().clone(), - U512::zero(), /* <-- this should be the native transfer cost from the - * chainspec */ + Gas::zero(), /* <-- this should be the native transfer cost from the + * chainspec */ ); // native transfer auto-commits let transfer_result = data_access_layer.transfer(transfer_req); diff --git a/node/src/components/rpc_server/rpcs/chain.rs b/node/src/components/rpc_server/rpcs/chain.rs index 4c646adc97..d774e447a5 100644 --- a/node/src/components/rpc_server/rpcs/chain.rs +++ b/node/src/components/rpc_server/rpcs/chain.rs @@ -13,7 +13,7 @@ use casper_storage::data_access_layer::QueryResult; use casper_types::{ account::AccountHash, AccessRights, Block, BlockHash, BlockHeaderV2, Digest, DigestError, Gas, InitiatorAddr, JsonBlockWithSignatures, Key, ProtocolVersion, PublicKey, SecretKey, - TransactionHash, TransactionV1Hash, Transfer, URef, U512, + TransactionHash, TransactionV1Hash, Transfer, TransferV2, URef, U512, }; use super::{ @@ -44,7 +44,7 @@ static GET_BLOCK_TRANSFERS_RESULT: Lazy = Lazy::new(|| GetBlockTransfersResult { api_version: DOCS_EXAMPLE_PROTOCOL_VERSION, block_hash: Some(*BlockHash::example()), - transfers: Some(vec![Transfer::new( + transfers: Some(vec![Transfer::V2(TransferV2::new( TransactionHash::V1(TransactionV1Hash::new(Digest::from([9; Digest::LENGTH]))), InitiatorAddr::PublicKey(PublicKey::from(SecretKey::example())), Some(AccountHash::new([10; 32])), @@ -53,7 +53,7 @@ static GET_BLOCK_TRANSFERS_RESULT: Lazy = U512::from(3_000_000_000_u64), Gas::new(2_500_000_000_u64), Some(9), - )]), + ))]), }); static GET_STATE_ROOT_HASH_PARAMS: Lazy = Lazy::new(|| GetStateRootHashParams { diff --git a/node/src/components/storage.rs b/node/src/components/storage.rs index e077abe5c2..6528e1741c 100644 --- a/node/src/components/storage.rs +++ b/node/src/components/storage.rs @@ -43,6 +43,7 @@ mod metrics; mod object_pool; #[cfg(test)] mod tests; +mod transfers; mod versioned_databases; #[cfg(test)] @@ -111,9 +112,10 @@ pub use error::FatalStorageError; use error::GetRequestError; pub(crate) use event::Event; use legacy_approvals_hashes::LegacyApprovalsHashes; -use lmdb_ext::{BytesreprError, LmdbExtError, TransactionExt, WriteTransactionExt}; +use lmdb_ext::{BytesreprError, LmdbExtError}; use metrics::Metrics; use object_pool::ObjectPool; +use transfers::Transfers; use versioned_databases::VersionedDatabases; const COMPONENT_NAME: &str = "storage"; @@ -126,7 +128,7 @@ const STORAGE_DB_FILENAME: &str = "storage.lmdb"; const MAX_TRANSACTIONS: u32 = 1; /// Maximum number of allowed dbs. -const MAX_DB_COUNT: u32 = 16; +const MAX_DB_COUNT: u32 = 17; /// Key under which completed blocks are to be stored. const COMPLETED_BLOCKS_STORAGE_KEY: &[u8] = b"completed_blocks_disjoint_sequences"; /// Name of the file created when initializing a force resync. @@ -172,8 +174,7 @@ pub struct Storage { /// hash for legacy DB. execution_result_dbs: VersionedDatabases, /// The transfer database. - #[data_size(skip)] - transfer_db: Database, + transfer_dbs: VersionedDatabases, /// The state storage database. #[data_size(skip)] state_store_db: Database, @@ -339,7 +340,7 @@ impl Storage { let transaction_dbs = VersionedDatabases::new(&env, "deploys", "transactions")?; let execution_result_dbs = VersionedDatabases::new(&env, "deploy_metadata", "execution_results")?; - let transfer_db = env.create_db(Some("transfer"), DatabaseFlags::empty())?; + let transfer_dbs = VersionedDatabases::new(&env, "transfer", "versioned_transfers")?; let state_store_db = env.create_db(Some("state_store"), DatabaseFlags::empty())?; let block_body_dbs = VersionedDatabases::<_, BlockBody>::new(&env, "block_body", "block_body_v2")?; @@ -463,7 +464,7 @@ impl Storage { approvals_hashes_dbs, transaction_dbs, execution_result_dbs, - transfer_db, + transfer_dbs, state_store_db, finalized_transaction_approvals_dbs, block_height_index, @@ -1541,9 +1542,9 @@ impl Storage { era_id, transaction_hashes, )?; - let mut transfers: Vec = vec![]; + let mut transfers = Transfers::default(); for (transaction_hash, execution_result) in execution_results.into_iter() { - transfers.extend(successful_transfers(&execution_result)); + transfers.0.extend(successful_transfers(&execution_result)); let was_written = self.execution_result_dbs @@ -1559,7 +1560,7 @@ impl Storage { } } - let was_written = txn.put_value(self.transfer_db, block_hash, &transfers, true)?; + let was_written = self.transfer_dbs.put(txn, block_hash, &transfers, true)?; if !was_written { error!(?block_hash, "failed to write transfers"); debug_assert!(was_written); @@ -2211,7 +2212,7 @@ impl Storage { /// Retrieves successful transfers associated with block. /// /// If there is no record of successful transfers for this block, then the list will be built - /// from the execution results and stored to `transfer_db`. The record could have been missing + /// from the execution results and stored to `transfer_dbs`. The record could have been missing /// or incorrectly set to an empty collection due to previous synchronization and storage /// issues. See https://github.com/casper-network/casper-node/issues/4255 and /// https://github.com/casper-network/casper-node/issues/4268 for further info. @@ -2220,9 +2221,9 @@ impl Storage { block_hash: &BlockHash, ) -> Result>, FatalStorageError> { let mut txn = self.env.begin_rw_txn()?; - if let Some(transfers) = txn.get_value::<_, Vec>(self.transfer_db, block_hash)? { - if !transfers.is_empty() { - return Ok(Some(transfers)); + if let Some(transfers) = self.transfer_dbs.get(&mut txn, block_hash)? { + if !transfers.0.is_empty() { + return Ok(Some(transfers.0)); } } @@ -2231,33 +2232,30 @@ impl Storage { None => return Ok(None), }; - let deploy_hashes: Vec = match block.clone_body() { - BlockBody::V1(v1) => v1.deploy_and_transfer_hashes().copied().collect(), - BlockBody::V2(v2) => v2 - .all_transactions() - .filter_map(|transaction_hash| match transaction_hash { - TransactionHash::Deploy(deploy_hash) => Some(*deploy_hash), - TransactionHash::V1(_) => None, - }) + let transaction_hashes: Vec = match block.clone_body() { + BlockBody::V1(v1) => v1 + .deploy_and_transfer_hashes() + .map(|deploy_hash| TransactionHash::Deploy(*deploy_hash)) .collect(), + BlockBody::V2(v2) => v2.all_transactions().copied().collect(), }; - let mut transfers: Vec = vec![]; - for deploy_hash in deploy_hashes { - let transaction_hash = TransactionHash::Deploy(deploy_hash); + let mut transfers = Transfers::default(); + for transaction_hash in transaction_hashes { let successful_xfers = match self.execution_result_dbs.get(&mut txn, &transaction_hash)? { Some(exec_result) => successful_transfers(&exec_result), None => { - error!(%deploy_hash, %block_hash, "should have exec result"); + error!(%transaction_hash, %block_hash, "should have exec result"); vec![] } }; - transfers.extend(successful_xfers); + transfers.0.extend(successful_xfers); } - txn.put_value(self.transfer_db, block_hash, &transfers, true)?; + self.transfer_dbs + .put(&mut txn, block_hash, &transfers, true)?; txn.commit()?; - Ok(Some(transfers)) + Ok(Some(transfers.0)) } /// Retrieves block signatures for a block with a given block hash. @@ -2970,10 +2968,10 @@ fn successful_transfers(execution_result: &ExecutionResult) -> Vec { match execution_result { ExecutionResult::V1(ExecutionResultV1::Success { effect, .. }) => { for transform_entry in &effect.transforms { - if let execution_result_v1::Transform::WriteTransfer(transfer) = + if let execution_result_v1::Transform::WriteTransfer(transfer_v1) = &transform_entry.transform { - transfers.push(transfer.clone()); + transfers.push(Transfer::V1(transfer_v1.clone())); } } } diff --git a/node/src/components/storage/tests.rs b/node/src/components/storage/tests.rs index 0772947cd5..f190138db3 100644 --- a/node/src/components/storage/tests.rs +++ b/node/src/components/storage/tests.rs @@ -17,27 +17,24 @@ use serde::{Deserialize, Serialize}; use smallvec::smallvec; use casper_types::{ - execution::{ - execution_result_v1::{ExecutionEffect, ExecutionResultV1, Transform, TransformEntry}, - ExecutionResult, ExecutionResultV2, - }, + execution::{Effects, ExecutionResult, ExecutionResultV2, Transform, TransformKind}, generate_ed25519_keypair, system::auction::UnbondingPurse, testing::TestRng, AccessRights, Block, BlockHash, BlockHeader, BlockSignatures, BlockSignaturesV2, BlockV2, ChainNameDigest, Chainspec, ChainspecRawBytes, Deploy, DeployApprovalsHash, DeployHash, Digest, EraId, FinalitySignature, FinalitySignatureV2, Gas, InitiatorAddr, Key, ProtocolVersion, - PublicKey, SecretKey, SignedBlockHeader, TestBlockBuilder, TestBlockV1Builder, TimeDiff, - Transaction, TransactionApprovalsHash, TransactionHash, TransactionV1Hash, Transfer, URef, - U512, + PublicKey, SecretKey, SignedBlockHeader, StoredValue, TestBlockBuilder, TestBlockV1Builder, + TimeDiff, Transaction, TransactionApprovalsHash, TransactionHash, TransactionV1Hash, Transfer, + TransferV2, URef, U512, }; use tempfile::tempdir; use super::{ initialize_block_metadata_dbs, - lmdb_ext::{deserialize_internal, serialize_internal, TransactionExt, WriteTransactionExt}, + lmdb_ext::{deserialize_internal, serialize_internal}, move_storage_files_to_network_subdir, should_move_storage_files_to_network_subdir, - BlockHashHeightAndEra, Config, Storage, FORCE_RESYNC_FILE_NAME, + BlockHashHeightAndEra, Config, Storage, Transfers, FORCE_RESYNC_FILE_NAME, }; use crate::{ components::fetcher::{FetchItem, FetchResponse}, @@ -1332,7 +1329,7 @@ fn prepare_exec_result_with_transfer( rng: &mut TestRng, txn_hash: &TransactionHash, ) -> (ExecutionResult, Transfer) { - let transfer = Transfer::new( + let transfer = Transfer::V2(TransferV2::new( *txn_hash, InitiatorAddr::random(rng), Some(rng.gen()), @@ -1341,19 +1338,17 @@ fn prepare_exec_result_with_transfer( rng.gen(), Gas::from(rng.gen::()), Some(rng.gen()), - ); - let transform = TransformEntry { - key: Key::TransactionInfo(*txn_hash).to_formatted_string(), - transform: Transform::WriteTransfer(transfer.clone()), - }; - let effect = ExecutionEffect { - operations: vec![], - transforms: vec![transform], - }; - let exec_result = ExecutionResult::V1(ExecutionResultV1::Success { - effect, + )); + let transform = Transform::new( + Key::TransactionInfo(*txn_hash), + TransformKind::Write(StoredValue::Transfer(transfer.clone())), + ); + let mut effects = Effects::new(); + effects.push(transform); + let exec_result = ExecutionResult::V2(ExecutionResultV2::Success { + effects, transfers: vec![], - cost: rng.gen(), + gas: Gas::new(rng.gen::()), }); (exec_result, transfer) } @@ -1458,10 +1453,8 @@ fn should_provide_transfers_if_not_stored() { // Check the empty collection has been stored. let mut txn = storage.env.begin_ro_txn().unwrap(); - let maybe_transfers = txn - .get_value::<_, Vec>(storage.transfer_db, &block_hash) - .unwrap(); - assert_eq!(Some(vec![]), maybe_transfers); + let maybe_transfers = storage.transfer_dbs.get(&mut txn, &block_hash).unwrap(); + assert_eq!(Some(Transfers::default()), maybe_transfers); } /// This is a regression test for the issue where a valid collection of `Transfer`s under a given @@ -1501,13 +1494,10 @@ fn should_provide_transfers_after_emptied() { // Replace the valid collection with an empty one. { let mut txn = storage.env.begin_rw_txn().unwrap(); - txn.put_value( - storage.transfer_db, - &block_hash, - &Vec::::new(), - true, - ) - .unwrap(); + storage + .transfer_dbs + .put(&mut txn, &block_hash, &Transfers::default(), true) + .unwrap(); txn.commit().unwrap(); } @@ -1521,10 +1511,8 @@ fn should_provide_transfers_after_emptied() { // Check the correct value has been stored. let mut txn = storage.env.begin_ro_txn().unwrap(); - let maybe_transfers = txn - .get_value::<_, Vec>(storage.transfer_db, &block_hash) - .unwrap(); - assert_eq!(Some(vec![transfer]), maybe_transfers); + let maybe_transfers = storage.transfer_dbs.get(&mut txn, &block_hash).unwrap(); + assert_eq!(Some(Transfers(vec![transfer])), maybe_transfers); } /// Example state used in storage. @@ -3011,9 +2999,9 @@ fn check_block_operations_with_node_1_5_2_storage() { let mut stored_transfers: Vec = transfers .unwrap() .iter() - .map(|transfer| match transfer.transaction_hash { - TransactionHash::Deploy(deploy_hash) => deploy_hash, - TransactionHash::V1(_) => panic!("expected deploy"), + .map(|transfer| match transfer { + Transfer::V1(transfer_v1) => transfer_v1.deploy_hash, + _ => panic!("expected transfer v1 variant"), }) .collect(); stored_transfers.sort(); diff --git a/node/src/components/storage/transfers.rs b/node/src/components/storage/transfers.rs new file mode 100644 index 0000000000..14dd58513c --- /dev/null +++ b/node/src/components/storage/transfers.rs @@ -0,0 +1,39 @@ +use serde::{Deserialize, Serialize}; + +use casper_types::{ + bytesrepr::{self, FromBytes, ToBytes}, + Transfer, TransferV1, +}; + +/// A wrapped `Vec`, used as the value type in the `transfer_dbs`. +/// +/// It exists to allow the `impl From>` to be written, making the +#[derive(Clone, Default, Serialize, Deserialize, Debug, PartialEq, Eq)] +pub(super) struct Transfers(pub(super) Vec); + +impl From> for Transfers { + fn from(v1_transfers: Vec) -> Self { + Transfers(v1_transfers.into_iter().map(Transfer::V1).collect()) + } +} + +impl ToBytes for Transfers { + fn to_bytes(&self) -> Result, bytesrepr::Error> { + self.0.to_bytes() + } + + fn serialized_length(&self) -> usize { + self.0.serialized_length() + } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + self.0.write_bytes(writer) + } +} + +impl FromBytes for Transfers { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + Vec::::from_bytes(bytes) + .map(|(transfers, remainder)| (Transfers(transfers), remainder)) + } +} diff --git a/node/src/components/storage/versioned_databases.rs b/node/src/components/storage/versioned_databases.rs index 585a1b8565..33ecd811d7 100644 --- a/node/src/components/storage/versioned_databases.rs +++ b/node/src/components/storage/versioned_databases.rs @@ -17,12 +17,12 @@ use casper_types::{ bytesrepr::{FromBytes, ToBytes}, execution::ExecutionResult, BlockBody, BlockBodyV1, BlockHash, BlockHeader, BlockHeaderV1, BlockSignatures, - BlockSignaturesV1, Deploy, DeployHash, Digest, Transaction, TransactionHash, + BlockSignaturesV1, Deploy, DeployHash, Digest, Transaction, TransactionHash, TransferV1, }; use super::{ lmdb_ext::{self, LmdbExtError, TransactionExt, WriteTransactionExt}, - DeployMetadataV1, FatalStorageError, LegacyApprovalsHashes, + DeployMetadataV1, FatalStorageError, LegacyApprovalsHashes, Transfers, }; use crate::types::{ApprovalsHashes, FinalizedApprovals, FinalizedDeployApprovals}; @@ -91,6 +91,10 @@ impl VersionedValue for BlockSignatures { type Legacy = BlockSignaturesV1; } +impl VersionedValue for Transfers { + type Legacy = Vec; +} + /// A pair of databases, one holding the original legacy form of the data, and the other holding the /// new versioned, future-proof form of the data. /// diff --git a/node/src/types/block/block_execution_results_or_chunk.rs b/node/src/types/block/block_execution_results_or_chunk.rs index bb0a2f8e64..7e2d502688 100644 --- a/node/src/types/block/block_execution_results_or_chunk.rs +++ b/node/src/types/block/block_execution_results_or_chunk.rs @@ -293,7 +293,7 @@ mod tests { use casper_types::{ execution::{execution_result_v1::ExecutionEffect, ExecutionResultV1}, testing::TestRng, - ChunkWithProof, TransferAddr, + ChunkWithProof, TransferV1Addr, }; use super::*; @@ -315,7 +315,7 @@ mod tests { // The serialized_length() of this should be equal to `ChunkWithProof::CHUNK_SIZE_BYTES` let execution_results_v1 = vec![ExecutionResultV1::Failure { effect: ExecutionEffect::default(), - transfers: vec![TransferAddr::new([1; 32]); 262143], + transfers: vec![TransferV1Addr::new([1; 32]); 262143], cost: 2_u64.into(), error_message: "ninebytes".to_string(), }]; diff --git a/resources/test/rpc_schema.json b/resources/test/rpc_schema.json index 007976a8c8..61cbf6953c 100644 --- a/resources/test/rpc_schema.json +++ b/resources/test/rpc_schema.json @@ -392,8 +392,12 @@ } ], "transfers": [ - "transfer-5959595959595959595959595959595959595959595959595959595959595959", - "transfer-8282828282828282828282828282828282828282828282828282828282828282" + { + "Version2": "transfer-v2-5959595959595959595959595959595959595959595959595959595959595959" + }, + { + "Version2": "transfer-v2-8282828282828282828282828282828282828282828282828282828282828282" + } ], "gas": "123456" } @@ -570,8 +574,12 @@ } ], "transfers": [ - "transfer-5959595959595959595959595959595959595959595959595959595959595959", - "transfer-8282828282828282828282828282828282828282828282828282828282828282" + { + "Version2": "transfer-v2-5959595959595959595959595959595959595959595959595959595959595959" + }, + { + "Version2": "transfer-v2-8282828282828282828282828282828282828282828282828282828282828282" + } ], "gas": "123456" } @@ -1519,18 +1527,20 @@ "block_hash": "0707070707070707070707070707070707070707070707070707070707070707", "transfers": [ { - "transaction_hash": { - "Version1": "0909090909090909090909090909090909090909090909090909090909090909" - }, - "from": { - "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c" - }, - "to": "account-hash-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a", - "source": "uref-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b-007", - "target": "uref-0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c-000", - "amount": "3000000000", - "gas": "2500000000", - "id": 9 + "Version2": { + "transaction_hash": { + "Version1": "0909090909090909090909090909090909090909090909090909090909090909" + }, + "from": { + "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c" + }, + "to": "account-hash-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a", + "source": "uref-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b-007", + "target": "uref-0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c-000", + "amount": "3000000000", + "gas": "2500000000", + "id": 9 + } } ] } @@ -3374,10 +3384,10 @@ ] }, "transfers": { - "description": "A record of Transfers performed while executing the deploy.", + "description": "A record of version 1 Transfers performed while executing the deploy.", "type": "array", "items": { - "$ref": "#/components/schemas/TransferAddr" + "$ref": "#/components/schemas/TransferV1Addr" } }, "cost": { @@ -3425,7 +3435,7 @@ "description": "A record of Transfers performed while executing the deploy.", "type": "array", "items": { - "$ref": "#/components/schemas/TransferAddr" + "$ref": "#/components/schemas/TransferV1Addr" } }, "cost": { @@ -3639,14 +3649,14 @@ "additionalProperties": false }, { - "description": "Writes the given Transfer to global state.", + "description": "Writes the given version 1 Transfer to global state.", "type": "object", "required": [ "WriteTransfer" ], "properties": { "WriteTransfer": { - "$ref": "#/components/schemas/Transfer" + "$ref": "#/components/schemas/TransferV1" } }, "additionalProperties": false @@ -3848,10 +3858,10 @@ ] }, "transfers": { - "description": "Transfers performed by the Deploy.", + "description": "Version 1 transfers performed by the Deploy.", "type": "array", "items": { - "$ref": "#/components/schemas/TransferAddr" + "$ref": "#/components/schemas/TransferV1Addr" } }, "from": { @@ -3881,8 +3891,8 @@ }, "additionalProperties": false }, - "TransferAddr": { - "description": "Hex-encoded transfer address.", + "TransferV1Addr": { + "description": "Hex-encoded version 1 transfer address.", "type": "string" }, "URef": { @@ -3995,36 +4005,36 @@ } ] }, - "Transfer": { - "description": "Represents a transfer from one purse to another", + "TransferV1": { + "description": "Represents a version 1 transfer from one purse to another.", "type": "object", "required": [ "amount", + "deploy_hash", "from", "gas", "source", - "target", - "transaction_hash" + "target" ], "properties": { - "transaction_hash": { - "description": "Transaction that created the transfer.", + "deploy_hash": { + "description": "Hex-encoded Deploy hash of Deploy that created the transfer.", "allOf": [ { - "$ref": "#/components/schemas/TransactionHash" + "$ref": "#/components/schemas/DeployHash" } ] }, "from": { - "description": "Entity from which transfer was executed.", + "description": "Account from which transfer was executed", "allOf": [ { - "$ref": "#/components/schemas/InitiatorAddr" + "$ref": "#/components/schemas/AccountHash" } ] }, "to": { - "description": "Account to which funds are transferred.", + "description": "Account to which funds are transferred", "anyOf": [ { "$ref": "#/components/schemas/AccountHash" @@ -4035,7 +4045,7 @@ ] }, "source": { - "description": "Source purse.", + "description": "Source purse", "allOf": [ { "$ref": "#/components/schemas/URef" @@ -4043,7 +4053,7 @@ ] }, "target": { - "description": "Target purse.", + "description": "Target purse", "allOf": [ { "$ref": "#/components/schemas/URef" @@ -4051,7 +4061,7 @@ ] }, "amount": { - "description": "Transfer amount.", + "description": "Transfer amount", "allOf": [ { "$ref": "#/components/schemas/U512" @@ -4059,15 +4069,15 @@ ] }, "gas": { - "description": "Gas.", + "description": "Gas", "allOf": [ { - "$ref": "#/components/schemas/Gas" + "$ref": "#/components/schemas/U512" } ] }, "id": { - "description": "User-defined ID.", + "description": "User-defined id", "type": [ "integer", "null" @@ -4078,14 +4088,6 @@ }, "additionalProperties": false }, - "Gas": { - "description": "The `Gas` struct represents a `U512` amount of gas.", - "allOf": [ - { - "$ref": "#/components/schemas/U512" - } - ] - }, "Bid": { "description": "An entry in the validator map.", "type": "object", @@ -4604,6 +4606,49 @@ "$ref": "#/components/schemas/Transform" } }, + "TransferAddr": { + "description": "A versioned wrapper for a transfer address.", + "oneOf": [ + { + "description": "A version 1 transfer address.", + "type": "object", + "required": [ + "Version1" + ], + "properties": { + "Version1": { + "$ref": "#/components/schemas/TransferV1Addr" + } + }, + "additionalProperties": false + }, + { + "description": "A version 2 transfer address.", + "type": "object", + "required": [ + "Version2" + ], + "properties": { + "Version2": { + "$ref": "#/components/schemas/TransferV2Addr" + } + }, + "additionalProperties": false + } + ] + }, + "TransferV2Addr": { + "description": "Hex-encoded version 2 transfer address.", + "type": "string" + }, + "Gas": { + "description": "The `Gas` struct represents a `U512` amount of gas.", + "allOf": [ + { + "$ref": "#/components/schemas/U512" + } + ] + }, "AccountIdentifier": { "description": "Identifier of an account.", "anyOf": [ @@ -4951,14 +4996,14 @@ "additionalProperties": false }, { - "description": "A `Transfer`.", + "description": "A version 1 (legacy) transfer.", "type": "object", "required": [ - "Transfer" + "LegacyTransfer" ], "properties": { - "Transfer": { - "$ref": "#/components/schemas/Transfer" + "LegacyTransfer": { + "$ref": "#/components/schemas/TransferV1" } }, "additionalProperties": false @@ -5137,6 +5182,19 @@ } }, "additionalProperties": false + }, + { + "description": "A versioned transfer.", + "type": "object", + "required": [ + "Transfer" + ], + "properties": { + "Transfer": { + "$ref": "#/components/schemas/Transfer" + } + }, + "additionalProperties": false } ] }, @@ -5870,6 +5928,120 @@ }, "additionalProperties": false }, + "Transfer": { + "description": "A versioned wrapper for a transfer.", + "oneOf": [ + { + "description": "A version 1 transfer.", + "type": "object", + "required": [ + "Version1" + ], + "properties": { + "Version1": { + "$ref": "#/components/schemas/TransferV1" + } + }, + "additionalProperties": false + }, + { + "description": "A version 2 transfer.", + "type": "object", + "required": [ + "Version2" + ], + "properties": { + "Version2": { + "$ref": "#/components/schemas/TransferV2" + } + }, + "additionalProperties": false + } + ] + }, + "TransferV2": { + "description": "Represents a version 2 transfer from one purse to another.", + "type": "object", + "required": [ + "amount", + "from", + "gas", + "source", + "target", + "transaction_hash" + ], + "properties": { + "transaction_hash": { + "description": "Transaction that created the transfer.", + "allOf": [ + { + "$ref": "#/components/schemas/TransactionHash" + } + ] + }, + "from": { + "description": "Entity from which transfer was executed.", + "allOf": [ + { + "$ref": "#/components/schemas/InitiatorAddr" + } + ] + }, + "to": { + "description": "Account to which funds are transferred.", + "anyOf": [ + { + "$ref": "#/components/schemas/AccountHash" + }, + { + "type": "null" + } + ] + }, + "source": { + "description": "Source purse.", + "allOf": [ + { + "$ref": "#/components/schemas/URef" + } + ] + }, + "target": { + "description": "Target purse.", + "allOf": [ + { + "$ref": "#/components/schemas/URef" + } + ] + }, + "amount": { + "description": "Transfer amount.", + "allOf": [ + { + "$ref": "#/components/schemas/U512" + } + ] + }, + "gas": { + "description": "Gas.", + "allOf": [ + { + "$ref": "#/components/schemas/Gas" + } + ] + }, + "id": { + "description": "User-defined ID.", + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, "GlobalStateIdentifier": { "description": "Identifier for possible ways to query Global State", "oneOf": [ diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index 7f4fa5f75a..16679d2964 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -2120,10 +2120,10 @@ ] }, "transfers": { - "description": "A record of Transfers performed while executing the deploy.", + "description": "A record of version 1 Transfers performed while executing the deploy.", "type": "array", "items": { - "$ref": "#/definitions/TransferAddr" + "$ref": "#/definitions/TransferV1Addr" } }, "cost": { @@ -2171,7 +2171,7 @@ "description": "A record of Transfers performed while executing the deploy.", "type": "array", "items": { - "$ref": "#/definitions/TransferAddr" + "$ref": "#/definitions/TransferV1Addr" } }, "cost": { @@ -2385,14 +2385,14 @@ "additionalProperties": false }, { - "description": "Writes the given Transfer to global state.", + "description": "Writes the given version 1 Transfer to global state.", "type": "object", "required": [ "WriteTransfer" ], "properties": { "WriteTransfer": { - "$ref": "#/definitions/Transfer" + "$ref": "#/definitions/TransferV1" } }, "additionalProperties": false @@ -2594,10 +2594,10 @@ ] }, "transfers": { - "description": "Transfers performed by the Deploy.", + "description": "Version 1 transfers performed by the Deploy.", "type": "array", "items": { - "$ref": "#/definitions/TransferAddr" + "$ref": "#/definitions/TransferV1Addr" } }, "from": { @@ -2627,8 +2627,8 @@ }, "additionalProperties": false }, - "TransferAddr": { - "description": "Hex-encoded transfer address.", + "TransferV1Addr": { + "description": "Hex-encoded version 1 transfer address.", "type": "string" }, "URef": { @@ -2737,36 +2737,36 @@ } ] }, - "Transfer": { - "description": "Represents a transfer from one purse to another", + "TransferV1": { + "description": "Represents a version 1 transfer from one purse to another.", "type": "object", "required": [ "amount", + "deploy_hash", "from", "gas", "source", - "target", - "transaction_hash" + "target" ], "properties": { - "transaction_hash": { - "description": "Transaction that created the transfer.", + "deploy_hash": { + "description": "Hex-encoded Deploy hash of Deploy that created the transfer.", "allOf": [ { - "$ref": "#/definitions/TransactionHash" + "$ref": "#/definitions/DeployHash" } ] }, "from": { - "description": "Entity from which transfer was executed.", + "description": "Account from which transfer was executed", "allOf": [ { - "$ref": "#/definitions/InitiatorAddr" + "$ref": "#/definitions/AccountHash" } ] }, "to": { - "description": "Account to which funds are transferred.", + "description": "Account to which funds are transferred", "anyOf": [ { "$ref": "#/definitions/AccountHash" @@ -2777,7 +2777,7 @@ ] }, "source": { - "description": "Source purse.", + "description": "Source purse", "allOf": [ { "$ref": "#/definitions/URef" @@ -2785,7 +2785,7 @@ ] }, "target": { - "description": "Target purse.", + "description": "Target purse", "allOf": [ { "$ref": "#/definitions/URef" @@ -2793,7 +2793,7 @@ ] }, "amount": { - "description": "Transfer amount.", + "description": "Transfer amount", "allOf": [ { "$ref": "#/definitions/U512" @@ -2801,15 +2801,15 @@ ] }, "gas": { - "description": "Gas.", + "description": "Gas", "allOf": [ { - "$ref": "#/definitions/Gas" + "$ref": "#/definitions/U512" } ] }, "id": { - "description": "User-defined ID.", + "description": "User-defined id", "type": [ "integer", "null" @@ -2820,14 +2820,6 @@ }, "additionalProperties": false }, - "Gas": { - "description": "The `Gas` struct represents a `U512` amount of gas.", - "allOf": [ - { - "$ref": "#/definitions/U512" - } - ] - }, "Bid": { "description": "An entry in the validator map.", "type": "object", @@ -3346,6 +3338,49 @@ "$ref": "#/definitions/Transform" } }, + "TransferAddr": { + "description": "A versioned wrapper for a transfer address.", + "oneOf": [ + { + "description": "A version 1 transfer address.", + "type": "object", + "required": [ + "Version1" + ], + "properties": { + "Version1": { + "$ref": "#/definitions/TransferV1Addr" + } + }, + "additionalProperties": false + }, + { + "description": "A version 2 transfer address.", + "type": "object", + "required": [ + "Version2" + ], + "properties": { + "Version2": { + "$ref": "#/definitions/TransferV2Addr" + } + }, + "additionalProperties": false + } + ] + }, + "TransferV2Addr": { + "description": "Hex-encoded version 2 transfer address.", + "type": "string" + }, + "Gas": { + "description": "The `Gas` struct represents a `U512` amount of gas.", + "allOf": [ + { + "$ref": "#/definitions/U512" + } + ] + }, "Message": { "description": "Message that was emitted by an addressable entity during execution.", "type": "object", diff --git a/storage/src/data_access_layer.rs b/storage/src/data_access_layer.rs index 89f5e18309..3c4f1f84a1 100644 --- a/storage/src/data_access_layer.rs +++ b/storage/src/data_access_layer.rs @@ -25,6 +25,7 @@ mod trie; pub use addressable_entity::{AddressableEntityRequest, AddressableEntityResult}; pub use balance::{BalanceRequest, BalanceResult}; pub use era_validators::{EraValidatorsRequest, EraValidatorsResult}; +pub use execute::{ExecuteNativeRequest, NativeEntryPoint, NewNativeRequestError}; pub use execution_results_checksum::{ ExecutionResultsChecksumRequest, ExecutionResultsChecksumResult, EXECUTION_RESULTS_CHECKSUM_NAME, diff --git a/storage/src/data_access_layer/transfer.rs b/storage/src/data_access_layer/transfer.rs index a64fcf0b90..42143ee465 100644 --- a/storage/src/data_access_layer/transfer.rs +++ b/storage/src/data_access_layer/transfer.rs @@ -1,8 +1,8 @@ use std::collections::BTreeSet; use casper_types::{ - account::AccountHash, execution::Effects, Digest, ProtocolVersion, PublicKey, RuntimeArgs, - TransferAddr, U512, + account::AccountHash, execution::Effects, Digest, Gas, InitiatorAddr, ProtocolVersion, + PublicKey, RuntimeArgs, TransactionHash, TransferAddr, }; use crate::system::transfer::{TransferArgs, TransferError}; @@ -92,15 +92,15 @@ pub struct TransferRequest { /// Public key of the proposer. proposer: PublicKey, /// Transaction hash. - transaction_hash: Digest, + transaction_hash: TransactionHash, /// Base account. - address: AccountHash, + initiator: InitiatorAddr, /// List of authorizing accounts. authorization_keys: BTreeSet, /// Args. args: TransferRequestArgs, /// Cost. - cost: U512, + gas: Gas, } impl TransferRequest { @@ -112,11 +112,11 @@ impl TransferRequest { block_time: u64, protocol_version: ProtocolVersion, proposer: PublicKey, - transaction_hash: Digest, - address: AccountHash, + transaction_hash: TransactionHash, + initiator: InitiatorAddr, authorization_keys: BTreeSet, args: TransferArgs, - cost: U512, + gas: Gas, ) -> Self { let args = TransferRequestArgs::Explicit(args); Self { @@ -126,10 +126,10 @@ impl TransferRequest { protocol_version, proposer, transaction_hash, - address, + initiator, authorization_keys, args, - cost, + gas, } } @@ -141,11 +141,11 @@ impl TransferRequest { block_time: u64, protocol_version: ProtocolVersion, proposer: PublicKey, - transaction_hash: Digest, // <-- TODO: this should probably be TransactionHash - address: AccountHash, + transaction_hash: TransactionHash, + initiator: InitiatorAddr, authorization_keys: BTreeSet, args: RuntimeArgs, - cost: U512, + gas: Gas, ) -> Self { let args = TransferRequestArgs::Raw(args); Self { @@ -155,10 +155,10 @@ impl TransferRequest { protocol_version, proposer, transaction_hash, - address, + initiator, authorization_keys, args, - cost, + gas, } } @@ -171,9 +171,9 @@ impl TransferRequest { self.state_hash } - /// Returns address. - pub fn address(&self) -> AccountHash { - self.address + /// Returns initiator. + pub fn initiator(&self) -> &InitiatorAddr { + &self.initiator } /// Returns authorization keys. @@ -192,7 +192,7 @@ impl TransferRequest { } /// Returns transaction hash. - pub fn transaction_hash(&self) -> Digest { + pub fn transaction_hash(&self) -> TransactionHash { self.transaction_hash } @@ -202,8 +202,8 @@ impl TransferRequest { } /// The cost. - pub fn cost(&self) -> U512 { - self.cost + pub fn gas(&self) -> Gas { + self.gas } /// Returns transfer args. diff --git a/storage/src/global_state/state/mod.rs b/storage/src/global_state/state/mod.rs index 318d04e9f0..4629b473d7 100644 --- a/storage/src/global_state/state/mod.rs +++ b/storage/src/global_state/state/mod.rs @@ -19,8 +19,8 @@ use casper_types::{ mint::{ARG_AMOUNT, ROUND_SEIGNIORAGE_RATE_KEY, TOTAL_SUPPLY_KEY}, AUCTION, MINT, }, - Account, AddressableEntity, AddressableEntityHash, DeployHash, Digest, EntityAddr, Key, KeyTag, - Phase, PublicKey, RuntimeArgs, StoredValue, U512, + Account, AddressableEntity, AddressableEntityHash, Digest, EntityAddr, Key, KeyTag, Phase, + PublicKey, RuntimeArgs, StoredValue, TransactionInfo, U512, }; #[cfg(test)] @@ -184,7 +184,7 @@ pub trait CommitProvider: StateProvider { } }; - let account_hash = request.address(); + let account_hash = request.initiator().account_hash(); let protocol_version = request.protocol_version(); if let Err(tce) = tc .borrow_mut() @@ -328,22 +328,17 @@ pub trait CommitProvider: StateProvider { let transfers = mint_provider.into_transfers(); - { - // TODO: this block needs to be updated with version management for new style - // Transactions - let deploy_hash = DeployHash::new(request.transaction_hash()); - let deploy_info = casper_types::DeployInfo::new( - deploy_hash, - &transfers, - account_hash, - entity.main_purse(), - request.cost(), - ); - tc.borrow_mut().write( - Key::DeployInfo(deploy_hash), - StoredValue::DeployInfo(deploy_info), - ); - } + let txn_info = TransactionInfo::new( + request.transaction_hash(), + transfers.clone(), + request.initiator().clone(), + entity.main_purse(), + request.gas(), + ); + tc.borrow_mut().write( + Key::TransactionInfo(txn_info.transaction_hash), + StoredValue::TransactionInfo(txn_info), + ); let effects = tc.borrow_mut().effects(); diff --git a/storage/src/system/mint/mint_native.rs b/storage/src/system/mint/mint_native.rs index b5de5d1ec5..bcae829a3f 100644 --- a/storage/src/system/mint/mint_native.rs +++ b/storage/src/system/mint/mint_native.rs @@ -19,9 +19,9 @@ use casper_types::{ addressable_entity::NamedKeys, bytesrepr::{FromBytes, ToBytes}, system::{mint::Error, Caller}, - AccessRights, AddressableEntity, CLTyped, CLValue, ContextAccessRights, DeployHash, Digest, - Gas, InitiatorAddr, Key, Phase, ProtocolVersion, PublicKey, StoredValue, SystemEntityRegistry, - TransactionHash, Transfer, TransferAddr, URef, U512, + AccessRights, AddressableEntity, CLTyped, CLValue, ContextAccessRights, Gas, InitiatorAddr, + Key, Phase, ProtocolVersion, PublicKey, StoredValue, SystemEntityRegistry, TransactionHash, + Transfer, TransferAddr, TransferV2, TransferV2Addr, URef, U512, }; pub struct NativeMintRuntime { @@ -36,7 +36,7 @@ pub struct NativeMintRuntime { access_rights: ContextAccessRights, remaining_spending_limit: U512, transfers: Vec, - transaction_hash: Digest, + transaction_hash: TransactionHash, phase: Phase, } @@ -54,10 +54,14 @@ where named_keys: NamedKeys, access_rights: ContextAccessRights, remaining_spending_limit: U512, - transaction_hash: Digest, + transaction_hash: TransactionHash, phase: Phase, ) -> Self { - let address_generator = AddressGenerator::new(transaction_hash.as_ref(), phase); + let hash_slice = match &transaction_hash { + TransactionHash::Deploy(hash) => hash.as_ref(), + TransactionHash::V1(hash) => hash.as_ref(), + }; + let address_generator = AddressGenerator::new(hash_slice, phase); let transfers = vec![]; NativeMintRuntime { address_generator, @@ -270,23 +274,16 @@ where if self.phase != Phase::Session { return Ok(()); } - let transfer_addr = TransferAddr::new(self.address_generator.create_address()); - let key = Key::Transfer(transfer_addr); // <-- a new key variant needed to deal w/ versioned transaction hash - let transaction_hash = self.transaction_hash; - let transfer = { - // the below line is incorrect; new transaction hash is not currently supported here - // ...the transfer struct needs to be upgraded to TransactionHash - let deploy_hash = TransactionHash::Deploy(DeployHash::new(transaction_hash)); - let from = InitiatorAddr::AccountHash(self.get_caller()); - let fee = Gas::zero(); - Transfer::new(deploy_hash, from, maybe_to, source, target, amount, fee, id) - }; - { - // im not sure why we need to collate these, but matching the existing impl - let transfers = &mut self.transfers; - transfers.push(transfer_addr); - } - + let transfer_addr = + TransferAddr::from(TransferV2Addr::new(self.address_generator.create_address())); + let key = Key::Transfer(transfer_addr); + let txn_hash = self.transaction_hash; + let from = InitiatorAddr::AccountHash(self.get_caller()); + let fee = Gas::zero(); // TODO + let transfer = Transfer::V2(TransferV2::new( + txn_hash, from, maybe_to, source, target, amount, fee, id, + )); + self.transfers.push(transfer_addr); self.tracking_copy .borrow_mut() .write(key, StoredValue::Transfer(transfer)); diff --git a/storage/src/tracking_copy/byte_size.rs b/storage/src/tracking_copy/byte_size.rs index 43f4829637..12f8fa91ba 100644 --- a/storage/src/tracking_copy/byte_size.rs +++ b/storage/src/tracking_copy/byte_size.rs @@ -35,7 +35,7 @@ impl ByteSize for StoredValue { } StoredValue::Package(package) => package.serialized_length(), StoredValue::DeployInfo(deploy_info) => deploy_info.serialized_length(), - StoredValue::Transfer(transfer) => transfer.serialized_length(), + StoredValue::LegacyTransfer(transfer_v1) => transfer_v1.serialized_length(), StoredValue::EraInfo(era_info) => era_info.serialized_length(), StoredValue::Bid(bid) => bid.serialized_length(), StoredValue::BidKind(bid_kind) => bid_kind.serialized_length(), @@ -48,6 +48,7 @@ impl ByteSize for StoredValue { StoredValue::Message(message_summary) => message_summary.serialized_length(), StoredValue::NamedKey(named_key) => named_key.serialized_length(), StoredValue::TransactionInfo(info) => info.serialized_length(), + StoredValue::Transfer(transfer) => transfer.serialized_length(), } } } diff --git a/storage/src/tracking_copy/mod.rs b/storage/src/tracking_copy/mod.rs index b16d58e034..6305a95d7e 100644 --- a/storage/src/tracking_copy/mod.rs +++ b/storage/src/tracking_copy/mod.rs @@ -632,8 +632,8 @@ where StoredValue::ByteCode(_) => { return Ok(query.into_not_found_result("ByteCode value found.")); } - StoredValue::Transfer(_) => { - return Ok(query.into_not_found_result("Transfer value found.")); + StoredValue::LegacyTransfer(_) => { + return Ok(query.into_not_found_result("Legacy Transfer value found.")); } StoredValue::DeployInfo(_) => { return Ok(query.into_not_found_result("DeployInfo value found.")); @@ -662,6 +662,9 @@ where StoredValue::TransactionInfo(_) => { return Ok(query.into_not_found_result("TransactionInfo value found.")); } + StoredValue::Transfer(_) => { + return Ok(query.into_not_found_result("Transfer value found.")); + } } } } diff --git a/types/benches/bytesrepr_bench.rs b/types/benches/bytesrepr_bench.rs index 12223c34aa..628bce93aa 100644 --- a/types/benches/bytesrepr_bench.rs +++ b/types/benches/bytesrepr_bench.rs @@ -15,8 +15,9 @@ use casper_types::{ AccessRights, AddressableEntityHash, ByteCodeHash, CLType, CLTyped, CLValue, DeployHash, DeployInfo, EntityVersionKey, EntityVersions, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Gas, Group, Groups, InitiatorAddr, Key, Package, PackageHash, PackageStatus, - Parameter, ProtocolVersion, PublicKey, SecretKey, TransactionHash, TransactionV1Hash, Transfer, - TransferAddr, URef, KEY_HASH_LENGTH, TRANSFER_ADDR_LENGTH, U128, U256, U512, UREF_ADDR_LENGTH, + Parameter, ProtocolVersion, PublicKey, SecretKey, TransactionHash, TransactionV1Hash, + TransferV1Addr, TransferV2, URef, KEY_HASH_LENGTH, TRANSFER_V1_ADDR_LENGTH, U128, U256, U512, + UREF_ADDR_LENGTH, }; static KB: usize = 1024; @@ -619,8 +620,8 @@ fn deserialize_bid(delegators_len: u32, b: &mut Bencher) { b.iter(|| Bid::from_bytes(black_box(&bid_bytes))); } -fn sample_transfer() -> Transfer { - Transfer::new( +fn sample_transfer() -> TransferV2 { + TransferV2::new( TransactionHash::V1(TransactionV1Hash::default()), InitiatorAddr::AccountHash(AccountHash::default()), None, @@ -634,21 +635,21 @@ fn sample_transfer() -> Transfer { fn serialize_transfer(b: &mut Bencher) { let transfer = sample_transfer(); - b.iter(|| Transfer::to_bytes(&transfer)); + b.iter(|| TransferV2::to_bytes(&transfer)); } fn deserialize_transfer(b: &mut Bencher) { let transfer = sample_transfer(); let transfer_bytes = transfer.to_bytes().unwrap(); - b.iter(|| Transfer::from_bytes(&transfer_bytes)); + b.iter(|| TransferV2::from_bytes(&transfer_bytes)); } fn sample_deploy_info(transfer_len: u16) -> DeployInfo { let transfers = (0..transfer_len) .map(|i| { - let mut tmp = [0u8; TRANSFER_ADDR_LENGTH]; + let mut tmp = [0u8; TRANSFER_V1_ADDR_LENGTH]; U256::from(i).to_little_endian(&mut tmp); - TransferAddr::new(tmp) + TransferV1Addr::new(tmp) }) .collect::>(); DeployInfo::new( diff --git a/types/src/cl_value.rs b/types/src/cl_value.rs index 5d0e10ec73..c1735bdfc9 100644 --- a/types/src/cl_value.rs +++ b/types/src/cl_value.rs @@ -262,8 +262,8 @@ mod tests { use crate::{ account::{AccountHash, ACCOUNT_HASH_LENGTH}, key::KEY_HASH_LENGTH, - AccessRights, DeployHash, Digest, Key, PublicKey, TransferAddr, URef, TRANSFER_ADDR_LENGTH, - U128, U256, U512, UREF_ADDR_LENGTH, + AccessRights, DeployHash, Digest, Key, PublicKey, TransferV1Addr, URef, + TRANSFER_V1_ADDR_LENGTH, U128, U256, U512, UREF_ADDR_LENGTH, }; #[cfg(feature = "json-schema")] @@ -425,7 +425,8 @@ mod tests { r#"{"cl_type":"Key","parsed":"uref-0303030303030303030303030303030303030303030303030303030303030303-001"}"#, ); - let key_transfer = Key::Transfer(TransferAddr::new([4; TRANSFER_ADDR_LENGTH])); + let key_transfer = + Key::LegacyTransfer(TransferV1Addr::new([4; TRANSFER_V1_ADDR_LENGTH])); check_to_json( key_transfer, r#"{"cl_type":"Key","parsed":"transfer-0404040404040404040404040404040404040404040404040404040404040404"}"#, @@ -647,7 +648,8 @@ mod tests { r#"{"cl_type":{"Option":"Key"},"parsed":"uref-0303030303030303030303030303030303030303030303030303030303030303-001"}"#, ); - let key_transfer = Key::Transfer(TransferAddr::new([4; TRANSFER_ADDR_LENGTH])); + let key_transfer = + Key::LegacyTransfer(TransferV1Addr::new([4; TRANSFER_V1_ADDR_LENGTH])); check_to_json( Some(key_transfer), r#"{"cl_type":{"Option":"Key"},"parsed":"transfer-0404040404040404040404040404040404040404040404040404040404040404"}"#, diff --git a/types/src/deploy_info.rs b/types/src/deploy_info.rs index 6f4da83582..c0bad8e239 100644 --- a/types/src/deploy_info.rs +++ b/types/src/deploy_info.rs @@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize}; use crate::{ account::AccountHash, bytesrepr::{self, FromBytes, ToBytes}, - serde_helpers, DeployHash, TransferAddr, URef, U512, + serde_helpers, DeployHash, TransferV1Addr, URef, U512, }; /// Information relating to the given Deploy. @@ -25,8 +25,8 @@ pub struct DeployInfo { schemars(with = "DeployHash", description = "Hex-encoded Deploy hash.") )] pub deploy_hash: DeployHash, - /// Transfers performed by the Deploy. - pub transfers: Vec, + /// Version 1 transfers performed by the Deploy. + pub transfers: Vec, /// Account identifier of the creator of the Deploy. pub from: AccountHash, /// Source purse used for payment of the Deploy. @@ -39,7 +39,7 @@ impl DeployInfo { /// Creates a [`DeployInfo`]. pub fn new( deploy_hash: DeployHash, - transfers: &[TransferAddr], + transfers: &[TransferV1Addr], from: AccountHash, source: URef, gas: U512, @@ -58,7 +58,7 @@ impl DeployInfo { impl FromBytes for DeployInfo { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { let (deploy_hash, rem) = DeployHash::from_bytes(bytes)?; - let (transfers, rem) = Vec::::from_bytes(rem)?; + let (transfers, rem) = Vec::::from_bytes(rem)?; let (from, rem) = AccountHash::from_bytes(rem)?; let (source, rem) = URef::from_bytes(rem)?; let (gas, rem) = U512::from_bytes(rem)?; @@ -107,11 +107,11 @@ impl ToBytes for DeployInfo { /// Generators for a `DeployInfo` #[cfg(any(feature = "testing", feature = "gens", test))] pub(crate) mod gens { - use proptest::prelude::Strategy; + use proptest::{collection, prelude::Strategy}; use crate::{ gens::{u512_arb, uref_arb}, - transaction_info::gens::{account_hash_arb, deploy_hash_arb, transfers_arb}, + transaction_info::gens::{account_hash_arb, deploy_hash_arb, transfer_v1_addr_arb}, DeployInfo, }; @@ -119,7 +119,7 @@ pub(crate) mod gens { let transfers_length_range = 0..5; ( deploy_hash_arb(), - transfers_arb(transfers_length_range), + collection::vec(transfer_v1_addr_arb(), transfers_length_range), account_hash_arb(), uref_arb(), u512_arb(), diff --git a/types/src/execution/execution_result_v1.rs b/types/src/execution/execution_result_v1.rs index 377af24f64..26ee3c0b76 100644 --- a/types/src/execution/execution_result_v1.rs +++ b/types/src/execution/execution_result_v1.rs @@ -22,7 +22,7 @@ use crate::{ account::AccountHash, bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, system::auction::{Bid, BidKind, EraInfo, UnbondingPurse, WithdrawPurse}, - CLValue, DeployInfo, Key, Transfer, TransferAddr, U128, U256, U512, + CLValue, DeployInfo, Key, TransferV1, TransferV1Addr, U128, U256, U512, }; #[derive(FromPrimitive, ToPrimitive, Debug)] @@ -103,8 +103,8 @@ pub enum ExecutionResultV1 { Failure { /// The effect of executing the deploy. effect: ExecutionEffect, - /// A record of Transfers performed while executing the deploy. - transfers: Vec, + /// A record of version 1 Transfers performed while executing the deploy. + transfers: Vec, /// The cost of executing the deploy. cost: U512, /// The error message associated with executing the deploy. @@ -115,7 +115,7 @@ pub enum ExecutionResultV1 { /// The effect of executing the deploy. effect: ExecutionEffect, /// A record of Transfers performed while executing the deploy. - transfers: Vec, + transfers: Vec, /// The cost of executing the deploy. cost: U512, }, @@ -153,7 +153,7 @@ impl Distribution for Standard { let transfer_count = rng.gen_range(0..6); let mut transfers = Vec::new(); for _ in 0..transfer_count { - transfers.push(TransferAddr::new(rng.gen())) + transfers.push(TransferV1Addr::new(rng.gen())) } if rng.gen() { @@ -240,7 +240,7 @@ impl FromBytes for ExecutionResultV1 { match TryFrom::try_from(tag)? { ExecutionResultTag::Failure => { let (effect, remainder) = ExecutionEffect::from_bytes(remainder)?; - let (transfers, remainder) = Vec::::from_bytes(remainder)?; + let (transfers, remainder) = Vec::::from_bytes(remainder)?; let (cost, remainder) = U512::from_bytes(remainder)?; let (error_message, remainder) = String::from_bytes(remainder)?; let execution_result = ExecutionResultV1::Failure { @@ -253,7 +253,7 @@ impl FromBytes for ExecutionResultV1 { } ExecutionResultTag::Success => { let (execution_effect, remainder) = ExecutionEffect::from_bytes(remainder)?; - let (transfers, remainder) = Vec::::from_bytes(remainder)?; + let (transfers, remainder) = Vec::::from_bytes(remainder)?; let (cost, remainder) = U512::from_bytes(remainder)?; let execution_result = ExecutionResultV1::Success { effect: execution_effect, @@ -465,8 +465,8 @@ pub enum Transform { WriteDeployInfo(DeployInfo), /// Writes the given EraInfo to global state. WriteEraInfo(EraInfo), - /// Writes the given Transfer to global state. - WriteTransfer(Transfer), + /// Writes the given version 1 Transfer to global state. + WriteTransfer(TransferV1), /// Writes the given Bid to global state. WriteBid(Box), /// Writes the given Withdraw to global state. @@ -640,7 +640,7 @@ impl FromBytes for Transform { Ok((Transform::WriteEraInfo(era_info), remainder)) } TransformTag::WriteTransfer => { - let (transfer, remainder) = Transfer::from_bytes(remainder)?; + let (transfer, remainder) = TransferV1::from_bytes(remainder)?; Ok((Transform::WriteTransfer(transfer), remainder)) } TransformTag::AddInt32 => { diff --git a/types/src/execution/execution_result_v2.rs b/types/src/execution/execution_result_v2.rs index e1c9318fb8..46f79565f4 100644 --- a/types/src/execution/execution_result_v2.rs +++ b/types/src/execution/execution_result_v2.rs @@ -23,6 +23,8 @@ use super::Effects; use super::{Transform, TransformKind}; #[cfg(any(feature = "testing", test))] use crate::testing::TestRng; +#[cfg(any(feature = "json-schema", feature = "testing", test))] +use crate::TransferV2Addr; use crate::{ bytesrepr::{self, FromBytes, ToBytes, RESULT_ERR_TAG, RESULT_OK_TAG, U8_SERIALIZED_LENGTH}, Gas, TransferAddr, @@ -45,8 +47,8 @@ static EXECUTION_RESULT: Lazy = Lazy::new(|| { effects.push(Transform::new(key2, TransformKind::Identity)); let transfers = vec![ - TransferAddr::new([89; KEY_HASH_LENGTH]), - TransferAddr::new([130; KEY_HASH_LENGTH]), + TransferAddr::V2(TransferV2Addr::new([89; KEY_HASH_LENGTH])), + TransferAddr::V2(TransferV2Addr::new([130; KEY_HASH_LENGTH])), ]; ExecutionResultV2::Success { @@ -90,7 +92,7 @@ impl Distribution for Standard { let transfer_count = rng.gen_range(0..6); let mut transfers = Vec::new(); for _ in 0..transfer_count { - transfers.push(TransferAddr::new(rng.gen())) + transfers.push(TransferAddr::V2(TransferV2Addr::new(rng.gen()))) } let effects = Effects::random(rng); @@ -128,7 +130,7 @@ impl ExecutionResultV2 { let transfer_count = rng.gen_range(0..6); let mut transfers = vec![]; for _ in 0..transfer_count { - transfers.push(TransferAddr::new(rng.gen())) + transfers.push(TransferAddr::V2(TransferV2Addr::new(rng.gen()))) } let gas = Gas::new(rng.gen::()); diff --git a/types/src/execution/transform_kind.rs b/types/src/execution/transform_kind.rs index f324aa4783..8a38014dd8 100644 --- a/types/src/execution/transform_kind.rs +++ b/types/src/execution/transform_kind.rs @@ -123,9 +123,9 @@ impl TransformKind { let found = "ByteCode".to_string(); Err(StoredValueTypeMismatch::new(expected, found).into()) } - StoredValue::Transfer(_) => { + StoredValue::LegacyTransfer(_) => { let expected = "Contract or Account".to_string(); - let found = "Transfer".to_string(); + let found = "LegacyTransfer".to_string(); Err(StoredValueTypeMismatch::new(expected, found).into()) } StoredValue::DeployInfo(_) => { @@ -188,6 +188,11 @@ impl TransformKind { let found = "TransactionInfo".to_string(); Err(StoredValueTypeMismatch::new(expected, found).into()) } + StoredValue::Transfer(_) => { + let expected = "Contract or Account".to_string(); + let found = "Transfer".to_string(); + Err(StoredValueTypeMismatch::new(expected, found).into()) + } }, TransformKind::Failure(error) => Err(error), } diff --git a/types/src/gas.rs b/types/src/gas.rs index 30c7ba0c8b..508102d1e0 100644 --- a/types/src/gas.rs +++ b/types/src/gas.rs @@ -20,7 +20,9 @@ use crate::{ }; /// The `Gas` struct represents a `U512` amount of gas. -#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] +#[derive( + Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize, +)] #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] pub struct Gas(U512); diff --git a/types/src/gens.rs b/types/src/gens.rs index aeed707c3c..9eb8ec78da 100644 --- a/types/src/gens.rs +++ b/types/src/gens.rs @@ -39,8 +39,11 @@ use crate::{ gens::era_info_arb, Bid, BidAddr, BidKind, DelegationRate, Delegator, UnbondingPurse, ValidatorBid, WithdrawPurse, DELEGATION_RATE_DENOMINATOR, }, - transaction_info::gens::{deploy_hash_arb, transfer_addr_arb, txn_info_arb}, - transfer::{gens::transfer_arb, TransferAddr}, + transaction_info::gens::{deploy_hash_arb, transfer_v1_addr_arb, txn_info_arb}, + transfer::{ + gens::{transfer_arb, transfer_v1_arb}, + TransferV1Addr, + }, AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, ByteCode, CLType, CLValue, EntityKind, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, EraId, Group, Key, NamedArg, Package, Parameter, Phase, ProtocolVersion, SemVer, StoredValue, URef, U128, U256, @@ -103,7 +106,7 @@ pub fn key_arb() -> impl Strategy { account_hash_arb().prop_map(Key::Account), u8_slice_32().prop_map(Key::Hash), uref_arb().prop_map(Key::URef), - transfer_addr_arb().prop_map(Key::Transfer), + transfer_v1_addr_arb().prop_map(Key::LegacyTransfer), deploy_hash_arb().prop_map(Key::DeployInfo), era_id_arb().prop_map(Key::EraInfo), uref_arb().prop_map(|uref| Key::Balance(uref.addr())), @@ -120,7 +123,7 @@ pub fn colliding_key_arb() -> impl Strategy { u2_slice_32().prop_map(|bytes| Key::Account(AccountHash::new(bytes))), u2_slice_32().prop_map(Key::Hash), u2_slice_32().prop_map(|bytes| Key::URef(URef::new(bytes, AccessRights::NONE))), - u2_slice_32().prop_map(|bytes| Key::Transfer(TransferAddr::new(bytes))), + u2_slice_32().prop_map(|bytes| Key::LegacyTransfer(TransferV1Addr::new(bytes))), u2_slice_32().prop_map(Key::Dictionary), ] } @@ -705,7 +708,7 @@ pub fn stored_value_arb() -> impl Strategy { contract_arb().prop_map(StoredValue::Contract), addressable_entity_arb().prop_map(StoredValue::AddressableEntity), package_arb().prop_map(StoredValue::Package), - transfer_arb().prop_map(StoredValue::Transfer), + transfer_v1_arb().prop_map(StoredValue::LegacyTransfer), deploy_info_arb().prop_map(StoredValue::DeployInfo), era_info_arb(1..10).prop_map(StoredValue::EraInfo), unified_bid_arb(0..3).prop_map(StoredValue::BidKind), @@ -717,6 +720,7 @@ pub fn stored_value_arb() -> impl Strategy { message_summary_arb().prop_map(StoredValue::Message), named_key_value_arb().prop_map(StoredValue::NamedKey), txn_info_arb().prop_map(StoredValue::TransactionInfo), + transfer_arb().prop_map(StoredValue::Transfer), ] .prop_map(|stored_value| // The following match statement is here only to make sure @@ -727,7 +731,7 @@ pub fn stored_value_arb() -> impl Strategy { StoredValue::ContractWasm(_) => stored_value, StoredValue::Contract(_) => stored_value, StoredValue::ContractPackage(_) => stored_value, - StoredValue::Transfer(_) => stored_value, + StoredValue::LegacyTransfer(_) => stored_value, StoredValue::DeployInfo(_) => stored_value, StoredValue::EraInfo(_) => stored_value, StoredValue::Bid(_) => stored_value, @@ -741,5 +745,6 @@ pub fn stored_value_arb() -> impl Strategy { StoredValue::Message(_) => stored_value, StoredValue::NamedKey(_) => stored_value, StoredValue::TransactionInfo(_) => stored_value, + StoredValue::Transfer(_) => stored_value, }) } diff --git a/types/src/key.rs b/types/src/key.rs index 18a5d33cc1..eae3daca2a 100644 --- a/types/src/key.rs +++ b/types/src/key.rs @@ -29,6 +29,8 @@ use rand::{ use schemars::JsonSchema; use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer}; +#[cfg(any(feature = "testing", test))] +use crate::TransferV2Addr; use crate::{ account::{AccountHash, ACCOUNT_HASH_LENGTH}, addressable_entity, @@ -46,11 +48,12 @@ use crate::{ system::auction::{BidAddr, BidAddrTag}, uref::{self, URef, URefAddr, UREF_SERIALIZED_LENGTH}, ByteCodeAddr, DeployHash, Digest, EraId, Tagged, TransactionHash, TransactionV1Hash, - TransferAddr, TransferFromStrError, TRANSFER_ADDR_LENGTH, UREF_ADDR_LENGTH, + TransferAddr, TransferFromStrError, TransferV1Addr, TRANSFER_V1_ADDR_LENGTH, UREF_ADDR_LENGTH, }; const HASH_PREFIX: &str = "hash-"; const DEPLOY_INFO_PREFIX: &str = "deploy-"; +const LEGACY_TRANSFER_PREFIX: &str = "transfer-"; const ERA_INFO_PREFIX: &str = "era-"; const BALANCE_PREFIX: &str = "balance-"; const BID_PREFIX: &str = "bid-"; @@ -71,8 +74,8 @@ const TXN_INFO_V1_PREFIX: &str = "v1-"; pub const BLAKE2B_DIGEST_LENGTH: usize = 32; /// The number of bytes in a [`Key::Hash`]. pub const KEY_HASH_LENGTH: usize = 32; -/// The number of bytes in a [`Key::Transfer`]. -pub const KEY_TRANSFER_LENGTH: usize = TRANSFER_ADDR_LENGTH; +/// The number of bytes in a [`Key::LegacyTransfer`]. +pub const KEY_LEGACY_TRANSFER_LENGTH: usize = TRANSFER_V1_ADDR_LENGTH; /// The number of bytes in a [`Key::DeployInfo`]. pub const KEY_DEPLOY_INFO_LENGTH: usize = DeployHash::LENGTH; /// The number of bytes in a [`Key::Dictionary`]. @@ -86,7 +89,8 @@ const KEY_ID_SERIALIZED_LENGTH: usize = 1; // u8 used to determine the ID const KEY_HASH_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_HASH_LENGTH; const KEY_UREF_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + UREF_SERIALIZED_LENGTH; -const KEY_TRANSFER_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_TRANSFER_LENGTH; +const KEY_LEGACY_TRANSFER_SERIALIZED_LENGTH: usize = + KEY_ID_SERIALIZED_LENGTH + KEY_LEGACY_TRANSFER_LENGTH; const KEY_DEPLOY_INFO_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_DEPLOY_INFO_LENGTH; const KEY_ERA_INFO_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + U64_SERIALIZED_LENGTH; const KEY_BALANCE_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + UREF_ADDR_LENGTH; @@ -126,7 +130,7 @@ pub enum KeyTag { Account = 0, Hash = 1, URef = 2, - Transfer = 3, + LegacyTransfer = 3, DeployInfo = 4, EraInfo = 5, Balance = 6, @@ -145,6 +149,7 @@ pub enum KeyTag { Message = 19, NamedKey = 20, TransactionInfo = 21, + Transfer = 22, } impl Display for KeyTag { @@ -153,7 +158,7 @@ impl Display for KeyTag { KeyTag::Account => write!(f, "Account"), KeyTag::Hash => write!(f, "Hash"), KeyTag::URef => write!(f, "URef"), - KeyTag::Transfer => write!(f, "Transfer"), + KeyTag::LegacyTransfer => write!(f, "LegacyTransfer"), KeyTag::DeployInfo => write!(f, "DeployInfo"), KeyTag::EraInfo => write!(f, "EraInfo"), KeyTag::Balance => write!(f, "Balance"), @@ -172,6 +177,7 @@ impl Display for KeyTag { KeyTag::Message => write!(f, "Message"), KeyTag::NamedKey => write!(f, "NamedKey"), KeyTag::TransactionInfo => write!(f, "TransactionInfo"), + KeyTag::Transfer => write!(f, "Transfer"), } } } @@ -189,8 +195,8 @@ pub enum Key { Hash(HashAddr), /// A `Key` which is a [`URef`], under which most types of data can be stored. URef(URef), - /// A `Key` under which a transfer is stored. - Transfer(TransferAddr), + /// A `Key` under which a version 1 (legacy) transfer is stored. + LegacyTransfer(TransferV1Addr), /// A `Key` under which a deploy info is stored. DeployInfo(DeployHash), /// A `Key` under which an era info is stored. @@ -228,6 +234,8 @@ pub enum Key { NamedKey(NamedKeyAddr), /// A `Key` under which info about a transaction is stored. TransactionInfo(TransactionHash), + /// A `Key` under which a versioned transfer is stored. + Transfer(TransferAddr), } #[cfg(feature = "json-schema")] @@ -258,8 +266,8 @@ pub enum FromStrError { Hash(String), /// URef parse error. URef(uref::FromStrError), - /// Transfer parse error. - Transfer(TransferFromStrError), + /// Legacy Transfer parse error. + LegacyTransfer(TransferFromStrError), /// DeployInfo parse error. DeployInfo(String), /// EraInfo parse error. @@ -296,6 +304,8 @@ pub enum FromStrError { NamedKey(String), /// TransactionInfo parse error. TransactionInfo(String), + /// Transfer parse error. + Transfer(TransferFromStrError), /// Unknown prefix. UnknownPrefix, } @@ -306,12 +316,6 @@ impl From for FromStrError { } } -impl From for FromStrError { - fn from(error: TransferFromStrError) -> Self { - FromStrError::Transfer(error) - } -} - impl From for FromStrError { fn from(error: uref::FromStrError) -> Self { FromStrError::URef(error) @@ -330,7 +334,9 @@ impl Display for FromStrError { FromStrError::Account(error) => write!(f, "account-key from string error: {}", error), FromStrError::Hash(error) => write!(f, "hash-key from string error: {}", error), FromStrError::URef(error) => write!(f, "uref-key from string error: {}", error), - FromStrError::Transfer(error) => write!(f, "transfer-key from string error: {}", error), + FromStrError::LegacyTransfer(error) => { + write!(f, "legacy-transfer-key from string error: {}", error) + } FromStrError::DeployInfo(error) => { write!(f, "deploy-info-key from string error: {}", error) } @@ -378,6 +384,9 @@ impl Display for FromStrError { write!(f, "transaction-info-key from string error: {}", error) } FromStrError::UnknownPrefix => write!(f, "unknown prefix for key"), + FromStrError::Transfer(error) => { + write!(f, "transfer-key from string error: {}", error) + } } } } @@ -390,7 +399,7 @@ impl Key { Key::Account(_) => String::from("Key::Account"), Key::Hash(_) => String::from("Key::Hash"), Key::URef(_) => String::from("Key::URef"), - Key::Transfer(_) => String::from("Key::Transfer"), + Key::LegacyTransfer(_) => String::from("Key::LegacyTransfer"), Key::DeployInfo(_) => String::from("Key::DeployInfo"), Key::EraInfo(_) => String::from("Key::EraInfo"), Key::Balance(_) => String::from("Key::Balance"), @@ -409,6 +418,7 @@ impl Key { Key::Message(_) => String::from("Key::Message"), Key::NamedKey(_) => String::from("Key::NamedKey"), Key::TransactionInfo(_) => String::from("Key::TransactionInfo"), + Key::Transfer(_) => String::from("Key::Transfer"), } } @@ -434,7 +444,13 @@ impl Key { Key::Account(account_hash) => account_hash.to_formatted_string(), Key::Hash(addr) => format!("{}{}", HASH_PREFIX, base16::encode_lower(&addr)), Key::URef(uref) => uref.to_formatted_string(), - Key::Transfer(transfer_addr) => transfer_addr.to_formatted_string(), + Key::LegacyTransfer(transfer_v1_addr) => { + format!( + "{}{}", + LEGACY_TRANSFER_PREFIX, + base16::encode_lower(&transfer_v1_addr.value()) + ) + } Key::DeployInfo(deploy_hash) => { format!( "{}{}", @@ -526,6 +542,7 @@ impl Key { ) } }, + Key::Transfer(transfer_addr) => transfer_addr.to_formatted_string(), } } @@ -556,7 +573,15 @@ impl Key { match TransferAddr::from_formatted_str(input) { Ok(transfer_addr) => return Ok(Key::Transfer(transfer_addr)), Err(TransferFromStrError::InvalidPrefix) => {} - Err(error) => return Err(error.into()), + Err(error) => return Err(FromStrError::Transfer(error)), + } + + if let Some(hex) = input.strip_prefix(LEGACY_TRANSFER_PREFIX) { + let v1_addr = checksummed_hex::decode(hex) + .map_err(|error| FromStrError::LegacyTransfer(TransferFromStrError::from(error)))?; + let addr_array = <[u8; TRANSFER_V1_ADDR_LENGTH]>::try_from(v1_addr.as_ref()) + .map_err(|error| FromStrError::LegacyTransfer(TransferFromStrError::from(error)))?; + return Ok(Key::LegacyTransfer(TransferV1Addr::new(addr_array))); } match URef::from_formatted_str(input) { @@ -1020,7 +1045,9 @@ impl Display for Key { Key::Account(account_hash) => write!(f, "Key::Account({})", account_hash), Key::Hash(addr) => write!(f, "Key::Hash({})", base16::encode_lower(&addr)), Key::URef(uref) => write!(f, "Key::{}", uref), /* Display impl for URef will append */ - Key::Transfer(transfer_addr) => write!(f, "Key::Transfer({})", transfer_addr), + Key::LegacyTransfer(transfer_v1_addr) => { + write!(f, "Key::LegacyTransfer({})", transfer_v1_addr) + } Key::DeployInfo(addr) => write!( f, "Key::DeployInfo({})", @@ -1087,6 +1114,12 @@ impl Display for Key { "Key::TransactionInfo(txn-v1-{})", base16::encode_lower(txn_v1_hash.as_ref()) ), + Key::Transfer(TransferAddr::V1(transfer_v1_addr)) => { + write!(f, "Key::Transfer(transfer-v1-{})", transfer_v1_addr) + } + Key::Transfer(TransferAddr::V2(transfer_v2_addr)) => { + write!(f, "Key::Transfer(transfer-v2-{})", transfer_v2_addr) + } } } } @@ -1103,7 +1136,7 @@ impl Tagged for Key { Key::Account(_) => KeyTag::Account, Key::Hash(_) => KeyTag::Hash, Key::URef(_) => KeyTag::URef, - Key::Transfer(_) => KeyTag::Transfer, + Key::LegacyTransfer(_) => KeyTag::LegacyTransfer, Key::DeployInfo(_) => KeyTag::DeployInfo, Key::EraInfo(_) => KeyTag::EraInfo, Key::Balance(_) => KeyTag::Balance, @@ -1122,6 +1155,7 @@ impl Tagged for Key { Key::Message(_) => KeyTag::Message, Key::NamedKey(_) => KeyTag::NamedKey, Key::TransactionInfo(_) => KeyTag::TransactionInfo, + Key::Transfer(_) => KeyTag::Transfer, } } } @@ -1207,7 +1241,7 @@ impl ToBytes for Key { } Key::Hash(_) => KEY_HASH_SERIALIZED_LENGTH, Key::URef(_) => KEY_UREF_SERIALIZED_LENGTH, - Key::Transfer(_) => KEY_TRANSFER_SERIALIZED_LENGTH, + Key::LegacyTransfer(_) => KEY_LEGACY_TRANSFER_SERIALIZED_LENGTH, Key::DeployInfo(_) => KEY_DEPLOY_INFO_SERIALIZED_LENGTH, Key::EraInfo(_) => KEY_ERA_INFO_SERIALIZED_LENGTH, Key::Balance(_) => KEY_BALANCE_SERIALIZED_LENGTH, @@ -1241,6 +1275,7 @@ impl ToBytes for Key { Key::TransactionInfo(txn_hash) => { KEY_ID_SERIALIZED_LENGTH + txn_hash.serialized_length() } + Key::Transfer(transfer) => KEY_ID_SERIALIZED_LENGTH + transfer.serialized_length(), } } @@ -1250,7 +1285,7 @@ impl ToBytes for Key { Key::Account(account_hash) => account_hash.write_bytes(writer), Key::Hash(hash) => hash.write_bytes(writer), Key::URef(uref) => uref.write_bytes(writer), - Key::Transfer(addr) => addr.write_bytes(writer), + Key::LegacyTransfer(addr) => addr.write_bytes(writer), Key::DeployInfo(deploy_hash) => deploy_hash.write_bytes(writer), Key::EraInfo(era_id) => era_id.write_bytes(writer), Key::Balance(uref_addr) => uref_addr.write_bytes(writer), @@ -1276,6 +1311,7 @@ impl ToBytes for Key { Key::Message(message_addr) => message_addr.write_bytes(writer), Key::NamedKey(named_key_addr) => named_key_addr.write_bytes(writer), Key::TransactionInfo(txn_hash) => txn_hash.write_bytes(writer), + Key::Transfer(addr) => addr.write_bytes(writer), } } } @@ -1296,9 +1332,9 @@ impl FromBytes for Key { let (uref, rem) = URef::from_bytes(remainder)?; Ok((Key::URef(uref), rem)) } - tag if tag == KeyTag::Transfer as u8 => { - let (transfer_addr, rem) = TransferAddr::from_bytes(remainder)?; - Ok((Key::Transfer(transfer_addr), rem)) + tag if tag == KeyTag::LegacyTransfer as u8 => { + let (transfer_v1_addr, rem) = TransferV1Addr::from_bytes(remainder)?; + Ok((Key::LegacyTransfer(transfer_v1_addr), rem)) } tag if tag == KeyTag::DeployInfo as u8 => { let (deploy_hash, rem) = DeployHash::from_bytes(remainder)?; @@ -1372,6 +1408,10 @@ impl FromBytes for Key { let (txn_hash, rem) = TransactionHash::from_bytes(remainder)?; Ok((Key::TransactionInfo(txn_hash), rem)) } + tag if tag == KeyTag::Transfer as u8 => { + let (transfer_addr, rem) = TransferAddr::from_bytes(remainder)?; + Ok((Key::Transfer(transfer_addr), rem)) + } _ => Err(Error::Formatting), } } @@ -1385,7 +1425,7 @@ fn please_add_to_distribution_impl(key: Key) { Key::Account(_) => unimplemented!(), Key::Hash(_) => unimplemented!(), Key::URef(_) => unimplemented!(), - Key::Transfer(_) => unimplemented!(), + Key::LegacyTransfer(_) => unimplemented!(), Key::DeployInfo(_) => unimplemented!(), Key::EraInfo(_) => unimplemented!(), Key::Balance(_) => unimplemented!(), @@ -1404,17 +1444,18 @@ fn please_add_to_distribution_impl(key: Key) { Key::Message(_) => unimplemented!(), Key::NamedKey(_) => unimplemented!(), Key::TransactionInfo(_) => unimplemented!(), + Key::Transfer(_) => unimplemented!(), } } #[cfg(any(feature = "testing", test))] impl Distribution for Standard { fn sample(&self, rng: &mut R) -> Key { - match rng.gen_range(0..=21) { + match rng.gen_range(0..=22) { 0 => Key::Account(rng.gen()), 1 => Key::Hash(rng.gen()), 2 => Key::URef(rng.gen()), - 3 => Key::Transfer(rng.gen()), + 3 => Key::LegacyTransfer(TransferV1Addr::new(rng.gen())), 4 => Key::DeployInfo(DeployHash::from_raw(rng.gen())), 5 => Key::EraInfo(EraId::new(rng.gen())), 6 => Key::Balance(rng.gen()), @@ -1437,6 +1478,11 @@ impl Distribution for Standard { } else { TransactionHash::V1(TransactionV1Hash::from_raw(rng.gen())) }), + 22 => Key::Transfer(if rng.gen() { + TransferAddr::V1(TransferV1Addr::new(rng.gen())) + } else { + TransferAddr::V2(TransferV2Addr::new(rng.gen())) + }), _ => unreachable!(), } } @@ -1450,7 +1496,7 @@ mod serde_helpers { Account(&'a AccountHash), Hash(&'a HashAddr), URef(&'a URef), - Transfer(&'a TransferAddr), + LegacyTransfer(&'a TransferV1Addr), #[serde(with = "crate::serde_helpers::deploy_hash_as_array")] DeployInfo(&'a DeployHash), EraInfo(&'a EraId), @@ -1470,6 +1516,7 @@ mod serde_helpers { Message(&'a MessageAddr), NamedKey(&'a NamedKeyAddr), TransactionInfo(&'a TransactionHash), + Transfer(&'a TransferAddr), } #[derive(Deserialize)] @@ -1477,7 +1524,7 @@ mod serde_helpers { Account(AccountHash), Hash(HashAddr), URef(URef), - Transfer(TransferAddr), + LegacyTransfer(TransferV1Addr), #[serde(with = "crate::serde_helpers::deploy_hash_as_array")] DeployInfo(DeployHash), EraInfo(EraId), @@ -1497,6 +1544,7 @@ mod serde_helpers { Message(MessageAddr), NamedKey(NamedKeyAddr), TransactionInfo(TransactionHash), + Transfer(TransferAddr), } impl<'a> From<&'a Key> for BinarySerHelper<'a> { @@ -1505,7 +1553,9 @@ mod serde_helpers { Key::Account(account_hash) => BinarySerHelper::Account(account_hash), Key::Hash(hash_addr) => BinarySerHelper::Hash(hash_addr), Key::URef(uref) => BinarySerHelper::URef(uref), - Key::Transfer(transfer_addr) => BinarySerHelper::Transfer(transfer_addr), + Key::LegacyTransfer(transfer_v1_addr) => { + BinarySerHelper::LegacyTransfer(transfer_v1_addr) + } Key::DeployInfo(deploy_hash) => BinarySerHelper::DeployInfo(deploy_hash), Key::EraInfo(era_id) => BinarySerHelper::EraInfo(era_id), Key::Balance(uref_addr) => BinarySerHelper::Balance(uref_addr), @@ -1526,6 +1576,7 @@ mod serde_helpers { Key::ByteCode(byte_code_addr) => BinarySerHelper::ByteCode(byte_code_addr), Key::NamedKey(named_key_addr) => BinarySerHelper::NamedKey(named_key_addr), Key::TransactionInfo(txn_hash) => BinarySerHelper::TransactionInfo(txn_hash), + Key::Transfer(transfer_addr) => BinarySerHelper::Transfer(transfer_addr), } } } @@ -1536,7 +1587,9 @@ mod serde_helpers { BinaryDeserHelper::Account(account_hash) => Key::Account(account_hash), BinaryDeserHelper::Hash(hash_addr) => Key::Hash(hash_addr), BinaryDeserHelper::URef(uref) => Key::URef(uref), - BinaryDeserHelper::Transfer(transfer_addr) => Key::Transfer(transfer_addr), + BinaryDeserHelper::LegacyTransfer(transfer_v1_addr) => { + Key::LegacyTransfer(transfer_v1_addr) + } BinaryDeserHelper::DeployInfo(deploy_hash) => Key::DeployInfo(deploy_hash), BinaryDeserHelper::EraInfo(era_id) => Key::EraInfo(era_id), BinaryDeserHelper::Balance(uref_addr) => Key::Balance(uref_addr), @@ -1557,6 +1610,7 @@ mod serde_helpers { BinaryDeserHelper::ByteCode(byte_code_addr) => Key::ByteCode(byte_code_addr), BinaryDeserHelper::NamedKey(named_key_addr) => Key::NamedKey(named_key_addr), BinaryDeserHelper::TransactionInfo(txn_hash) => Key::TransactionInfo(txn_hash), + BinaryDeserHelper::Transfer(transfer_addr) => Key::Transfer(transfer_addr), } } } @@ -1592,11 +1646,11 @@ mod tests { use crate::{ account::ACCOUNT_HASH_FORMATTED_STRING_PREFIX, bytesrepr::{Error, FromBytes}, - transfer::TRANSFER_ADDR_FORMATTED_STRING_PREFIX, uref::UREF_FORMATTED_STRING_PREFIX, AccessRights, URef, }; + const TRANSFER_ADDR_FORMATTED_STRING_PREFIX: &str = "transfer-"; const ENTITY_PREFIX: &str = "entity-addr-"; const ACCOUNT_ENTITY_PREFIX: &str = "account-"; @@ -1606,7 +1660,7 @@ mod tests { const ACCOUNT_KEY: Key = Key::Account(AccountHash::new([42; 32])); const HASH_KEY: Key = Key::Hash([42; 32]); const UREF_KEY: Key = Key::URef(URef::new([42; 32], AccessRights::READ)); - const TRANSFER_KEY: Key = Key::Transfer(TransferAddr::new([42; 32])); + const LEGACY_TRANSFER_KEY: Key = Key::LegacyTransfer(TransferV1Addr::new([42; 32])); const DEPLOY_INFO_KEY: Key = Key::DeployInfo(DeployHash::from_raw([42; 32])); const ERA_INFO_KEY: Key = Key::EraInfo(EraId::new(42)); const BALANCE_KEY: Key = Key::Balance([42; 32]); @@ -1647,11 +1701,13 @@ mod tests { Key::TransactionInfo(TransactionHash::Deploy(DeployHash::from_raw([42; 32]))); const TRANSACTION_INFO_V1_KEY: Key = Key::TransactionInfo(TransactionHash::V1(TransactionV1Hash::from_raw([42; 32]))); + const TRANSFER_V1_KEY: Key = Key::Transfer(TransferAddr::V1(TransferV1Addr::new([42; 32]))); + const TRANSFER_V2_KEY: Key = Key::Transfer(TransferAddr::V2(TransferV2Addr::new([42; 32]))); const KEYS: &[Key] = &[ ACCOUNT_KEY, HASH_KEY, UREF_KEY, - TRANSFER_KEY, + LEGACY_TRANSFER_KEY, DEPLOY_INFO_KEY, ERA_INFO_KEY, BALANCE_KEY, @@ -1676,6 +1732,8 @@ mod tests { MESSAGE_KEY, NAMED_KEY, TRANSACTION_INFO_V1_KEY, + TRANSFER_V1_KEY, + TRANSFER_V2_KEY, ]; const HEX_STRING: &str = "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"; const TOPIC_NAME_HEX_STRING: &str = @@ -1748,8 +1806,8 @@ mod tests { format!("Key::URef({}, READ)", HEX_STRING) ); assert_eq!( - format!("{}", TRANSFER_KEY), - format!("Key::Transfer({})", HEX_STRING) + format!("{}", LEGACY_TRANSFER_KEY), + format!("Key::LegacyTransfer({})", HEX_STRING) ); assert_eq!( format!("{}", DEPLOY_INFO_KEY), @@ -1859,6 +1917,14 @@ mod tests { format!("{}", TRANSACTION_INFO_V1_KEY), format!("Key::TransactionInfo(txn-v1-{})", HEX_STRING) ); + assert_eq!( + format!("{}", TRANSFER_V1_KEY), + format!("Key::Transfer(transfer-v1-{})", HEX_STRING) + ); + assert_eq!( + format!("{}", TRANSFER_V2_KEY), + format!("Key::Transfer(transfer-v2-{})", HEX_STRING) + ); } #[test] @@ -2048,7 +2114,7 @@ mod tests { Key::from_formatted_str(TRANSFER_ADDR_FORMATTED_STRING_PREFIX) .unwrap_err() .to_string() - .starts_with("transfer-key from string error: ") + .starts_with("legacy-transfer-key from string error: ") ); assert!(Key::from_formatted_str(DEPLOY_INFO_PREFIX) .unwrap_err() @@ -2185,7 +2251,7 @@ mod tests { round_trip(&Key::Account(AccountHash::new(zeros))); round_trip(&Key::Hash(zeros)); round_trip(&Key::URef(URef::new(zeros, AccessRights::READ))); - round_trip(&Key::Transfer(TransferAddr::new(zeros))); + round_trip(&Key::LegacyTransfer(TransferV1Addr::new(zeros))); round_trip(&Key::DeployInfo(DeployHash::from_raw(zeros))); round_trip(&Key::EraInfo(EraId::from(0))); round_trip(&Key::Balance(URef::new(zeros, AccessRights::READ).addr())); @@ -2219,5 +2285,7 @@ mod tests { round_trip(&Key::TransactionInfo(TransactionHash::V1( TransactionV1Hash::from_raw(zeros), ))); + round_trip(&Key::Transfer(TransferAddr::V1(TransferV1Addr::new(zeros)))); + round_trip(&Key::Transfer(TransferAddr::V2(TransferV2Addr::new(zeros)))); } } diff --git a/types/src/lib.rs b/types/src/lib.rs index f0b85a088e..b1fadebb58 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -185,7 +185,8 @@ pub use transaction::{ }; pub use transaction_info::TransactionInfo; pub use transfer::{ - FromStrError as TransferFromStrError, Transfer, TransferAddr, TRANSFER_ADDR_LENGTH, + Transfer, TransferAddr, TransferFromStrError, TransferV1, TransferV1Addr, TransferV2, + TransferV2Addr, TRANSFER_V1_ADDR_LENGTH, TRANSFER_V2_ADDR_LENGTH, }; pub use transfer_result::{TransferResult, TransferredTo}; pub use uref::{ diff --git a/types/src/stored_value.rs b/types/src/stored_value.rs index 944d014fda..fa026e3209 100644 --- a/types/src/stored_value.rs +++ b/types/src/stored_value.rs @@ -23,7 +23,7 @@ use crate::{ contracts::{Contract, ContractPackage}, package::Package, system::auction::{Bid, BidKind, EraInfo, UnbondingPurse, WithdrawPurse}, - AddressableEntity, ByteCode, CLValue, DeployInfo, TransactionInfo, Transfer, + AddressableEntity, ByteCode, CLValue, DeployInfo, TransactionInfo, Transfer, TransferV1, }; pub use type_mismatch::TypeMismatch; @@ -35,7 +35,7 @@ enum Tag { ContractWasm = 2, Contract = 3, ContractPackage = 4, - Transfer = 5, + LegacyTransfer = 5, DeployInfo = 6, EraInfo = 7, Bid = 8, @@ -49,6 +49,7 @@ enum Tag { Message = 16, NamedKey = 17, TransactionInfo = 18, + Transfer = 19, } /// A value stored in Global State. @@ -71,8 +72,8 @@ pub enum StoredValue { Contract(Contract), /// A contract package. ContractPackage(ContractPackage), - /// A `Transfer`. - Transfer(Transfer), + /// A version 1 (legacy) transfer. + LegacyTransfer(TransferV1), /// Info about a deploy. DeployInfo(DeployInfo), /// Info about an era. @@ -99,6 +100,8 @@ pub enum StoredValue { NamedKey(NamedKeyValue), /// Info about a transaction. TransactionInfo(TransactionInfo), + /// A versioned transfer. + Transfer(Transfer), } impl StoredValue { @@ -142,10 +145,10 @@ impl StoredValue { } } - /// Returns a reference to the wrapped `Transfer` if this is a `Transfer` variant. - pub fn as_transfer(&self) -> Option<&Transfer> { + /// Returns a reference to the wrapped `TransferV1` if this is a `LegacyTransfer` variant. + pub fn as_legacy_transfer(&self) -> Option<&TransferV1> { match self { - StoredValue::Transfer(transfer) => Some(transfer), + StoredValue::LegacyTransfer(transfer_v1) => Some(transfer_v1), _ => None, } } @@ -234,6 +237,14 @@ impl StoredValue { } } + /// Returns a reference to the wrapped `Transfer` if this is a `Transfer` variant. + pub fn as_transfer(&self) -> Option<&Transfer> { + match self { + StoredValue::Transfer(transfer) => Some(transfer), + _ => None, + } + } + /// Returns the `CLValue` if this is a `CLValue` variant. pub fn into_cl_value(self) -> Option { match self { @@ -282,10 +293,10 @@ impl StoredValue { } } - /// Returns the `Transfer` if this is a `Transfer` variant. - pub fn into_transfer(self) -> Option { + /// Returns the `TransferV1` if this is a `LegacyTransfer` variant. + pub fn into_legacy_transfer(self) -> Option { match self { - StoredValue::Transfer(transfer) => Some(transfer), + StoredValue::LegacyTransfer(transfer_v1) => Some(transfer_v1), _ => None, } } @@ -354,6 +365,14 @@ impl StoredValue { } } + /// Returns the `Transfer` if this is a `Transfer` variant. + pub fn into_transfer(self) -> Option { + match self { + StoredValue::Transfer(transfer) => Some(transfer), + _ => None, + } + } + /// Returns the type name of the [`StoredValue`] enum variant. /// /// For [`CLValue`] variants it will return the name of the [`CLType`](crate::cl_type::CLType) @@ -364,7 +383,7 @@ impl StoredValue { StoredValue::ContractWasm(_) => "ContractWasm".to_string(), StoredValue::Contract(_) => "Contract".to_string(), StoredValue::ContractPackage(_) => "ContractPackage".to_string(), - StoredValue::Transfer(_) => "Transfer".to_string(), + StoredValue::LegacyTransfer(_) => "LegacyTransfer".to_string(), StoredValue::DeployInfo(_) => "DeployInfo".to_string(), StoredValue::EraInfo(_) => "EraInfo".to_string(), StoredValue::Bid(_) => "Bid".to_string(), @@ -378,6 +397,7 @@ impl StoredValue { StoredValue::Message(_) => "Message".to_string(), StoredValue::NamedKey(_) => "NamedKey".to_string(), StoredValue::TransactionInfo(_) => "TransactionInfo".to_string(), + StoredValue::Transfer(_) => "Transfer".to_string(), } } @@ -388,7 +408,7 @@ impl StoredValue { StoredValue::ContractWasm(_) => Tag::ContractWasm, StoredValue::ContractPackage(_) => Tag::ContractPackage, StoredValue::Contract(_) => Tag::Contract, - StoredValue::Transfer(_) => Tag::Transfer, + StoredValue::LegacyTransfer(_) => Tag::LegacyTransfer, StoredValue::DeployInfo(_) => Tag::DeployInfo, StoredValue::EraInfo(_) => Tag::EraInfo, StoredValue::Bid(_) => Tag::Bid, @@ -402,6 +422,7 @@ impl StoredValue { StoredValue::Message(_) => Tag::Message, StoredValue::NamedKey(_) => Tag::NamedKey, StoredValue::TransactionInfo(_) => Tag::TransactionInfo, + StoredValue::Transfer(_) => Tag::Transfer, } } } @@ -576,13 +597,16 @@ impl TryFrom for AddressableEntity { } } -impl TryFrom for Transfer { +impl TryFrom for TransferV1 { type Error = TypeMismatch; fn try_from(value: StoredValue) -> Result { match value { - StoredValue::Transfer(transfer) => Ok(transfer), - _ => Err(TypeMismatch::new("Transfer".to_string(), value.type_name())), + StoredValue::LegacyTransfer(transfer_v1) => Ok(transfer_v1), + _ => Err(TypeMismatch::new( + "LegacyTransfer".to_string(), + value.type_name(), + )), } } } @@ -662,6 +686,17 @@ impl TryFrom for TransactionInfo { } } +impl TryFrom for Transfer { + type Error = TypeMismatch; + + fn try_from(value: StoredValue) -> Result { + match value { + StoredValue::Transfer(transfer) => Ok(transfer), + _ => Err(TypeMismatch::new("Transfer".to_string(), value.type_name())), + } + } +} + impl ToBytes for StoredValue { fn to_bytes(&self) -> Result, Error> { let mut buffer = bytesrepr::allocate_buffer(self)?; @@ -679,7 +714,7 @@ impl ToBytes for StoredValue { StoredValue::ContractPackage(contract_package) => { contract_package.serialized_length() } - StoredValue::Transfer(transfer) => transfer.serialized_length(), + StoredValue::LegacyTransfer(transfer_v1) => transfer_v1.serialized_length(), StoredValue::DeployInfo(deploy_info) => deploy_info.serialized_length(), StoredValue::EraInfo(era_info) => era_info.serialized_length(), StoredValue::Bid(bid) => bid.serialized_length(), @@ -695,6 +730,7 @@ impl ToBytes for StoredValue { StoredValue::Message(message_digest) => message_digest.serialized_length(), StoredValue::NamedKey(named_key_value) => named_key_value.serialized_length(), StoredValue::TransactionInfo(txn_info) => txn_info.serialized_length(), + StoredValue::Transfer(transfer) => transfer.serialized_length(), } } @@ -706,7 +742,7 @@ impl ToBytes for StoredValue { StoredValue::ContractWasm(contract_wasm) => contract_wasm.write_bytes(writer), StoredValue::Contract(contract_header) => contract_header.write_bytes(writer), StoredValue::ContractPackage(contract_package) => contract_package.write_bytes(writer), - StoredValue::Transfer(transfer) => transfer.write_bytes(writer), + StoredValue::LegacyTransfer(transfer_v1) => transfer_v1.write_bytes(writer), StoredValue::DeployInfo(deploy_info) => deploy_info.write_bytes(writer), StoredValue::EraInfo(era_info) => era_info.write_bytes(writer), StoredValue::Bid(bid) => bid.write_bytes(writer), @@ -722,6 +758,7 @@ impl ToBytes for StoredValue { StoredValue::Message(message_digest) => message_digest.write_bytes(writer), StoredValue::NamedKey(named_key_value) => named_key_value.write_bytes(writer), StoredValue::TransactionInfo(txn_info) => txn_info.write_bytes(writer), + StoredValue::Transfer(transfer) => transfer.write_bytes(writer), } } } @@ -746,8 +783,11 @@ impl FromBytes for StoredValue { } tag if tag == Tag::Contract as u8 => Contract::from_bytes(remainder) .map(|(contract, remainder)| (StoredValue::Contract(contract), remainder)), - tag if tag == Tag::Transfer as u8 => Transfer::from_bytes(remainder) - .map(|(transfer, remainder)| (StoredValue::Transfer(transfer), remainder)), + tag if tag == Tag::LegacyTransfer as u8 => { + TransferV1::from_bytes(remainder).map(|(transfer_v1, remainder)| { + (StoredValue::LegacyTransfer(transfer_v1), remainder) + }) + } tag if tag == Tag::DeployInfo as u8 => DeployInfo::from_bytes(remainder) .map(|(deploy_info, remainder)| (StoredValue::DeployInfo(deploy_info), remainder)), tag if tag == Tag::EraInfo as u8 => EraInfo::from_bytes(remainder) @@ -785,6 +825,8 @@ impl FromBytes for StoredValue { } tag if tag == Tag::TransactionInfo as u8 => TransactionInfo::from_bytes(remainder) .map(|(txn_info, remainder)| (StoredValue::TransactionInfo(txn_info), remainder)), + tag if tag == Tag::Transfer as u8 => Transfer::from_bytes(remainder) + .map(|(transfer, remainder)| (StoredValue::Transfer(transfer), remainder)), _ => Err(Error::Formatting), } } @@ -795,85 +837,50 @@ mod serde_helpers { #[derive(Serialize)] pub(super) enum BinarySerHelper<'a> { - /// A CLValue. CLValue(&'a CLValue), - /// An account. Account(&'a Account), ContractWasm(&'a ContractWasm), - /// A contract. Contract(&'a Contract), - /// A `Package`. ContractPackage(&'a ContractPackage), - /// A `Transfer`. - Transfer(&'a Transfer), - /// Info about a deploy. + LegacyTransfer(&'a TransferV1), DeployInfo(&'a DeployInfo), - /// Info about an era. EraInfo(&'a EraInfo), - /// Variant that stores [`Bid`]. Bid(&'a Bid), - /// Variant that stores withdraw information. Withdraw(&'a Vec), - /// Unbonding information. Unbonding(&'a Vec), - /// An `AddressableEntity`. AddressableEntity(&'a AddressableEntity), - /// Variant that stores [`BidKind`]. BidKind(&'a BidKind), - /// Package. Package(&'a Package), - /// A record of byte code. ByteCode(&'a ByteCode), - /// Variant that stores [`MessageTopicSummary`]. MessageTopic(&'a MessageTopicSummary), - /// Variant that stores a [`MessageChecksum`]. Message(&'a MessageChecksum), - /// A record for NamedKey. NamedKey(&'a NamedKeyValue), - /// Info about a transaction. TransactionInfo(&'a TransactionInfo), + Transfer(&'a Transfer), } #[derive(Deserialize)] pub(super) enum BinaryDeserHelper { - /// A CLValue. CLValue(CLValue), - /// An account. Account(Account), - /// A contract wasm. ContractWasm(ContractWasm), - /// A contract. Contract(Contract), - /// A `Package`. ContractPackage(ContractPackage), - /// A `Transfer`. - Transfer(Transfer), - /// Info about a deploy. + LegacyTransfer(TransferV1), DeployInfo(DeployInfo), - /// Info about an era. EraInfo(EraInfo), - /// Variant that stores [`Bid`]. Bid(Box), - /// Variant that stores withdraw information. Withdraw(Vec), - /// Unbonding information. Unbonding(Vec), - /// An `AddressableEntity`. AddressableEntity(AddressableEntity), - /// Variant that stores [`BidKind`]. BidKind(BidKind), - /// A record of a Package. Package(Package), - /// A record of byte code. ByteCode(ByteCode), - /// Variant that stores [`MessageTopicSummary`]. MessageTopic(MessageTopicSummary), - /// Variant that stores [`MessageChecksum`]. Message(MessageChecksum), - /// A record for NamedKey. NamedKey(NamedKeyValue), - /// Info about a transaction. TransactionInfo(TransactionInfo), + Transfer(Transfer), } impl<'a> From<&'a StoredValue> for BinarySerHelper<'a> { @@ -884,7 +891,7 @@ mod serde_helpers { StoredValue::ContractWasm(payload) => BinarySerHelper::ContractWasm(payload), StoredValue::Contract(payload) => BinarySerHelper::Contract(payload), StoredValue::ContractPackage(payload) => BinarySerHelper::ContractPackage(payload), - StoredValue::Transfer(payload) => BinarySerHelper::Transfer(payload), + StoredValue::LegacyTransfer(payload) => BinarySerHelper::LegacyTransfer(payload), StoredValue::DeployInfo(payload) => BinarySerHelper::DeployInfo(payload), StoredValue::EraInfo(payload) => BinarySerHelper::EraInfo(payload), StoredValue::Bid(payload) => BinarySerHelper::Bid(payload), @@ -902,6 +909,7 @@ mod serde_helpers { StoredValue::Message(message_digest) => BinarySerHelper::Message(message_digest), StoredValue::NamedKey(payload) => BinarySerHelper::NamedKey(payload), StoredValue::TransactionInfo(payload) => BinarySerHelper::TransactionInfo(payload), + StoredValue::Transfer(payload) => BinarySerHelper::Transfer(payload), } } } @@ -916,7 +924,7 @@ mod serde_helpers { BinaryDeserHelper::ContractPackage(payload) => { StoredValue::ContractPackage(payload) } - BinaryDeserHelper::Transfer(payload) => StoredValue::Transfer(payload), + BinaryDeserHelper::LegacyTransfer(payload) => StoredValue::LegacyTransfer(payload), BinaryDeserHelper::DeployInfo(payload) => StoredValue::DeployInfo(payload), BinaryDeserHelper::EraInfo(payload) => StoredValue::EraInfo(payload), BinaryDeserHelper::Bid(bid) => StoredValue::Bid(bid), @@ -936,6 +944,7 @@ mod serde_helpers { BinaryDeserHelper::TransactionInfo(payload) => { StoredValue::TransactionInfo(payload) } + BinaryDeserHelper::Transfer(payload) => StoredValue::Transfer(payload), } } } diff --git a/types/src/transaction/transaction_hash.rs b/types/src/transaction/transaction_hash.rs index e8152e7d63..faadb1dc2e 100644 --- a/types/src/transaction/transaction_hash.rs +++ b/types/src/transaction/transaction_hash.rs @@ -7,8 +7,6 @@ use datasize::DataSize; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -#[cfg(doc)] -use super::TransactionV1; use super::{DeployHash, TransactionV1Hash}; use crate::bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}; diff --git a/types/src/transaction_info.rs b/types/src/transaction_info.rs index 4f536077b3..732fb24c0d 100644 --- a/types/src/transaction_info.rs +++ b/types/src/transaction_info.rs @@ -109,7 +109,7 @@ pub(crate) mod gens { crypto::gens::public_key_arb_no_system, gens::{u512_arb, uref_arb}, DeployHash, Gas, InitiatorAddr, TransactionHash, TransactionInfo, TransactionV1Hash, - TransferAddr, + TransferAddr, TransferV1Addr, TransferV2Addr, }; pub fn deploy_hash_arb() -> impl Strategy { @@ -127,11 +127,21 @@ pub(crate) mod gens { ] } - pub fn transfer_addr_arb() -> impl Strategy { - array::uniform32(::arbitrary()).prop_map(TransferAddr::new) + pub fn transfer_v1_addr_arb() -> impl Strategy { + array::uniform32(::arbitrary()).prop_map(TransferV1Addr::new) } - pub fn transfers_arb(size: impl Into) -> impl Strategy> { + fn transfer_v2_addr_arb() -> impl Strategy { + array::uniform32(::arbitrary()).prop_map(TransferV2Addr::new) + } + + fn transfer_addr_arb() -> impl Strategy { + transfer_v2_addr_arb().prop_map(TransferAddr::from) + } + + pub fn transfer_addrs_arb( + size: impl Into, + ) -> impl Strategy> { collection::vec(transfer_addr_arb(), size) } @@ -151,7 +161,7 @@ pub(crate) mod gens { let transfers_length_range = 0..5; ( txn_hash_arb(), - transfers_arb(transfers_length_range), + transfer_addrs_arb(transfers_length_range), initiator_addr_arb(), uref_arb(), u512_arb(), diff --git a/types/src/transfer.rs b/types/src/transfer.rs index 10d0a3fb3f..4f8bc628e1 100644 --- a/types/src/transfer.rs +++ b/types/src/transfer.rs @@ -1,319 +1,179 @@ -use alloc::{format, string::String, vec::Vec}; -use core::{ - array::TryFromSliceError, - convert::TryFrom, - fmt::{self, Debug, Display, Formatter}, -}; +mod error; +mod transfer_addr; +mod transfer_v1; +mod transfer_v2; + +use alloc::vec::Vec; #[cfg(feature = "datasize")] use datasize::DataSize; -#[cfg(any(feature = "testing", test))] -use rand::{ - distributions::{Distribution, Standard}, - Rng, -}; #[cfg(feature = "json-schema")] -use schemars::{gen::SchemaGenerator, schema::Schema, JsonSchema}; -use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer}; +use once_cell::sync::Lazy; +#[cfg(feature = "json-schema")] +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use crate::bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}; +#[cfg(feature = "json-schema")] use crate::{ - account::AccountHash, - bytesrepr::{self, FromBytes, ToBytes}, - checksummed_hex, CLType, CLTyped, Gas, InitiatorAddr, TransactionHash, URef, U512, + account::AccountHash, Gas, InitiatorAddr, TransactionHash, TransactionV1Hash, URef, U512, }; +pub use error::TransferFromStrError; +pub use transfer_addr::TransferAddr; +pub use transfer_v1::{TransferV1, TransferV1Addr, TRANSFER_V1_ADDR_LENGTH}; +pub use transfer_v2::{TransferV2, TransferV2Addr, TRANSFER_V2_ADDR_LENGTH}; -/// The length of a transfer address. -pub const TRANSFER_ADDR_LENGTH: usize = 32; -pub(super) const TRANSFER_ADDR_FORMATTED_STRING_PREFIX: &str = "transfer-"; +const V1_TAG: u8 = 0; +const V2_TAG: u8 = 1; -/// Represents a transfer from one purse to another -#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)] +#[cfg(feature = "json-schema")] +pub(super) static TRANSFER: Lazy = Lazy::new(|| { + let transaction_hash = TransactionHash::V1(TransactionV1Hash::from_raw([1; 32])); + let from = InitiatorAddr::AccountHash(AccountHash::new([2; 32])); + let to = Some(AccountHash::new([3; 32])); + let source = URef::from_formatted_str( + "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007", + ) + .unwrap(); + let target = URef::from_formatted_str( + "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000", + ) + .unwrap(); + let amount = U512::from(1_000_000_000_000_u64); + let gas = Gas::new(2_500_000_000_u64); + let id = Some(999); + Transfer::V2(TransferV2::new( + transaction_hash, + from, + to, + source, + target, + amount, + gas, + id, + )) +}); + +/// A versioned wrapper for a transfer. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Debug)] #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] -#[serde(deny_unknown_fields)] -pub struct Transfer { - /// Transaction that created the transfer. - pub transaction_hash: TransactionHash, - /// Entity from which transfer was executed. - pub from: InitiatorAddr, - /// Account to which funds are transferred. - pub to: Option, - /// Source purse. - pub source: URef, - /// Target purse. - pub target: URef, - /// Transfer amount. - pub amount: U512, - /// Gas. - pub gas: Gas, - /// User-defined ID. - pub id: Option, +pub enum Transfer { + /// A version 1 transfer. + #[serde(rename = "Version1")] + V1(TransferV1), + /// A version 2 transfer. + #[serde(rename = "Version2")] + V2(TransferV2), } impl Transfer { - /// Creates a [`Transfer`]. - #[allow(clippy::too_many_arguments)] - pub fn new( - transaction_hash: TransactionHash, - from: InitiatorAddr, - to: Option, - source: URef, - target: URef, - amount: U512, - gas: Gas, - id: Option, - ) -> Self { - Transfer { - transaction_hash, - from, - to, - source, - target, - amount, - gas, - id, - } + // This method is not intended to be used by third party crates. + #[doc(hidden)] + #[cfg(feature = "json-schema")] + pub fn example() -> &'static Self { + &TRANSFER } } -impl ToBytes for Transfer { - fn to_bytes(&self) -> Result, bytesrepr::Error> { - let mut buf = Vec::new(); - self.write_bytes(&mut buf)?; - Ok(buf) - } - - fn serialized_length(&self) -> usize { - self.transaction_hash.serialized_length() - + self.from.serialized_length() - + self.to.serialized_length() - + self.source.serialized_length() - + self.target.serialized_length() - + self.amount.serialized_length() - + self.gas.serialized_length() - + self.id.serialized_length() - } - - fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - self.transaction_hash.write_bytes(writer)?; - self.from.write_bytes(writer)?; - self.to.write_bytes(writer)?; - self.source.write_bytes(writer)?; - self.target.write_bytes(writer)?; - self.amount.write_bytes(writer)?; - self.gas.write_bytes(writer)?; - self.id.write_bytes(writer) +impl From for Transfer { + fn from(v1_transfer: TransferV1) -> Self { + Transfer::V1(v1_transfer) } } -impl FromBytes for Transfer { - fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (transaction_hash, remainder) = TransactionHash::from_bytes(bytes)?; - let (from, remainder) = InitiatorAddr::from_bytes(remainder)?; - let (to, remainder) = >::from_bytes(remainder)?; - let (source, remainder) = URef::from_bytes(remainder)?; - let (target, remainder) = URef::from_bytes(remainder)?; - let (amount, remainder) = U512::from_bytes(remainder)?; - let (gas, remainder) = Gas::from_bytes(remainder)?; - let (id, remainder) = >::from_bytes(remainder)?; - Ok(( - Transfer { - transaction_hash, - from, - to, - source, - target, - amount, - gas, - id, - }, - remainder, - )) - } -} - -/// Error returned when decoding a `TransferAddr` from a formatted string. -#[derive(Debug)] -#[non_exhaustive] -pub enum FromStrError { - /// The prefix is invalid. - InvalidPrefix, - /// The address is not valid hex. - Hex(base16::DecodeError), - /// The slice is the wrong length. - Length(TryFromSliceError), -} - -impl From for FromStrError { - fn from(error: base16::DecodeError) -> Self { - FromStrError::Hex(error) +impl From for Transfer { + fn from(v2_transfer: TransferV2) -> Self { + Transfer::V2(v2_transfer) } } -impl From for FromStrError { - fn from(error: TryFromSliceError) -> Self { - FromStrError::Length(error) - } -} - -impl Display for FromStrError { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { +impl ToBytes for Transfer { + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { match self { - FromStrError::InvalidPrefix => write!(f, "prefix is not 'transfer-'"), - FromStrError::Hex(error) => { - write!(f, "failed to decode address portion from hex: {}", error) + Transfer::V1(transfer) => { + V1_TAG.write_bytes(writer)?; + transfer.write_bytes(writer) + } + Transfer::V2(transfer) => { + V2_TAG.write_bytes(writer)?; + transfer.write_bytes(writer) } - FromStrError::Length(error) => write!(f, "address portion is wrong length: {}", error), - } - } -} - -/// A newtype wrapping a [u8; [TRANSFER_ADDR_LENGTH]] which is the raw bytes of the -/// transfer address. -#[derive(Default, PartialOrd, Ord, PartialEq, Eq, Hash, Clone, Copy)] -#[cfg_attr(feature = "datasize", derive(DataSize))] -pub struct TransferAddr([u8; TRANSFER_ADDR_LENGTH]); - -impl TransferAddr { - /// Constructs a new `TransferAddr` instance from the raw bytes. - pub const fn new(value: [u8; TRANSFER_ADDR_LENGTH]) -> TransferAddr { - TransferAddr(value) - } - - /// Returns the raw bytes of the transfer address as an array. - pub fn value(&self) -> [u8; TRANSFER_ADDR_LENGTH] { - self.0 - } - - /// Returns the raw bytes of the transfer address as a `slice`. - pub fn as_bytes(&self) -> &[u8] { - &self.0 - } - - /// Formats the `TransferAddr` as a prefixed, hex-encoded string. - pub fn to_formatted_string(self) -> String { - format!( - "{}{}", - TRANSFER_ADDR_FORMATTED_STRING_PREFIX, - base16::encode_lower(&self.0), - ) - } - - /// Parses a string formatted as per `Self::to_formatted_string()` into a `TransferAddr`. - pub fn from_formatted_str(input: &str) -> Result { - let remainder = input - .strip_prefix(TRANSFER_ADDR_FORMATTED_STRING_PREFIX) - .ok_or(FromStrError::InvalidPrefix)?; - let bytes = - <[u8; TRANSFER_ADDR_LENGTH]>::try_from(checksummed_hex::decode(remainder)?.as_ref())?; - Ok(TransferAddr(bytes)) - } -} - -#[cfg(feature = "json-schema")] -impl JsonSchema for TransferAddr { - fn schema_name() -> String { - String::from("TransferAddr") - } - - fn json_schema(gen: &mut SchemaGenerator) -> Schema { - let schema = gen.subschema_for::(); - let mut schema_object = schema.into_object(); - schema_object.metadata().description = Some("Hex-encoded transfer address.".to_string()); - schema_object.into() - } -} - -impl Serialize for TransferAddr { - fn serialize(&self, serializer: S) -> Result { - if serializer.is_human_readable() { - self.to_formatted_string().serialize(serializer) - } else { - self.0.serialize(serializer) - } - } -} - -impl<'de> Deserialize<'de> for TransferAddr { - fn deserialize>(deserializer: D) -> Result { - if deserializer.is_human_readable() { - let formatted_string = String::deserialize(deserializer)?; - TransferAddr::from_formatted_str(&formatted_string).map_err(SerdeError::custom) - } else { - let bytes = <[u8; TRANSFER_ADDR_LENGTH]>::deserialize(deserializer)?; - Ok(TransferAddr(bytes)) } } -} - -impl Display for TransferAddr { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "{}", base16::encode_lower(&self.0)) - } -} - -impl Debug for TransferAddr { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "TransferAddr({})", base16::encode_lower(&self.0)) - } -} -impl CLTyped for TransferAddr { - fn cl_type() -> CLType { - CLType::ByteArray(TRANSFER_ADDR_LENGTH as u32) - } -} - -impl ToBytes for TransferAddr { - #[inline(always)] fn to_bytes(&self) -> Result, bytesrepr::Error> { - self.0.to_bytes() + let mut buffer = bytesrepr::allocate_buffer(self)?; + self.write_bytes(&mut buffer)?; + Ok(buffer) } - #[inline(always)] fn serialized_length(&self) -> usize { - self.0.serialized_length() - } - - #[inline(always)] - fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - self.0.write_bytes(writer) + U8_SERIALIZED_LENGTH + + match self { + Transfer::V1(transfer) => transfer.serialized_length(), + Transfer::V2(transfer) => transfer.serialized_length(), + } } } -impl FromBytes for TransferAddr { +impl FromBytes for Transfer { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (bytes, remainder) = FromBytes::from_bytes(bytes)?; - Ok((TransferAddr::new(bytes), remainder)) - } -} - -impl AsRef<[u8]> for TransferAddr { - fn as_ref(&self) -> &[u8] { - self.0.as_ref() - } -} - -#[cfg(any(feature = "testing", test))] -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> TransferAddr { - TransferAddr::new(rng.gen()) + let (tag, remainder) = u8::from_bytes(bytes)?; + match tag { + V1_TAG => { + let (transfer, remainder) = TransferV1::from_bytes(remainder)?; + Ok((Transfer::V1(transfer), remainder)) + } + V2_TAG => { + let (transfer, remainder) = TransferV2::from_bytes(remainder)?; + Ok((Transfer::V2(transfer), remainder)) + } + _ => Err(bytesrepr::Error::Formatting), + } } } -/// Generators for [`Transfer`] +/// Proptest generators for [`Transfer`]. #[cfg(any(feature = "testing", feature = "gens", test))] pub mod gens { - use proptest::prelude::{prop::option, Arbitrary, Strategy}; + use proptest::prelude::{prop::option, prop_oneof, Arbitrary, Strategy}; + use super::*; use crate::{ gens::{u512_arb, uref_arb}, - transaction_info::gens::{account_hash_arb, initiator_addr_arb, txn_hash_arb}, + transaction_info::gens::{ + account_hash_arb, deploy_hash_arb, initiator_addr_arb, txn_hash_arb, + }, Gas, Transfer, }; - /// Creates an arbitrary [`Transfer`] - pub fn transfer_arb() -> impl Strategy { + pub fn transfer_v1_arb() -> impl Strategy { + ( + deploy_hash_arb(), + account_hash_arb(), + option::of(account_hash_arb()), + uref_arb(), + uref_arb(), + u512_arb(), + u512_arb(), + option::of(::arbitrary()), + ) + .prop_map(|(deploy_hash, from, to, source, target, amount, gas, id)| { + TransferV1 { + deploy_hash, + from, + to, + source, + target, + amount, + gas, + id, + } + }) + } + + pub fn transfer_v2_arb() -> impl Strategy { ( txn_hash_arb(), initiator_addr_arb(), @@ -325,7 +185,7 @@ pub mod gens { option::of(::arbitrary()), ) .prop_map( - |(transaction_hash, from, to, source, target, amount, gas, id)| Transfer { + |(transaction_hash, from, to, source, target, amount, gas, id)| TransferV2 { transaction_hash, from, to, @@ -337,6 +197,14 @@ pub mod gens { }, ) } + + /// Creates an arbitrary [`Transfer`] + pub fn transfer_arb() -> impl Strategy { + prop_oneof![ + transfer_v1_arb().prop_map(Transfer::V1), + transfer_v2_arb().prop_map(Transfer::V2) + ] + } } #[cfg(test)] @@ -349,51 +217,8 @@ mod tests { proptest! { #[test] - fn test_serialization_roundtrip(transfer in gens::transfer_arb()) { + fn bytesrepr_roundtrip(transfer in gens::transfer_arb()) { bytesrepr::test_serialization_roundtrip(&transfer) } } - - #[test] - fn transfer_addr_from_str() { - let transfer_address = TransferAddr([4; 32]); - let encoded = transfer_address.to_formatted_string(); - let decoded = TransferAddr::from_formatted_str(&encoded).unwrap(); - assert_eq!(transfer_address, decoded); - - let invalid_prefix = - "transfe-0000000000000000000000000000000000000000000000000000000000000000"; - assert!(TransferAddr::from_formatted_str(invalid_prefix).is_err()); - - let invalid_prefix = - "transfer0000000000000000000000000000000000000000000000000000000000000000"; - assert!(TransferAddr::from_formatted_str(invalid_prefix).is_err()); - - let short_addr = "transfer-00000000000000000000000000000000000000000000000000000000000000"; - assert!(TransferAddr::from_formatted_str(short_addr).is_err()); - - let long_addr = - "transfer-000000000000000000000000000000000000000000000000000000000000000000"; - assert!(TransferAddr::from_formatted_str(long_addr).is_err()); - - let invalid_hex = - "transfer-000000000000000000000000000000000000000000000000000000000000000g"; - assert!(TransferAddr::from_formatted_str(invalid_hex).is_err()); - } - - #[test] - fn transfer_addr_serde_roundtrip() { - let transfer_address = TransferAddr([255; 32]); - let serialized = bincode::serialize(&transfer_address).unwrap(); - let decoded = bincode::deserialize(&serialized).unwrap(); - assert_eq!(transfer_address, decoded); - } - - #[test] - fn transfer_addr_json_roundtrip() { - let transfer_address = TransferAddr([255; 32]); - let json_string = serde_json::to_string_pretty(&transfer_address).unwrap(); - let decoded = serde_json::from_str(&json_string).unwrap(); - assert_eq!(transfer_address, decoded); - } } diff --git a/types/src/transfer/error.rs b/types/src/transfer/error.rs new file mode 100644 index 0000000000..b97ec03d6d --- /dev/null +++ b/types/src/transfer/error.rs @@ -0,0 +1,63 @@ +use core::{ + array::TryFromSliceError, + fmt::{self, Debug, Display, Formatter}, +}; +#[cfg(feature = "std")] +use std::error::Error as StdError; + +/// Error returned when decoding a `TransferAddr` from a formatted string. +#[derive(Debug, Clone)] +#[non_exhaustive] +pub enum TransferFromStrError { + /// The prefix is invalid. + InvalidPrefix, + /// The address is not valid hex. + Hex(base16::DecodeError), + /// The slice is the wrong length. + Length(TryFromSliceError), +} + +impl From for TransferFromStrError { + fn from(error: base16::DecodeError) -> Self { + TransferFromStrError::Hex(error) + } +} + +impl From for TransferFromStrError { + fn from(error: TryFromSliceError) -> Self { + TransferFromStrError::Length(error) + } +} + +impl Display for TransferFromStrError { + fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { + match self { + TransferFromStrError::InvalidPrefix => { + write!(formatter, "transfer addr prefix is invalid",) + } + TransferFromStrError::Hex(error) => { + write!( + formatter, + "failed to decode address portion of transfer addr from hex: {}", + error + ) + } + TransferFromStrError::Length(error) => write!( + formatter, + "address portion of transfer addr is wrong length: {}", + error + ), + } + } +} + +#[cfg(feature = "std")] +impl StdError for TransferFromStrError { + fn source(&self) -> Option<&(dyn StdError + 'static)> { + match self { + TransferFromStrError::InvalidPrefix => None, + TransferFromStrError::Hex(error) => Some(error), + TransferFromStrError::Length(error) => Some(error), + } + } +} diff --git a/types/src/transfer/transfer_addr.rs b/types/src/transfer/transfer_addr.rs new file mode 100644 index 0000000000..1a0c03a497 --- /dev/null +++ b/types/src/transfer/transfer_addr.rs @@ -0,0 +1,254 @@ +use alloc::{string::String, vec::Vec}; +use core::{ + convert::TryFrom, + fmt::{self, Display, Formatter}, +}; + +#[cfg(feature = "datasize")] +use datasize::DataSize; +#[cfg(any(feature = "testing", test))] +use rand::{ + distributions::{Distribution, Standard}, + Rng, +}; +#[cfg(feature = "json-schema")] +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use super::{ + transfer_v1::V1_PREFIX, transfer_v2::V2_PREFIX, TransferFromStrError, TransferV1Addr, + TransferV2Addr, TRANSFER_V1_ADDR_LENGTH, TRANSFER_V2_ADDR_LENGTH, +}; +#[cfg(any(feature = "testing", test))] +use crate::testing::TestRng; +use crate::{ + bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, + checksummed_hex, +}; + +pub(super) const TRANSFER_ADDR_FORMATTED_STRING_PREFIX: &str = "transfer-"; +const V1_TAG: u8 = 0; +const V2_TAG: u8 = 1; + +/// A versioned wrapper for a transfer address. +#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize, Debug)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +#[serde(deny_unknown_fields)] +pub enum TransferAddr { + /// A version 1 transfer address. + #[serde(rename = "Version1")] + V1(TransferV1Addr), + /// A version 2 transfer address. + #[serde(rename = "Version2")] + V2(TransferV2Addr), +} + +impl TransferAddr { + /// Formats the `TransferAddr` as a prefixed, hex-encoded string. + pub fn to_formatted_string(self) -> String { + match self { + TransferAddr::V1(addr) => addr.to_formatted_string(), + TransferAddr::V2(addr) => addr.to_formatted_string(), + } + } + + /// Parses a string formatted as per `Self::to_formatted_string()` into a `TransferAddr`. + pub fn from_formatted_str(input: &str) -> Result { + let v_remainder = input + .strip_prefix(TRANSFER_ADDR_FORMATTED_STRING_PREFIX) + .ok_or(TransferFromStrError::InvalidPrefix)?; + if let Some(v1_addr_hex) = v_remainder.strip_prefix(V1_PREFIX) { + let addr = <[u8; TRANSFER_V1_ADDR_LENGTH]>::try_from( + checksummed_hex::decode(v1_addr_hex)?.as_ref(), + )?; + Ok(TransferAddr::V1(TransferV1Addr::new(addr))) + } else if let Some(v2_addr_hex) = v_remainder.strip_prefix(V2_PREFIX) { + let addr = <[u8; TRANSFER_V2_ADDR_LENGTH]>::try_from( + checksummed_hex::decode(v2_addr_hex)?.as_ref(), + )?; + Ok(TransferAddr::V2(TransferV2Addr::new(addr))) + } else { + Err(TransferFromStrError::InvalidPrefix) + } + } + + /// Returns a random `TransferAddr`. + #[cfg(any(feature = "testing", test))] + pub fn random(rng: &mut TestRng) -> Self { + if rng.gen() { + TransferAddr::V1(TransferV1Addr::random(rng)) + } else { + TransferAddr::V2(TransferV2Addr::random(rng)) + } + } +} + +impl From for TransferAddr { + fn from(addr: TransferV1Addr) -> Self { + Self::V1(addr) + } +} + +impl From<&TransferV1Addr> for TransferAddr { + fn from(addr: &TransferV1Addr) -> Self { + Self::from(*addr) + } +} + +impl From for TransferAddr { + fn from(addr: TransferV2Addr) -> Self { + Self::V2(addr) + } +} + +impl From<&TransferV2Addr> for TransferAddr { + fn from(addr: &TransferV2Addr) -> Self { + Self::from(*addr) + } +} + +impl Display for TransferAddr { + fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { + match self { + TransferAddr::V1(addr) => Display::fmt(addr, formatter), + TransferAddr::V2(addr) => Display::fmt(addr, formatter), + } + } +} + +impl ToBytes for TransferAddr { + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + match self { + TransferAddr::V1(addr) => { + V1_TAG.write_bytes(writer)?; + addr.write_bytes(writer) + } + TransferAddr::V2(addr) => { + V2_TAG.write_bytes(writer)?; + addr.write_bytes(writer) + } + } + } + + fn to_bytes(&self) -> Result, bytesrepr::Error> { + let mut buffer = bytesrepr::allocate_buffer(self)?; + self.write_bytes(&mut buffer)?; + Ok(buffer) + } + + fn serialized_length(&self) -> usize { + U8_SERIALIZED_LENGTH + + match self { + TransferAddr::V1(addr) => addr.serialized_length(), + TransferAddr::V2(addr) => addr.serialized_length(), + } + } +} + +impl FromBytes for TransferAddr { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (tag, remainder) = u8::from_bytes(bytes)?; + match tag { + V1_TAG => { + let (addr, remainder) = TransferV1Addr::from_bytes(remainder)?; + Ok((TransferAddr::V1(addr), remainder)) + } + V2_TAG => { + let (addr, remainder) = TransferV2Addr::from_bytes(remainder)?; + Ok((TransferAddr::V2(addr), remainder)) + } + _ => Err(bytesrepr::Error::Formatting), + } + } +} + +#[cfg(any(feature = "testing", test))] +impl Distribution for Standard { + fn sample(&self, rng: &mut R) -> TransferAddr { + if rng.gen() { + TransferAddr::V1(TransferV1Addr::new(rng.gen())) + } else { + TransferAddr::V2(TransferV2Addr::new(rng.gen())) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::testing::TestRng; + + #[test] + fn transfer_addr_from_str() { + let transfer_v1_addr = TransferV1Addr::new([4; 32]); + let encoded = transfer_v1_addr.to_formatted_string(); + let decoded = TransferV1Addr::from_formatted_str(&encoded).unwrap(); + assert_eq!(transfer_v1_addr, decoded); + + let transfer_v2_addr = TransferV2Addr::new([4; 32]); + let encoded = transfer_v2_addr.to_formatted_string(); + let decoded = TransferV2Addr::from_formatted_str(&encoded).unwrap(); + assert_eq!(transfer_v2_addr, decoded); + + let invalid_prefix = + "transfer-v-0000000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + TransferV2Addr::from_formatted_str(invalid_prefix), + Err(TransferFromStrError::InvalidPrefix) + )); + + let invalid_prefix = + "transfer-v20000000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + TransferV2Addr::from_formatted_str(invalid_prefix), + Err(TransferFromStrError::InvalidPrefix) + )); + + let short_addr = + "transfer-v2-00000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + TransferV2Addr::from_formatted_str(short_addr), + Err(TransferFromStrError::Length(_)) + )); + + let long_addr = + "transfer-v2-000000000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + TransferV2Addr::from_formatted_str(long_addr), + Err(TransferFromStrError::Length(_)) + )); + + let invalid_hex = + "transfer-v2-000000000000000000000000000000000000000000000000000000000000000g"; + assert!(matches!( + TransferV2Addr::from_formatted_str(invalid_hex), + Err(TransferFromStrError::Hex(_)) + )); + } + + #[test] + fn bytesrepr_roundtrip() { + let rng = &mut TestRng::new(); + let addr = TransferAddr::random(rng); + bytesrepr::test_serialization_roundtrip(&addr); + } + + #[test] + fn bincode_roundtrip() { + let rng = &mut TestRng::new(); + let addr = TransferAddr::random(rng); + let serialized = bincode::serialize(&addr).unwrap(); + let decoded = bincode::deserialize(&serialized).unwrap(); + assert_eq!(addr, decoded); + } + + #[test] + fn json_roundtrip() { + let rng = &mut TestRng::new(); + let addr = TransferAddr::random(rng); + let json_string = serde_json::to_string_pretty(&addr).unwrap(); + let decoded = serde_json::from_str(&json_string).unwrap(); + assert_eq!(addr, decoded); + } +} diff --git a/types/src/transfer/transfer_v1.rs b/types/src/transfer/transfer_v1.rs new file mode 100644 index 0000000000..e161e49f67 --- /dev/null +++ b/types/src/transfer/transfer_v1.rs @@ -0,0 +1,132 @@ +mod transfer_v1_addr; + +use alloc::vec::Vec; + +#[cfg(feature = "datasize")] +use datasize::DataSize; +#[cfg(feature = "json-schema")] +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use crate::{ + account::AccountHash, + bytesrepr::{self, FromBytes, ToBytes}, + serde_helpers, DeployHash, URef, U512, +}; +pub(super) use transfer_v1_addr::V1_PREFIX; +pub use transfer_v1_addr::{TransferV1Addr, TRANSFER_V1_ADDR_LENGTH}; + +/// Represents a version 1 transfer from one purse to another. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default, Debug)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +#[serde(deny_unknown_fields)] +pub struct TransferV1 { + /// Deploy that created the transfer + #[serde(with = "serde_helpers::deploy_hash_as_array")] + #[cfg_attr( + feature = "json-schema", + schemars( + with = "DeployHash", + description = "Hex-encoded Deploy hash of Deploy that created the transfer." + ) + )] + pub deploy_hash: DeployHash, + /// Account from which transfer was executed + pub from: AccountHash, + /// Account to which funds are transferred + pub to: Option, + /// Source purse + pub source: URef, + /// Target purse + pub target: URef, + /// Transfer amount + pub amount: U512, + /// Gas + pub gas: U512, + /// User-defined id + pub id: Option, +} + +impl TransferV1 { + /// Creates a [`TransferV1`]. + #[allow(clippy::too_many_arguments)] + pub fn new( + deploy_hash: DeployHash, + from: AccountHash, + to: Option, + source: URef, + target: URef, + amount: U512, + gas: U512, + id: Option, + ) -> Self { + TransferV1 { + deploy_hash, + from, + to, + source, + target, + amount, + gas, + id, + } + } +} + +impl ToBytes for TransferV1 { + fn to_bytes(&self) -> Result, bytesrepr::Error> { + let mut buffer = bytesrepr::allocate_buffer(self)?; + self.write_bytes(&mut buffer)?; + Ok(buffer) + } + + fn serialized_length(&self) -> usize { + self.deploy_hash.serialized_length() + + self.from.serialized_length() + + self.to.serialized_length() + + self.source.serialized_length() + + self.target.serialized_length() + + self.amount.serialized_length() + + self.gas.serialized_length() + + self.id.serialized_length() + } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + self.deploy_hash.write_bytes(writer)?; + self.from.write_bytes(writer)?; + self.to.write_bytes(writer)?; + self.source.write_bytes(writer)?; + self.target.write_bytes(writer)?; + self.amount.write_bytes(writer)?; + self.gas.write_bytes(writer)?; + self.id.write_bytes(writer)?; + Ok(()) + } +} + +impl FromBytes for TransferV1 { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (deploy_hash, rem) = FromBytes::from_bytes(bytes)?; + let (from, rem) = AccountHash::from_bytes(rem)?; + let (to, rem) = >::from_bytes(rem)?; + let (source, rem) = URef::from_bytes(rem)?; + let (target, rem) = URef::from_bytes(rem)?; + let (amount, rem) = U512::from_bytes(rem)?; + let (gas, rem) = U512::from_bytes(rem)?; + let (id, rem) = >::from_bytes(rem)?; + Ok(( + TransferV1 { + deploy_hash, + from, + to, + source, + target, + amount, + gas, + id, + }, + rem, + )) + } +} diff --git a/types/src/transfer/transfer_v1/transfer_v1_addr.rs b/types/src/transfer/transfer_v1/transfer_v1_addr.rs new file mode 100644 index 0000000000..018be413e2 --- /dev/null +++ b/types/src/transfer/transfer_v1/transfer_v1_addr.rs @@ -0,0 +1,225 @@ +use alloc::{format, string::String, vec::Vec}; +use core::{ + convert::TryFrom, + fmt::{self, Debug, Display, Formatter}, +}; + +#[cfg(feature = "datasize")] +use datasize::DataSize; +#[cfg(any(feature = "testing", test))] +use rand::Rng; +#[cfg(feature = "json-schema")] +use schemars::JsonSchema; +use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer}; + +use super::super::{transfer_addr::TRANSFER_ADDR_FORMATTED_STRING_PREFIX, TransferFromStrError}; +#[cfg(any(feature = "testing", test))] +use crate::testing::TestRng; +use crate::{ + bytesrepr::{self, FromBytes, ToBytes}, + checksummed_hex, CLType, CLTyped, +}; + +/// The length of a version 1 transfer address. +pub const TRANSFER_V1_ADDR_LENGTH: usize = 32; +pub(in crate::transfer) const V1_PREFIX: &str = "v1-"; + +/// A newtype wrapping a [u8; [TRANSFER_V1_ADDR_LENGTH]] which is the raw bytes of the +/// transfer address. +#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Default)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr( + feature = "json-schema", + derive(JsonSchema), + schemars(description = "Hex-encoded version 1 transfer address.") +)] +pub struct TransferV1Addr( + #[cfg_attr(feature = "json-schema", schemars(skip, with = "String"))] + [u8; TRANSFER_V1_ADDR_LENGTH], +); + +impl TransferV1Addr { + /// Constructs a new `TransferV1Addr` instance from the raw bytes. + pub const fn new(value: [u8; TRANSFER_V1_ADDR_LENGTH]) -> TransferV1Addr { + TransferV1Addr(value) + } + + /// Returns the raw bytes of the transfer address as an array. + pub fn value(&self) -> [u8; TRANSFER_V1_ADDR_LENGTH] { + self.0 + } + + /// Returns the raw bytes of the transfer address as a `slice`. + pub fn as_bytes(&self) -> &[u8] { + &self.0 + } + + /// Formats the `TransferV1Addr` as a prefixed, hex-encoded string. + pub fn to_formatted_string(self) -> String { + format!( + "{}{}{}", + TRANSFER_ADDR_FORMATTED_STRING_PREFIX, + V1_PREFIX, + base16::encode_lower(&self.0), + ) + } + + /// Parses a string formatted as per `Self::to_formatted_string()` into a `TransferV1Addr`. + pub fn from_formatted_str(input: &str) -> Result { + let v1_remainder = input + .strip_prefix(TRANSFER_ADDR_FORMATTED_STRING_PREFIX) + .ok_or(TransferFromStrError::InvalidPrefix)?; + let remainder = v1_remainder + .strip_prefix(V1_PREFIX) + .ok_or(TransferFromStrError::InvalidPrefix)?; + let bytes = <[u8; TRANSFER_V1_ADDR_LENGTH]>::try_from( + checksummed_hex::decode(remainder)?.as_ref(), + )?; + Ok(TransferV1Addr(bytes)) + } + + /// Returns a random `TransferV1Addr`. + #[cfg(any(feature = "testing", test))] + pub fn random(rng: &mut TestRng) -> Self { + TransferV1Addr(rng.gen()) + } +} + +impl Serialize for TransferV1Addr { + fn serialize(&self, serializer: S) -> Result { + if serializer.is_human_readable() { + self.to_formatted_string().serialize(serializer) + } else { + self.0.serialize(serializer) + } + } +} + +impl<'de> Deserialize<'de> for TransferV1Addr { + fn deserialize>(deserializer: D) -> Result { + if deserializer.is_human_readable() { + let formatted_string = String::deserialize(deserializer)?; + TransferV1Addr::from_formatted_str(&formatted_string).map_err(SerdeError::custom) + } else { + let bytes = <[u8; TRANSFER_V1_ADDR_LENGTH]>::deserialize(deserializer)?; + Ok(TransferV1Addr(bytes)) + } + } +} + +impl Display for TransferV1Addr { + fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { + write!(formatter, "{}", base16::encode_lower(&self.0)) + } +} + +impl Debug for TransferV1Addr { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "TransferV1Addr({})", base16::encode_lower(&self.0)) + } +} + +impl CLTyped for TransferV1Addr { + fn cl_type() -> CLType { + CLType::ByteArray(TRANSFER_V1_ADDR_LENGTH as u32) + } +} + +impl ToBytes for TransferV1Addr { + #[inline(always)] + fn to_bytes(&self) -> Result, bytesrepr::Error> { + self.0.to_bytes() + } + + #[inline(always)] + fn serialized_length(&self) -> usize { + self.0.serialized_length() + } + + #[inline(always)] + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + self.0.write_bytes(writer) + } +} + +impl FromBytes for TransferV1Addr { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (bytes, remainder) = <[u8; TRANSFER_V1_ADDR_LENGTH]>::from_bytes(bytes)?; + Ok((TransferV1Addr(bytes), remainder)) + } +} + +#[cfg(test)] +mod tests { + use crate::{bytesrepr, testing::TestRng}; + + use super::*; + + #[test] + fn transfer_addr_from_str() { + let transfer_address = TransferV1Addr([4; 32]); + let encoded = transfer_address.to_formatted_string(); + let decoded = TransferV1Addr::from_formatted_str(&encoded).unwrap(); + assert_eq!(transfer_address, decoded); + + let invalid_prefix = + "transfer-v-0000000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + TransferV1Addr::from_formatted_str(invalid_prefix), + Err(TransferFromStrError::InvalidPrefix) + )); + + let invalid_prefix = + "transfer-v10000000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + TransferV1Addr::from_formatted_str(invalid_prefix), + Err(TransferFromStrError::InvalidPrefix) + )); + + let short_addr = + "transfer-v1-00000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + TransferV1Addr::from_formatted_str(short_addr), + Err(TransferFromStrError::Length(_)) + )); + + let long_addr = + "transfer-v1-000000000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + TransferV1Addr::from_formatted_str(long_addr), + Err(TransferFromStrError::Length(_)) + )); + + let invalid_hex = + "transfer-v1-000000000000000000000000000000000000000000000000000000000000000g"; + assert!(matches!( + TransferV1Addr::from_formatted_str(invalid_hex), + Err(TransferFromStrError::Hex(_)) + )); + } + + #[test] + fn bytesrepr_roundtrip() { + let rng = &mut TestRng::new(); + let transfer_address = TransferV1Addr::random(rng); + bytesrepr::test_serialization_roundtrip(&transfer_address) + } + + #[test] + fn bincode_roundtrip() { + let rng = &mut TestRng::new(); + let transfer_address = TransferV1Addr::random(rng); + let serialized = bincode::serialize(&transfer_address).unwrap(); + let decoded = bincode::deserialize(&serialized).unwrap(); + assert_eq!(transfer_address, decoded); + } + + #[test] + fn json_roundtrip() { + let rng = &mut TestRng::new(); + let transfer_address = TransferV1Addr::random(rng); + let json_string = serde_json::to_string_pretty(&transfer_address).unwrap(); + let decoded = serde_json::from_str(&json_string).unwrap(); + assert_eq!(transfer_address, decoded); + } +} diff --git a/types/src/transfer/transfer_v2.rs b/types/src/transfer/transfer_v2.rs new file mode 100644 index 0000000000..9333871b65 --- /dev/null +++ b/types/src/transfer/transfer_v2.rs @@ -0,0 +1,123 @@ +mod transfer_v2_addr; + +use alloc::vec::Vec; + +#[cfg(feature = "datasize")] +use datasize::DataSize; +#[cfg(feature = "json-schema")] +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use crate::{ + account::AccountHash, + bytesrepr::{self, FromBytes, ToBytes}, + Gas, InitiatorAddr, TransactionHash, URef, U512, +}; +pub(super) use transfer_v2_addr::V2_PREFIX; +pub use transfer_v2_addr::{TransferV2Addr, TRANSFER_V2_ADDR_LENGTH}; + +/// Represents a version 2 transfer from one purse to another. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Debug)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +#[serde(deny_unknown_fields)] +pub struct TransferV2 { + /// Transaction that created the transfer. + pub transaction_hash: TransactionHash, + /// Entity from which transfer was executed. + pub from: InitiatorAddr, + /// Account to which funds are transferred. + pub to: Option, + /// Source purse. + pub source: URef, + /// Target purse. + pub target: URef, + /// Transfer amount. + pub amount: U512, + /// Gas. + pub gas: Gas, + /// User-defined ID. + pub id: Option, +} + +impl TransferV2 { + /// Creates a [`TransferV2`]. + #[allow(clippy::too_many_arguments)] + pub fn new( + transaction_hash: TransactionHash, + from: InitiatorAddr, + to: Option, + source: URef, + target: URef, + amount: U512, + gas: Gas, + id: Option, + ) -> Self { + TransferV2 { + transaction_hash, + from, + to, + source, + target, + amount, + gas, + id, + } + } +} + +impl ToBytes for TransferV2 { + fn to_bytes(&self) -> Result, bytesrepr::Error> { + let mut buf = Vec::new(); + self.write_bytes(&mut buf)?; + Ok(buf) + } + + fn serialized_length(&self) -> usize { + self.transaction_hash.serialized_length() + + self.from.serialized_length() + + self.to.serialized_length() + + self.source.serialized_length() + + self.target.serialized_length() + + self.amount.serialized_length() + + self.gas.serialized_length() + + self.id.serialized_length() + } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + self.transaction_hash.write_bytes(writer)?; + self.from.write_bytes(writer)?; + self.to.write_bytes(writer)?; + self.source.write_bytes(writer)?; + self.target.write_bytes(writer)?; + self.amount.write_bytes(writer)?; + self.gas.write_bytes(writer)?; + self.id.write_bytes(writer) + } +} + +impl FromBytes for TransferV2 { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (transaction_hash, remainder) = TransactionHash::from_bytes(bytes)?; + let (from, remainder) = InitiatorAddr::from_bytes(remainder)?; + let (to, remainder) = >::from_bytes(remainder)?; + let (source, remainder) = URef::from_bytes(remainder)?; + let (target, remainder) = URef::from_bytes(remainder)?; + let (amount, remainder) = U512::from_bytes(remainder)?; + let (gas, remainder) = Gas::from_bytes(remainder)?; + let (id, remainder) = >::from_bytes(remainder)?; + Ok(( + TransferV2 { + transaction_hash, + from, + to, + source, + target, + amount, + gas, + id, + }, + remainder, + )) + } +} diff --git a/types/src/transfer/transfer_v2/transfer_v2_addr.rs b/types/src/transfer/transfer_v2/transfer_v2_addr.rs new file mode 100644 index 0000000000..a35aa27de0 --- /dev/null +++ b/types/src/transfer/transfer_v2/transfer_v2_addr.rs @@ -0,0 +1,225 @@ +use alloc::{format, string::String, vec::Vec}; +use core::{ + convert::TryFrom, + fmt::{self, Debug, Display, Formatter}, +}; + +#[cfg(feature = "datasize")] +use datasize::DataSize; +#[cfg(any(feature = "testing", test))] +use rand::Rng; +#[cfg(feature = "json-schema")] +use schemars::JsonSchema; +use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer}; + +use super::super::{transfer_addr::TRANSFER_ADDR_FORMATTED_STRING_PREFIX, TransferFromStrError}; +#[cfg(any(feature = "testing", test))] +use crate::testing::TestRng; +use crate::{ + bytesrepr::{self, FromBytes, ToBytes}, + checksummed_hex, CLType, CLTyped, +}; + +/// The length of a version 2 transfer address. +pub const TRANSFER_V2_ADDR_LENGTH: usize = 32; +pub(in crate::transfer) const V2_PREFIX: &str = "v2-"; + +/// A newtype wrapping a [u8; [TRANSFER_V2_ADDR_LENGTH]] which is the raw bytes of the +/// transfer address. +#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Default)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr( + feature = "json-schema", + derive(JsonSchema), + schemars(description = "Hex-encoded version 2 transfer address.") +)] +pub struct TransferV2Addr( + #[cfg_attr(feature = "json-schema", schemars(skip, with = "String"))] + [u8; TRANSFER_V2_ADDR_LENGTH], +); + +impl TransferV2Addr { + /// Constructs a new `TransferV2Addr` instance from the raw bytes. + pub const fn new(value: [u8; TRANSFER_V2_ADDR_LENGTH]) -> TransferV2Addr { + TransferV2Addr(value) + } + + /// Returns the raw bytes of the transfer address as an array. + pub fn value(&self) -> [u8; TRANSFER_V2_ADDR_LENGTH] { + self.0 + } + + /// Returns the raw bytes of the transfer address as a `slice`. + pub fn as_bytes(&self) -> &[u8] { + &self.0 + } + + /// Formats the `TransferV2Addr` as a prefixed, hex-encoded string. + pub fn to_formatted_string(self) -> String { + format!( + "{}{}{}", + TRANSFER_ADDR_FORMATTED_STRING_PREFIX, + V2_PREFIX, + base16::encode_lower(&self.0), + ) + } + + /// Parses a string formatted as per `Self::to_formatted_string()` into a `TransferV2Addr`. + pub fn from_formatted_str(input: &str) -> Result { + let v2_remainder = input + .strip_prefix(TRANSFER_ADDR_FORMATTED_STRING_PREFIX) + .ok_or(TransferFromStrError::InvalidPrefix)?; + let remainder = v2_remainder + .strip_prefix(V2_PREFIX) + .ok_or(TransferFromStrError::InvalidPrefix)?; + let bytes = <[u8; TRANSFER_V2_ADDR_LENGTH]>::try_from( + checksummed_hex::decode(remainder)?.as_ref(), + )?; + Ok(TransferV2Addr(bytes)) + } + + /// Returns a random `TransferV2Addr`. + #[cfg(any(feature = "testing", test))] + pub fn random(rng: &mut TestRng) -> Self { + TransferV2Addr(rng.gen()) + } +} + +impl Serialize for TransferV2Addr { + fn serialize(&self, serializer: S) -> Result { + if serializer.is_human_readable() { + self.to_formatted_string().serialize(serializer) + } else { + self.0.serialize(serializer) + } + } +} + +impl<'de> Deserialize<'de> for TransferV2Addr { + fn deserialize>(deserializer: D) -> Result { + if deserializer.is_human_readable() { + let formatted_string = String::deserialize(deserializer)?; + TransferV2Addr::from_formatted_str(&formatted_string).map_err(SerdeError::custom) + } else { + let bytes = <[u8; TRANSFER_V2_ADDR_LENGTH]>::deserialize(deserializer)?; + Ok(TransferV2Addr(bytes)) + } + } +} + +impl Display for TransferV2Addr { + fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { + write!(formatter, "{}", base16::encode_lower(&self.0)) + } +} + +impl Debug for TransferV2Addr { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "TransferV2Addr({})", base16::encode_lower(&self.0)) + } +} + +impl CLTyped for TransferV2Addr { + fn cl_type() -> CLType { + CLType::ByteArray(TRANSFER_V2_ADDR_LENGTH as u32) + } +} + +impl ToBytes for TransferV2Addr { + #[inline(always)] + fn to_bytes(&self) -> Result, bytesrepr::Error> { + self.0.to_bytes() + } + + #[inline(always)] + fn serialized_length(&self) -> usize { + self.0.serialized_length() + } + + #[inline(always)] + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + self.0.write_bytes(writer) + } +} + +impl FromBytes for TransferV2Addr { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (bytes, remainder) = <[u8; TRANSFER_V2_ADDR_LENGTH]>::from_bytes(bytes)?; + Ok((TransferV2Addr(bytes), remainder)) + } +} + +#[cfg(test)] +mod tests { + use crate::{bytesrepr, testing::TestRng}; + + use super::*; + + #[test] + fn transfer_addr_from_str() { + let transfer_address = TransferV2Addr([4; 32]); + let encoded = transfer_address.to_formatted_string(); + let decoded = TransferV2Addr::from_formatted_str(&encoded).unwrap(); + assert_eq!(transfer_address, decoded); + + let invalid_prefix = + "transfer-v-0000000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + TransferV2Addr::from_formatted_str(invalid_prefix), + Err(TransferFromStrError::InvalidPrefix) + )); + + let invalid_prefix = + "transfer-v20000000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + TransferV2Addr::from_formatted_str(invalid_prefix), + Err(TransferFromStrError::InvalidPrefix) + )); + + let short_addr = + "transfer-v2-00000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + TransferV2Addr::from_formatted_str(short_addr), + Err(TransferFromStrError::Length(_)) + )); + + let long_addr = + "transfer-v2-000000000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + TransferV2Addr::from_formatted_str(long_addr), + Err(TransferFromStrError::Length(_)) + )); + + let invalid_hex = + "transfer-v2-000000000000000000000000000000000000000000000000000000000000000g"; + assert!(matches!( + TransferV2Addr::from_formatted_str(invalid_hex), + Err(TransferFromStrError::Hex(_)) + )); + } + + #[test] + fn bytesrepr_roundtrip() { + let rng = &mut TestRng::new(); + let transfer_address = TransferV2Addr::random(rng); + bytesrepr::test_serialization_roundtrip(&transfer_address) + } + + #[test] + fn bincode_roundtrip() { + let rng = &mut TestRng::new(); + let transfer_address = TransferV2Addr::random(rng); + let serialized = bincode::serialize(&transfer_address).unwrap(); + let decoded = bincode::deserialize(&serialized).unwrap(); + assert_eq!(transfer_address, decoded); + } + + #[test] + fn json_roundtrip() { + let rng = &mut TestRng::new(); + let transfer_address = TransferV2Addr::random(rng); + let json_string = serde_json::to_string_pretty(&transfer_address).unwrap(); + let decoded = serde_json::from_str(&json_string).unwrap(); + assert_eq!(transfer_address, decoded); + } +} diff --git a/utils/validation/src/generators.rs b/utils/validation/src/generators.rs index 46bf00833a..77f00d06b7 100644 --- a/utils/validation/src/generators.rs +++ b/utils/validation/src/generators.rs @@ -19,7 +19,8 @@ use casper_types::{ CLValue, DeployHash, DeployInfo, EntityVersionKey, EntityVersions, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, EraId, Gas, Group, Groups, InitiatorAddr, Key, Package, PackageHash, PackageStatus, Parameter, ProtocolVersion, PublicKey, SecretKey, - StoredValue, TransactionHash, Transfer, TransferAddr, URef, U512, + StoredValue, TransactionHash, TransactionV1Hash, Transfer, TransferV1, TransferV1Addr, + TransferV2, URef, U512, }; use casper_validation::{ abi::{ABIFixture, ABITestCase}, @@ -66,19 +67,29 @@ pub fn make_abi_test_fixtures() -> Result { } }; - let transfer = Transfer::new( - TransactionHash::from(DeployHash::from_raw([44; 32])), - InitiatorAddr::from(AccountHash::new([100; 32])), + let legacy_transfer = TransferV1::new( + DeployHash::from_raw([44; 32]), + AccountHash::new([100; 32]), Some(AccountHash::new([101; 32])), URef::new([10; 32], AccessRights::WRITE), URef::new([11; 32], AccessRights::WRITE), U512::from(15_000_000_000u64), - Gas::new(2_500_000_000u64), + U512::from(2_500_000_000u64), Some(1), ); + let transfer = Transfer::V2(TransferV2::new( + TransactionHash::V1(TransactionV1Hash::from_raw([44; 32])), + InitiatorAddr::AccountHash(AccountHash::new([100; 32])), + Some(AccountHash::new([101; 32])), + URef::new([10; 32], AccessRights::WRITE), + URef::new([11; 32], AccessRights::WRITE), + U512::from(15_000_000_000u64), + Gas::new(2_500_000_000u64), + Some(1), + )); let deploy_info = DeployInfo::new( DeployHash::from_raw([55; 32]), - &[TransferAddr::new([1; 32]), TransferAddr::new([2; 32])], + &[TransferV1Addr::new([1; 32]), TransferV1Addr::new([2; 32])], AccountHash::new([100; 32]), URef::new([10; 32], AccessRights::READ_ADD_WRITE), U512::from(2_500_000_000u64), @@ -202,7 +213,7 @@ pub fn make_abi_test_fixtures() -> Result { const ACCOUNT_KEY: Key = Key::Account(AccountHash::new([42; 32])); const HASH_KEY: Key = Key::Hash([42; 32]); const UREF_KEY: Key = Key::URef(URef::new([42; 32], AccessRights::READ)); - const TRANSFER_KEY: Key = Key::Transfer(TransferAddr::new([42; 32])); + const LEGACY_TRANSFER_KEY: Key = Key::LegacyTransfer(TransferV1Addr::new([42; 32])); const DEPLOY_INFO_KEY: Key = Key::DeployInfo(DeployHash::from_raw([42; 32])); const ERA_INFO_KEY: Key = Key::EraInfo(EraId::new(42)); const BALANCE_KEY: Key = Key::Balance([42; 32]); @@ -228,8 +239,8 @@ pub fn make_abi_test_fixtures() -> Result { ABITestCase::from_inputs(vec![UREF_KEY.into()])?, ); keys.insert( - "Transfer".to_string(), - ABITestCase::from_inputs(vec![TRANSFER_KEY.into()])?, + "LegacyTransfer".to_string(), + ABITestCase::from_inputs(vec![LEGACY_TRANSFER_KEY.into()])?, ); keys.insert( "DeployInfo".to_string(), @@ -407,8 +418,8 @@ pub fn make_abi_test_fixtures() -> Result { ); stored_value.insert( - "Transfer".to_string(), - ABITestCase::from_inputs(vec![StoredValue::Transfer(transfer).into()])?, + "LegacyTransfer".to_string(), + ABITestCase::from_inputs(vec![StoredValue::LegacyTransfer(legacy_transfer).into()])?, ); stored_value.insert( "DeployInfo".to_string(), @@ -451,6 +462,10 @@ pub fn make_abi_test_fixtures() -> Result { ]) .into()])?, ); + stored_value.insert( + "Transfer".to_string(), + ABITestCase::from_inputs(vec![StoredValue::Transfer(transfer).into()])?, + ); Fixture::ABI { name: "stored_value".to_string(), diff --git a/utils/validation/tests/fixtures/ABI/key.json b/utils/validation/tests/fixtures/ABI/key.json index 6315c07f33..4b780a0afe 100644 --- a/utils/validation/tests/fixtures/ABI/key.json +++ b/utils/validation/tests/fixtures/ABI/key.json @@ -80,23 +80,23 @@ ], "output": "012a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a" }, - "SystemContractRegistry": { + "LegacyTransfer": { "input": [ { "type": "Key", - "value": "system-contract-registry-0000000000000000000000000000000000000000000000000000000000000000" + "value": "transfer-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a" } ], - "output": "0a0000000000000000000000000000000000000000000000000000000000000000" + "output": "032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a" }, - "Transfer": { + "SystemEntityRegistry": { "input": [ { "type": "Key", - "value": "transfer-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a" + "value": "system-entity-registry-0000000000000000000000000000000000000000000000000000000000000000" } ], - "output": "032a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a" + "output": "0a0000000000000000000000000000000000000000000000000000000000000000" }, "URef": { "input": [ diff --git a/utils/validation/tests/fixtures/ABI/stored_value.json b/utils/validation/tests/fixtures/ABI/stored_value.json index 3e50ac4403..fd56259dfc 100644 --- a/utils/validation/tests/fixtures/ABI/stored_value.json +++ b/utils/validation/tests/fixtures/ABI/stored_value.json @@ -39,8 +39,11 @@ "type": "StoredValue", "value": { "AddressableEntity": { + "protocol_version": "1.0.0", + "entity_kind": "SmartContract", "package_hash": "contract-package-6464646464646464646464646464646464646464646464646464646464646464", "byte_code_hash": "byte-code-6565656565656565656565656565656565656565656565656565656565656565", + "main_purse": "uref-0000000000000000000000000000000000000000000000000000000000000000-000", "entry_points": [ { "name": "public_entry_point_func", @@ -62,16 +65,13 @@ } } ], - "protocol_version": "1.0.0", - "main_purse": "uref-0000000000000000000000000000000000000000000000000000000000000000-000", "associated_keys": [], "action_thresholds": { "deployment": 1, "upgrade_management": 1, "key_management": 1 }, - "message_topics": [], - "entity_kind": "SmartContract" + "message_topics": [] } } } @@ -173,8 +173,8 @@ "DeployInfo": { "deploy_hash": "3737373737373737373737373737373737373737373737373737373737373737", "transfers": [ - "transfer-0101010101010101010101010101010101010101010101010101010101010101", - "transfer-0202020202020202020202020202020202020202020202020202020202020202" + "transfer-v1-0101010101010101010101010101010101010101010101010101010101010101", + "transfer-v1-0202020202020202020202020202020202020202020202020202020202020202" ], "from": "account-hash-6464646464646464646464646464646464646464646464646464646464646464", "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007", @@ -212,6 +212,26 @@ ], "output": "07020000000001197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d610400ca9a3b010202bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f201197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d610400ca9a3b" }, + "LegacyTransfer": { + "input": [ + { + "type": "StoredValue", + "value": { + "LegacyTransfer": { + "deploy_hash": "2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c", + "from": "account-hash-6464646464646464646464646464646464646464646464646464646464646464", + "to": "account-hash-6565656565656565656565656565656565656565656565656565656565656565", + "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-002", + "target": "uref-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b-002", + "amount": "15000000000", + "gas": "2500000000", + "id": 1 + } + } + } + ], + "output": "052c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c64646464646464646464646464646464646464646464646464646464646464640165656565656565656565656565656565656565656565656565656565656565650a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a020b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b020500d6117e030400f90295010100000000000000" + }, "Package": { "input": [ { @@ -266,19 +286,25 @@ "type": "StoredValue", "value": { "Transfer": { - "deploy_hash": "2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c", - "from": "account-hash-6464646464646464646464646464646464646464646464646464646464646464", - "to": "account-hash-6565656565656565656565656565656565656565656565656565656565656565", - "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-002", - "target": "uref-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b-002", - "amount": "15000000000", - "gas": "2500000000", - "id": 1 + "Version2": { + "transaction_hash": { + "Version1": "2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c" + }, + "from": { + "AccountHash": "account-hash-6464646464646464646464646464646464646464646464646464646464646464" + }, + "to": "account-hash-6565656565656565656565656565656565656565656565656565656565656565", + "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-002", + "target": "uref-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b-002", + "amount": "15000000000", + "gas": "2500000000", + "id": 1 + } } } } ], - "output": "052c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c64646464646464646464646464646464646464646464646464646464646464640165656565656565656565656565656565656565656565656565656565656565650a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a020b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b020500d6117e030400f90295010100000000000000" + "output": "1301012c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c0164646464646464646464646464646464646464646464646464646464646464640165656565656565656565656565656565656565656565656565656565656565650a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a020b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b020500d6117e030400f90295010100000000000000" }, "Unbonding": { "input": [ From 1a7d591383508bdf54c7058017d352498dcdfe35 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Fri, 23 Feb 2024 03:18:39 +0000 Subject: [PATCH 03/70] create transfer request builder and remove transfer fn from exec request builder --- Cargo.lock | 1 + .../src/engine_state/engine_config.rs | 9 + .../src/engine_state/execute_request.rs | 19 +- execution_engine/src/engine_state/mod.rs | 67 +--- execution_engine/src/execution/error.rs | 2 +- execution_engine/src/runtime/mod.rs | 6 +- .../test_support/Cargo.toml | 1 + .../src/execute_request_builder.rs | 21 +- .../test_support/src/lib.rs | 2 + .../src/transfer_request_builder.rs | 210 +++++++++++++ .../test_support/src/wasm_test_builder.rs | 68 ++++- .../contract_api/account/authorized_keys.rs | 52 +--- .../tests/src/test/contract_api/dictionary.rs | 58 ++-- .../contract_api/list_authorization_keys.rs | 41 ++- .../src/test/contract_api/transfer_cached.rs | 85 ++---- .../tests/src/test/deploy/receipts.rs | 28 +- .../tests/src/test/explorer/faucet.rs | 83 +++-- .../src/test/explorer/faucet_test_helpers.rs | 23 +- .../tests/src/test/get_balance.rs | 37 +-- .../private_chain/burn_fees_and_refund.rs | 26 +- .../test/private_chain/fees_accumulation.rs | 27 +- .../src/test/private_chain/management.rs | 24 +- .../private_chain/unrestricted_transfers.rs | 201 +++++------- .../tests/src/test/regression/ee_1160.rs | 73 +---- .../tests/src/test/regression/ee_1163.rs | 180 ++++------- .../tests/src/test/regression/ee_572.rs | 2 +- .../tests/src/test/regression/ee_599.rs | 2 +- .../tests/src/test/regression/ee_890.rs | 4 +- .../tests/src/test/regression/gh_1470.rs | 47 +-- .../tests/src/test/regression/gh_1902.rs | 21 +- .../tests/src/test/regression/gov_116.rs | 38 +-- .../tests/src/test/regression/gov_42.rs | 4 +- .../test/regression/regression_20210707.rs | 64 ++-- .../test/regression/regression_20210831.rs | 61 ++-- .../test/regression/regression_20211110.rs | 21 +- .../test/regression/regression_20220217.rs | 18 +- .../test/regression/regression_20220221.rs | 36 +-- .../test/regression/regression_20220222.rs | 17 +- .../test/system_contracts/auction_bidding.rs | 23 +- .../test/system_contracts/standard_payment.rs | 8 +- .../tests/src/test/upgrade.rs | 24 +- .../tests/src/test/wasmless_transfer.rs | 211 ++++--------- node/src/components/contract_runtime.rs | 21 +- node/src/components/contract_runtime/error.rs | 24 +- .../components/contract_runtime/operations.rs | 285 +++++++++++------- node/src/components/contract_runtime/types.rs | 6 +- node/src/components/contract_runtime/utils.rs | 68 +++-- storage/src/data_access_layer.rs | 4 +- storage/src/data_access_layer/execute.rs | 123 -------- storage/src/data_access_layer/transfer.rs | 21 +- storage/src/tracking_copy/error.rs | 2 +- types/src/block/signed_block_header.rs | 2 + types/src/transaction/transaction_hash.rs | 16 + 53 files changed, 1111 insertions(+), 1406 deletions(-) create mode 100644 execution_engine_testing/test_support/src/transfer_request_builder.rs delete mode 100644 storage/src/data_access_layer/execute.rs diff --git a/Cargo.lock b/Cargo.lock index ce42c60afa..617a001d18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -449,6 +449,7 @@ dependencies = [ name = "casper-engine-test-support" version = "6.0.0" dependencies = [ + "blake2", "casper-execution-engine", "casper-storage", "casper-types", diff --git a/execution_engine/src/engine_state/engine_config.rs b/execution_engine/src/engine_state/engine_config.rs index 5682f203f5..4c2e2d57b6 100644 --- a/execution_engine/src/engine_state/engine_config.rs +++ b/execution_engine/src/engine_state/engine_config.rs @@ -228,6 +228,15 @@ impl EngineConfig { pub fn compute_rewards(&self) -> bool { self.compute_rewards } + + /// Sets the protocol version of the config. + /// + /// NOTE: This is only useful to the WasmTestBuilder for emulating a network upgrade, and hence + /// is subject to change or deletion without notice. + #[doc(hidden)] + pub fn set_protocol_version(&mut self, protocol_version: ProtocolVersion) { + self.protocol_version = protocol_version; + } } /// A builder for an [`EngineConfig`]. diff --git a/execution_engine/src/engine_state/execute_request.rs b/execution_engine/src/engine_state/execute_request.rs index 63351779e1..01238fcea6 100644 --- a/execution_engine/src/engine_state/execute_request.rs +++ b/execution_engine/src/engine_state/execute_request.rs @@ -212,18 +212,15 @@ impl TryFrom<(TransactionV1Body, TransactionV1Hash)> for SessionInfo { ) -> Result { let (args, target, entry_point, _scheduling) = txn_v1_body.destructure(); - let session: Session; - match target { + let session = match target { TransactionTarget::Native => { - return Err(NewRequestError::InvalidSessionV1Target(txn_v1_hash)) - } - TransactionTarget::Stored { id, .. } => { - session = Session::Stored(id); + return Err(NewRequestError::InvalidSessionV1Target(txn_v1_hash)); } + TransactionTarget::Stored { id, .. } => Session::Stored(id), TransactionTarget::Session { kind, module_bytes, .. - } => session = Session::ModuleBytes { kind, module_bytes }, - } + } => Session::ModuleBytes { kind, module_bytes }, + }; let TransactionEntryPoint::Custom(session_entry_point) = entry_point else { return Err(NewRequestError::InvalidSessionV1EntryPoint(txn_v1_hash)); @@ -258,7 +255,7 @@ pub enum NewRequestError { #[derive(Debug)] pub struct ExecuteRequest { /// State root hash of the global state in which the transaction will be executed. - pub pre_state_hash: Digest, + pub state_hash: Digest, /// Block time represented as a unix timestamp. pub block_time: BlockTime, /// The hash identifying the transaction. @@ -288,7 +285,7 @@ pub struct ExecuteRequest { impl ExecuteRequest { /// Creates a new execute request. pub fn new( - parent_state_hash: Digest, + state_hash: Digest, block_time: BlockTime, txn: Transaction, proposer: PublicKey, @@ -331,7 +328,7 @@ impl ExecuteRequest { }; Ok(Self { - pre_state_hash: parent_state_hash, + state_hash, block_time, transaction_hash, gas_price, diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index 44bb84daad..369e820d49 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -26,7 +26,6 @@ use casper_storage::{ balance::BalanceResult, get_bids::{BidsRequest, BidsResult}, query::{QueryRequest, QueryResult}, - transfer::{TransferConfig, TransferRequest}, DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, FlushRequest, FlushResult, GenesisRequest, GenesisResult, ProtocolUpgradeRequest, ProtocolUpgradeResult, TrieRequest, }, @@ -56,8 +55,8 @@ use casper_types::{ handle_payment::{self, ACCUMULATION_PURSE_KEY}, AUCTION, HANDLE_PAYMENT, MINT, }, - AddressableEntity, AddressableEntityHash, BlockTime, Digest, EntityAddr, FeeHandling, Gas, - InitiatorAddr, Key, KeyTag, Motes, Phase, ProtocolVersion, PublicKey, RuntimeArgs, StoredValue, + AddressableEntity, AddressableEntityHash, BlockTime, Digest, EntityAddr, FeeHandling, Gas, Key, + KeyTag, Motes, Phase, ProtocolVersion, PublicKey, RuntimeArgs, StoredValue, SystemEntityRegistry, TransactionHash, TransactionInfo, TransactionSessionKind, TransactionV1Hash, URef, U512, }; @@ -338,46 +337,6 @@ where Ok(BalanceResult::Success { motes, proof }) } - /// Executes a transfer. - /// - /// Native transfers do not involve WASM at all, and also skip executing payment code. - /// Therefore this is the fastest and cheapest way to transfer tokens from account to account. - /// - /// Returns an [`ExecutionResult`] for a successful native transfer. - #[allow(clippy::too_many_arguments)] - pub fn transfer( - &self, - _executor: &Executor, - protocol_version: ProtocolVersion, - prestate_hash: Digest, - blocktime: BlockTime, - deploy_item: DeployItem, - proposer: PublicKey, - ) -> Result { - let deploy_hash = deploy_item.deploy_hash; - let transfer_config = TransferConfig::new( - self.config.administrative_accounts.clone(), - self.config.allow_unrestricted_transfers, - ); - let wasmless_transfer_gas = - Gas::new(self.config().system_config().wasmless_transfer_cost()); - let transfer_req = TransferRequest::with_runtime_args( - transfer_config, - prestate_hash, - blocktime.value(), - protocol_version, - proposer, - TransactionHash::Deploy(deploy_hash), // TODO - should have this passed in - InitiatorAddr::AccountHash(deploy_item.address), // TODO - should have this passed in - deploy_item.authorization_keys, - deploy_item.session.args().clone(), - wasmless_transfer_gas, - ); - let transfer_result = self.state.transfer(transfer_req); - ExecutionResult::from_transfer_result(transfer_result, wasmless_transfer_gas) - .map_err(|_| Error::RootNotFound(prestate_hash)) - } - /// Executes a transaction. /// /// A transaction execution consists of running the payment code, which is expected to deposit @@ -391,7 +350,7 @@ where pub fn execute_transaction( &self, ExecuteRequest { - pre_state_hash, + state_hash, block_time, transaction_hash, gas_price, @@ -413,9 +372,9 @@ where // Create tracking copy (which functions as a deploy context) // validation_spec_2: prestate_hash check // do this second; as there is no reason to proceed if the prestate hash is invalid - let tracking_copy = match self.tracking_copy(pre_state_hash) { + let tracking_copy = match self.tracking_copy(state_hash) { Err(gse) => return Ok(ExecutionResult::precondition_failure(Error::Storage(gse))), - Ok(None) => return Err(Error::RootNotFound(pre_state_hash)), + Ok(None) => return Err(Error::RootNotFound(state_hash)), Ok(Some(tracking_copy)) => Rc::new(RefCell::new(tracking_copy)), }; @@ -560,8 +519,8 @@ where // payment_code_spec_6: system contract validity let Some(payment_purse_key) = handle_payment_named_keys.get(handle_payment::PAYMENT_PURSE_KEY).copied() else { - return Ok(ExecutionResult::precondition_failure(Error::Deploy)); - }; + return Ok(ExecutionResult::precondition_failure(Error::Deploy)); + }; let payment_purse_uref = payment_purse_key .into_uref() @@ -571,7 +530,7 @@ where let mut execution_result_builder = execution_result::ExecutionResultBuilder::new(); let rewards_target_purse = - match self.get_rewards_purse(protocol_version, proposer, pre_state_hash) { + match self.get_rewards_purse(protocol_version, proposer, state_hash) { Ok(target_purse) => target_purse, Err(error) => return Ok(ExecutionResult::precondition_failure(error)), }; @@ -901,7 +860,7 @@ where ) else { return Ok(ExecutionResult::precondition_failure( Error::GasConversionOverflow, - )) + )); }; let maybe_runtime_args = RuntimeArgs::try_new(|args| { @@ -1154,7 +1113,9 @@ where bids.push(bid_kind); } Some(_) => { - return BidsResult::Failure(TrackingCopyError::UnexpectedStoredValueVariant) + return BidsResult::Failure( + TrackingCopyError::UnexpectedStoredValueVariant, + ); } None => return BidsResult::Failure(TrackingCopyError::MissingBid(*key)), }, @@ -1171,7 +1132,7 @@ where protocol_version: ProtocolVersion, rewards: &BTreeMap, next_block_height: u64, - time: u64, + block_time: BlockTime, ) -> Result { let tracking_copy = match self.tracking_copy(pre_state_hash) { Ok(Some(tracking_copy)) => Rc::new(RefCell::new(tracking_copy)), @@ -1200,7 +1161,7 @@ where let txn_hash = { // seeds address generator w/ era_end_timestamp_millis - let mut bytes = time.into_bytes()?; + let mut bytes = block_time.into_bytes()?; bytes.append(&mut next_block_height.into_bytes()?); TransactionHash::V1(TransactionV1Hash::new(Digest::hash(&bytes))) }; diff --git a/execution_engine/src/execution/error.rs b/execution_engine/src/execution/error.rs index 2c64c2f4dd..fcfa5d4d3f 100644 --- a/execution_engine/src/execution/error.rs +++ b/execution_engine/src/execution/error.rs @@ -120,7 +120,7 @@ pub enum Error { #[error("Host buffer is empty")] HostBufferEmpty, /// WASM bytes contains an unsupported "start" section. - #[error("Unsupported WASM start")] + #[error("Unsupported Wasm start")] UnsupportedWasmStart, /// Contract package has no active contract versions. #[error("No active contract versions for contract package")] diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index 4811fb5465..bb4b4f75a3 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -3471,9 +3471,9 @@ where fn dump_runtime_stack_info(instance: casper_wasmi::ModuleRef, max_stack_height: u32) { let globals = instance.globals(); let Some(current_runtime_call_stack_height) = globals.last() - else { - return; - }; + else { + return; + }; if let RuntimeValue::I32(current_runtime_call_stack_height) = current_runtime_call_stack_height.get() diff --git a/execution_engine_testing/test_support/Cargo.toml b/execution_engine_testing/test_support/Cargo.toml index 23f021afe4..492ed70a82 100644 --- a/execution_engine_testing/test_support/Cargo.toml +++ b/execution_engine_testing/test_support/Cargo.toml @@ -11,6 +11,7 @@ repository = "https://github.com/CasperLabs/casper-node/tree/master/execution_en license = "Apache-2.0" [dependencies] +blake2 = "0.9.0" casper-execution-engine = { version = "6.0.0", path = "../../execution_engine", features = ["test-support"] } casper-storage = { version = "1.4.3", path = "../../storage" } casper-types = { version = "3.0.0", path = "../../types" } diff --git a/execution_engine_testing/test_support/src/execute_request_builder.rs b/execution_engine_testing/test_support/src/execute_request_builder.rs index d38bccfe69..ecd57865b5 100644 --- a/execution_engine_testing/test_support/src/execute_request_builder.rs +++ b/execution_engine_testing/test_support/src/execute_request_builder.rs @@ -18,7 +18,7 @@ use crate::{ /// Builds an [`ExecuteRequest`]. #[derive(Debug)] pub struct ExecuteRequestBuilder { - pre_state_hash: Digest, + state_hash: Digest, block_time: BlockTime, transaction_hash: TransactionHash, gas_price: u64, @@ -36,7 +36,7 @@ pub struct ExecuteRequestBuilder { impl Default for ExecuteRequestBuilder { fn default() -> Self { ExecuteRequestBuilder { - pre_state_hash: Self::DEFAULT_PRE_STATE_HASH, + state_hash: Self::DEFAULT_STATE_HASH, block_time: BlockTime::new(DEFAULT_BLOCK_TIME), transaction_hash: Self::DEFAULT_TRANSACTION_HASH, gas_price: DEFAULT_GAS_PRICE, @@ -54,8 +54,8 @@ impl Default for ExecuteRequestBuilder { } impl ExecuteRequestBuilder { - /// The default value used for `ExecuteRequest::pre_state_hash`. - pub const DEFAULT_PRE_STATE_HASH: Digest = Digest::from_raw([1; 32]); + /// The default value used for `ExecuteRequest::state_hash`. + pub const DEFAULT_STATE_HASH: Digest = Digest::from_raw([1; 32]); /// The default value used for `ExecuteRequest::transaction_hash`. pub const DEFAULT_TRANSACTION_HASH: TransactionHash = TransactionHash::V1(TransactionV1Hash::from_raw([2; 32])); @@ -65,8 +65,6 @@ impl ExecuteRequestBuilder { pub const DEFAULT_PAYMENT_ENTRY_POINT: &'static str = "call"; /// The default value used for `ExecuteRequest::session_entry_point`. pub const DEFAULT_SESSION_ENTRY_POINT: &'static str = "call"; - /// The default value used in `ExecuteRequest::authorization_keys`. - pub const DEFAULT_AUTHORIZATION_KEY: AccountHash = AccountHash::new([3; 32]); /// Returns a new `ExecuteRequestBuilder` with default values. pub fn new() -> Self { @@ -222,10 +220,10 @@ impl ExecuteRequestBuilder { self } - /// Consumes self and returns an [`ExecuteRequest`]. + /// Consumes self and returns an `ExecuteRequest`. pub fn build(self) -> ExecuteRequest { ExecuteRequest { - pre_state_hash: self.pre_state_hash, + state_hash: self.state_hash, block_time: self.block_time, transaction_hash: self.transaction_hash, gas_price: self.gas_price, @@ -242,11 +240,4 @@ impl ExecuteRequestBuilder { proposer: self.proposer, } } - - /// Returns an [`ExecuteRequest`] for a native transfer. - pub fn transfer(_sender: AccountHash, _transfer_args: RuntimeArgs) -> Self { - todo!( - "this should not be a part of Self - should maybe have an ExecuteNativeRequestBuilder" - ); - } } diff --git a/execution_engine_testing/test_support/src/lib.rs b/execution_engine_testing/test_support/src/lib.rs index e2cefdc695..32ab3f21ca 100644 --- a/execution_engine_testing/test_support/src/lib.rs +++ b/execution_engine_testing/test_support/src/lib.rs @@ -13,6 +13,7 @@ mod chainspec_config; mod deploy_item_builder; mod execute_request_builder; mod step_request_builder; +mod transfer_request_builder; mod upgrade_request_builder; pub mod utils; mod wasm_test_builder; @@ -39,6 +40,7 @@ use chainspec_config::PRODUCTION_PATH; pub use deploy_item_builder::DeployItemBuilder; pub use execute_request_builder::ExecuteRequestBuilder; pub use step_request_builder::StepRequestBuilder; +pub use transfer_request_builder::TransferRequestBuilder; pub use upgrade_request_builder::UpgradeRequestBuilder; pub use wasm_test_builder::{EntityWithNamedKeys, LmdbWasmTestBuilder, WasmTestBuilder}; diff --git a/execution_engine_testing/test_support/src/transfer_request_builder.rs b/execution_engine_testing/test_support/src/transfer_request_builder.rs new file mode 100644 index 0000000000..5879232d82 --- /dev/null +++ b/execution_engine_testing/test_support/src/transfer_request_builder.rs @@ -0,0 +1,210 @@ +use std::{ + collections::{BTreeMap, BTreeSet}, + iter, +}; + +use blake2::{ + digest::{Update, VariableOutput}, + VarBlake2b, +}; + +use casper_storage::data_access_layer::{TransferConfig, TransferRequest}; +use casper_types::{ + account::AccountHash, + bytesrepr::ToBytes, + system::mint::{ARG_AMOUNT, ARG_ID, ARG_SOURCE, ARG_TARGET}, + BlockTime, CLValue, Digest, Gas, InitiatorAddr, ProtocolVersion, PublicKey, RuntimeArgs, + TransactionHash, TransactionV1Hash, TransferTarget, URef, U512, +}; + +use crate::{ + DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, DEFAULT_BLOCK_TIME, + DEFAULT_PROPOSER_PUBLIC_KEY, DEFAULT_PROTOCOL_VERSION, +}; + +/// Builds a [`TransferRequest`]. +#[derive(Debug)] +pub struct TransferRequestBuilder { + config: TransferConfig, + state_hash: Digest, + block_time: BlockTime, + protocol_version: ProtocolVersion, + proposer: PublicKey, + transaction_hash: Option, + initiator: InitiatorAddr, + authorization_keys: BTreeSet, + args: BTreeMap, + gas: Gas, +} + +impl TransferRequestBuilder { + /// The default value used for `TransferRequest::config`. + pub const DEFAULT_CONFIG: TransferConfig = TransferConfig::Unadministered; + /// The default value used for `TransferRequest::state_hash`. + pub const DEFAULT_STATE_HASH: Digest = Digest::from_raw([1; 32]); + /// The default value used for `TransferRequest::gas`. + pub const DEFAULT_GAS: u64 = 2_500_000_000; + + /// Constructs a new `TransferRequestBuilder`. + pub fn new, T: Into>(amount: A, target: T) -> Self { + let mut args = BTreeMap::new(); + let _ = args.insert( + ARG_AMOUNT.to_string(), + CLValue::from_t(amount.into()).unwrap(), + ); + let _ = args.insert( + ARG_ID.to_string(), + CLValue::from_t(Option::::None).unwrap(), + ); + let target_value = match target.into() { + TransferTarget::PublicKey(public_key) => CLValue::from_t(public_key), + TransferTarget::AccountHash(account_hash) => CLValue::from_t(account_hash), + TransferTarget::URef(uref) => CLValue::from_t(uref), + } + .unwrap(); + let _ = args.insert(ARG_TARGET.to_string(), target_value); + TransferRequestBuilder { + config: Self::DEFAULT_CONFIG, + state_hash: Self::DEFAULT_STATE_HASH, + block_time: BlockTime::new(DEFAULT_BLOCK_TIME), + protocol_version: *DEFAULT_PROTOCOL_VERSION, + proposer: DEFAULT_PROPOSER_PUBLIC_KEY.clone(), + transaction_hash: None, + initiator: InitiatorAddr::PublicKey(DEFAULT_ACCOUNT_PUBLIC_KEY.clone()), + authorization_keys: iter::once(*DEFAULT_ACCOUNT_ADDR).collect(), + args, + gas: Gas::new(Self::DEFAULT_GAS), + } + } + + /// Sets the transfer config of the [`TransferRequest`]. + pub fn with_transfer_config(mut self, config: TransferConfig) -> Self { + self.config = config; + self + } + + /// Sets the block time of the [`TransferRequest`]. + pub fn with_block_time(mut self, block_time: u64) -> Self { + self.block_time = BlockTime::new(block_time); + self + } + + /// Sets the protocol version used by the [`TransferRequest`]. + pub fn with_protocol_version(mut self, protocol_version: ProtocolVersion) -> Self { + self.protocol_version = protocol_version; + self + } + + /// Sets the proposer used by the [`TransferRequest`]. + pub fn with_proposer(mut self, proposer: PublicKey) -> Self { + self.proposer = proposer; + self + } + + /// Sets the transaction hash used by the [`TransferRequest`]. + pub fn with_transaction_hash(mut self, transaction_hash: TransactionHash) -> Self { + self.transaction_hash = Some(transaction_hash); + self + } + + /// Sets the initiator used by the [`TransferRequest`], and adds its account hash to the set of + /// authorization keys. + pub fn with_initiator>(mut self, initiator: T) -> Self { + self.initiator = initiator.into(); + let _ = self + .authorization_keys + .insert(self.initiator.account_hash()); + self + } + + /// Sets the authorization keys used by the [`TransferRequest`]. + pub fn with_authorization_keys>( + mut self, + authorization_keys: T, + ) -> Self { + self.authorization_keys = authorization_keys.into_iter().collect(); + self + } + + /// Adds the "source" runtime arg, replacing the existing one if it exists. + pub fn with_source(mut self, source: URef) -> Self { + let value = CLValue::from_t(source).unwrap(); + let _ = self.args.insert(ARG_SOURCE.to_string(), value); + self + } + + /// Adds the "id" runtime arg, replacing the existing one if it exists.. + pub fn with_transfer_id(mut self, id: u64) -> Self { + let value = CLValue::from_t(Some(id)).unwrap(); + let _ = self.args.insert(ARG_ID.to_string(), value); + self + } + + /// Consumes self and returns a `TransferRequest`. + /// + /// If a transaction hash was not provided, the blake2b hash of the contents of the other fields + /// will be calculated, so that different requests will have different transaction hashes. Note + /// that this generated hash is not the same as what would have been generated on an actual + /// `Transaction` for an equivalent request. + pub fn build(self) -> TransferRequest { + let txn_hash = match self.transaction_hash { + Some(txn_hash) => txn_hash, + None => { + let mut result = [0; 32]; + let mut hasher = VarBlake2b::new(32).unwrap(); + + match &self.config { + TransferConfig::Administered { + administrative_accounts, + allow_unrestricted_transfer, + } => hasher.update( + (administrative_accounts, allow_unrestricted_transfer) + .to_bytes() + .unwrap(), + ), + TransferConfig::Unadministered => { + hasher.update([1]); + } + } + hasher.update(self.state_hash); + hasher.update(self.block_time.to_bytes().unwrap()); + hasher.update(self.protocol_version.to_bytes().unwrap()); + hasher.update(self.proposer.to_bytes().unwrap()); + hasher.update(self.initiator.to_bytes().unwrap()); + hasher.update(self.authorization_keys.to_bytes().unwrap()); + hasher.update(self.args.to_bytes().unwrap()); + hasher.update(self.gas.to_bytes().unwrap()); + hasher.finalize_variable(|slice| { + result.copy_from_slice(slice); + }); + TransactionHash::V1(TransactionV1Hash::from_raw(result)) + } + }; + + TransferRequest::with_runtime_args( + self.config, + self.state_hash, + self.block_time, + self.protocol_version, + self.proposer, + txn_hash, + self.initiator, + self.authorization_keys, + RuntimeArgs::from(self.args), + self.gas, + ) + } + + /// Sets the runtime args used by the [`TransferRequest`]. + /// + /// NOTE: This is not generally useful for creating a valid `TransferRequest`, and hence is + /// subject to change or deletion without notice. + #[doc(hidden)] + pub fn with_args(mut self, args: RuntimeArgs) -> Self { + self.args = args + .named_args() + .map(|named_arg| (named_arg.name().to_string(), named_arg.cl_value().clone())) + .collect(); + self + } +} diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index f6fdca20cb..73d7c90080 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -25,7 +25,8 @@ use casper_storage::{ data_access_layer::{ BalanceResult, BidsRequest, BlockStore, DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, GenesisRequest, GenesisResult, ProtocolUpgradeRequest, - ProtocolUpgradeResult, QueryRequest, QueryResult, + ProtocolUpgradeResult, QueryRequest, QueryResult, TransferConfig, TransferRequest, + TransferResult, }, global_state::{ state::{ @@ -53,11 +54,11 @@ use casper_types::{ mint::{ROUND_SEIGNIORAGE_RATE_KEY, TOTAL_SUPPLY_KEY}, AUCTION, HANDLE_PAYMENT, MINT, STANDARD_PAYMENT, }, - AddressableEntity, AddressableEntityHash, AuctionCosts, ByteCode, ByteCodeAddr, ByteCodeHash, - CLTyped, CLValue, Contract, Digest, EntityAddr, EraId, Gas, HandlePaymentCosts, Key, KeyTag, - MintCosts, Motes, Package, PackageHash, ProtocolUpgradeConfig, ProtocolVersion, PublicKey, - RefundHandling, StoredValue, SystemEntityRegistry, TransactionHash, TransactionInfo, Transfer, - TransferAddr, URef, OS_PAGE_SIZE, U512, + AddressableEntity, AddressableEntityHash, AuctionCosts, BlockTime, ByteCode, ByteCodeAddr, + ByteCodeHash, CLTyped, CLValue, Contract, Digest, EntityAddr, EraId, Gas, HandlePaymentCosts, + Key, KeyTag, MintCosts, Motes, Package, PackageHash, ProtocolUpgradeConfig, ProtocolVersion, + PublicKey, RefundHandling, StoredValue, SystemEntityRegistry, TransactionHash, TransactionInfo, + Transfer, TransferAddr, URef, OS_PAGE_SIZE, U512, }; use tempfile::TempDir; @@ -79,6 +80,7 @@ pub(crate) const DEFAULT_MAX_READERS: u32 = 512; const GLOBAL_STATE_DIR: &str = "global_state"; /// A wrapper structure that groups an entity alongside its namedkeys. +#[derive(Debug)] pub struct EntityWithNamedKeys { entity: AddressableEntity, named_keys: NamedKeys, @@ -182,14 +184,15 @@ impl LmdbWasmTestBuilder { /// Upgrades the execution engine using the scratch trie. pub fn upgrade_using_scratch( &mut self, - engine_config: EngineConfig, + mut engine_config: EngineConfig, upgrade_config: &mut ProtocolUpgradeConfig, ) -> &mut Self { let pre_state_hash = self.post_state_hash.expect("should have state hash"); upgrade_config.with_pre_state_hash(pre_state_hash); - let engine_state = Rc::get_mut(&mut self.engine_state).unwrap(); - engine_state.update_config(engine_config); + Rc::get_mut(&mut self.engine_state) + .unwrap() + .update_config(engine_config.clone()); let scratch_state = self.engine_state.get_scratch_engine_state(); let pre_state_hash = upgrade_config.pre_state_hash(); @@ -202,6 +205,10 @@ impl LmdbWasmTestBuilder { .write_scratch_to_db(pre_state_hash, scratch_state.into_inner()) .unwrap(); self.post_state_hash = Some(post_state_hash); + engine_config.set_protocol_version(upgrade_config.new_protocol_version()); + Rc::get_mut(&mut self.engine_state) + .unwrap() + .update_config(engine_config); ProtocolUpgradeResult::Success { post_state_hash, effects, @@ -504,7 +511,7 @@ impl LmdbWasmTestBuilder { // Scratch still requires that one deploy be executed and committed at a time. let exec_request = { let hash = self.post_state_hash.expect("expected post_state_hash"); - exec_request.pre_state_hash = hash; + exec_request.state_hash = hash; exec_request }; @@ -552,6 +559,31 @@ impl LmdbWasmTestBuilder { .expect("unable to run step request against scratch global state"); self } + + /// Runs a [`TransferRequest`]. + pub fn transfer_and_commit(&mut self, mut transfer_request: TransferRequest) -> &mut Self { + let pre_state_hash = self.post_state_hash.expect("expected post_state_hash"); + let transfer_config = TransferConfig::new( + self.engine_state.config().administrative_accounts().clone(), + self.engine_state.config().allow_unrestricted_transfers(), + ); + transfer_request.set_state_hash_and_config(pre_state_hash, transfer_config); + let gas = transfer_request.gas(); + let data_access_layer = self.engine_state.get_state(); + let transfer_result = data_access_layer.transfer(transfer_request); + // native transfer auto-commits + if let TransferResult::Success { + post_state_hash, .. + } = &transfer_result + { + self.post_state_hash = Some(*post_state_hash); + } + // Cache transformations + let execution_result = ExecutionResult::from_transfer_result(transfer_result, gas).unwrap(); + self.effects.push(execution_result.effects().clone()); + self.exec_results.push(execution_result); + self + } } impl WasmTestBuilder @@ -749,7 +781,7 @@ where /// Runs an [`ExecuteRequest`]. pub fn exec(&mut self, mut exec_request: ExecuteRequest) -> &mut Self { - exec_request.pre_state_hash = self.post_state_hash.expect("expected post_state_hash"); + exec_request.state_hash = self.post_state_hash.expect("expected post_state_hash"); let execution_result = self.engine_state.execute_transaction(exec_request).unwrap(); // Cache transformations self.effects.push(execution_result.effects().clone()); @@ -796,14 +828,14 @@ where engine_config: Option, upgrade_config: &mut ProtocolUpgradeConfig, ) -> &mut Self { - let engine_config = engine_config.unwrap_or_else(|| self.engine_state.config().clone()); + let mut engine_config = engine_config.unwrap_or_else(|| self.engine_state.config().clone()); let pre_state_hash = self.post_state_hash.expect("should have state hash"); upgrade_config.with_pre_state_hash(pre_state_hash); - let engine_state_mut = - Rc::get_mut(&mut self.engine_state).expect("should have unique ownership"); - engine_state_mut.update_config(engine_config); + Rc::get_mut(&mut self.engine_state) + .unwrap() + .update_config(engine_config.clone()); let req = ProtocolUpgradeRequest::new(upgrade_config.clone()); let result = self.engine_state.commit_upgrade(req); @@ -812,6 +844,10 @@ where post_state_hash, .. } = result { + engine_config.set_protocol_version(upgrade_config.new_protocol_version()); + Rc::get_mut(&mut self.engine_state) + .unwrap() + .update_config(engine_config); self.post_state_hash = Some(post_state_hash); } @@ -868,7 +904,7 @@ where protocol_version, rewards, next_block_height, - time, + BlockTime::new(time), )?; self.post_state_hash = Some(post_state_hash); diff --git a/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs b/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs index 946ba35416..bba8b24633 100644 --- a/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs +++ b/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs @@ -1,15 +1,13 @@ use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, ARG_AMOUNT, - DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, + ARG_AMOUNT, DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_execution_engine::{ engine_state::{self, Error}, execution, }; use casper_storage::{system::transfer::TransferError, tracking_copy::TrackingCopyError}; -use casper_types::{ - account::AccountHash, addressable_entity::Weight, runtime_args, system::mint, U512, -}; +use casper_types::{account::AccountHash, addressable_entity::Weight, runtime_args, U512}; const CONTRACT_ADD_ASSOCIATED_KEY: &str = "add_associated_key.wasm"; const CONTRACT_ADD_UPDATE_ASSOCIATED_KEY: &str = "add_update_associated_key.wasm"; @@ -513,24 +511,11 @@ fn should_not_authorize_transfer_without_deploy_key_threshold() { .commit(); // KEY_1 (w: 2) DEFAULT_ACCOUNT (w: 1) does not pass deploy threshold of 5 - let id: Option = None; - - let transfer_request_1 = { - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_transfer_args(runtime_args! { - mint::ARG_TARGET => KEY_2, - mint::ARG_AMOUNT => transfer_amount, - mint::ARG_ID => id, - }) - .with_deploy_hash([36; 32]) - .with_authorization_keys(&[KEY_1, *DEFAULT_ACCOUNT_ADDR]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy).build() - }; + let transfer_request_1 = TransferRequestBuilder::new(transfer_amount, KEY_2) + .with_authorization_keys([KEY_1, *DEFAULT_ACCOUNT_ADDR]) + .build(); - builder.exec(transfer_request_1).commit(); + builder.transfer_and_commit(transfer_request_1); let response = builder .get_exec_result_owned(3) @@ -544,22 +529,11 @@ fn should_not_authorize_transfer_without_deploy_key_threshold() { )); // KEY_1 (w: 2) KEY_2 (w: 2) DEFAULT_ACCOUNT_ADDR (w: 1) each passes threshold of 5 - let id: Option = None; + let transfer_request = TransferRequestBuilder::new(transfer_amount, KEY_2) + .with_authorization_keys([KEY_2, KEY_1, *DEFAULT_ACCOUNT_ADDR]) + .build(); - let transfer_request = { - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_transfer_args(runtime_args! { - mint::ARG_TARGET => KEY_2, - mint::ARG_AMOUNT => transfer_amount, - mint::ARG_ID => id, - }) - .with_deploy_hash([37; 32]) - .with_authorization_keys(&[KEY_2, KEY_1, *DEFAULT_ACCOUNT_ADDR]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy).build() - }; - - builder.exec(transfer_request).expect_success().commit(); + builder + .transfer_and_commit(transfer_request) + .expect_success(); } diff --git a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs index 1d1a579a5f..f0e73d5acc 100644 --- a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs +++ b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs @@ -1,18 +1,19 @@ +use std::{convert::TryFrom, path::PathBuf}; + use casper_engine_test_support::{ utils::create_genesis_config, DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, - ARG_AMOUNT, DEFAULT_ACCOUNTS, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_INITIAL_BALANCE, - DEFAULT_ACCOUNT_PUBLIC_KEY, DEFAULT_CHAINSPEC_REGISTRY, DEFAULT_GENESIS_CONFIG_HASH, - DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, MINIMUM_ACCOUNT_CREATION_BALANCE, - PRODUCTION_RUN_GENESIS_REQUEST, + TransferRequestBuilder, ARG_AMOUNT, DEFAULT_ACCOUNTS, DEFAULT_ACCOUNT_ADDR, + DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_ACCOUNT_PUBLIC_KEY, DEFAULT_CHAINSPEC_REGISTRY, + DEFAULT_GENESIS_CONFIG_HASH, DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, + MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state::Error as EngineError, execution::Error}; use casper_storage::data_access_layer::GenesisRequest; use casper_types::{ - account::AccountHash, addressable_entity::EntityKindTag, runtime_args, system::mint, - AccessRights, AddressableEntityHash, ApiError, CLType, CLValue, GenesisAccount, Key, Motes, - RuntimeArgs, StoredValue, U512, + account::AccountHash, addressable_entity::EntityKindTag, runtime_args, AccessRights, + AddressableEntityHash, ApiError, CLType, CLValue, GenesisAccount, Key, Motes, RuntimeArgs, + StoredValue, U512, }; -use std::{convert::TryFrom, path::PathBuf}; use dictionary_call::{NEW_DICTIONARY_ITEM_KEY, NEW_DICTIONARY_VALUE}; @@ -28,15 +29,8 @@ fn setup() -> (LmdbWasmTestBuilder, AddressableEntityHash) { builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); - let fund_request = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => >::None, - }, - ) - .build(); + let fund_request = + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, ACCOUNT_1_ADDR).build(); let install_contract_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -45,7 +39,7 @@ fn setup() -> (LmdbWasmTestBuilder, AddressableEntityHash) { ) .build(); - builder.exec(fund_request).commit().expect_success(); + builder.transfer_and_commit(fund_request).expect_success(); builder .exec(install_contract_request) @@ -114,7 +108,7 @@ fn query_dictionary_item( _ => { return Err( "Provided base key is nether an account or a contract".to_string() - ) + ); } }; @@ -456,15 +450,8 @@ fn dictionary_put_should_fail_with_large_item_key() { builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); - let fund_request = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => >::None, - }, - ) - .build(); + let fund_request = + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, ACCOUNT_1_ADDR).build(); let install_contract_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -475,7 +462,7 @@ fn dictionary_put_should_fail_with_large_item_key() { ) .build(); - builder.exec(fund_request).commit().expect_success(); + builder.transfer_and_commit(fund_request).expect_success(); builder.exec(install_contract_request).commit(); let exec_result = builder.get_last_exec_result().expect("should have results"); let error = exec_result.as_error().expect("should have error"); @@ -496,15 +483,8 @@ fn dictionary_get_should_fail_with_large_item_key() { builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); - let fund_request = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => >::None, - }, - ) - .build(); + let fund_request = + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, ACCOUNT_1_ADDR).build(); let install_contract_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -515,7 +495,7 @@ fn dictionary_get_should_fail_with_large_item_key() { ) .build(); - builder.exec(fund_request).commit().expect_success(); + builder.transfer_and_commit(fund_request).expect_success(); builder.exec(install_contract_request).commit(); let exec_result = builder.get_last_exec_result().expect("should have results"); let error = exec_result.as_error().expect("should have error"); diff --git a/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs b/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs index e363a9a7ea..d145d2791a 100644 --- a/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs +++ b/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs @@ -1,14 +1,12 @@ use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, + DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, + PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state::Error, execution}; use casper_types::{ - account::AccountHash, - addressable_entity::Weight, - runtime_args, - system::{mint, standard_payment::ARG_AMOUNT}, - ApiError, PublicKey, SecretKey, U512, + account::AccountHash, addressable_entity::Weight, runtime_args, + system::standard_payment::ARG_AMOUNT, ApiError, PublicKey, SecretKey, }; use once_cell::sync::Lazy; @@ -42,7 +40,7 @@ fn should_list_authorization_keys() { test_match( *DEFAULT_ACCOUNT_ADDR, vec![*DEFAULT_ACCOUNT_ADDR], - vec![*DEFAULT_ACCOUNT_ADDR] + vec![*DEFAULT_ACCOUNT_ADDR], ), "one signature should match the expected authorization key" ); @@ -50,7 +48,7 @@ fn should_list_authorization_keys() { !test_match( *DEFAULT_ACCOUNT_ADDR, vec![*ACCOUNT_2_ADDR, *DEFAULT_ACCOUNT_ADDR], - vec![*DEFAULT_ACCOUNT_ADDR, *ACCOUNT_1_ADDR] + vec![*DEFAULT_ACCOUNT_ADDR, *ACCOUNT_1_ADDR], ), "two signatures are off by one" ); @@ -58,7 +56,7 @@ fn should_list_authorization_keys() { test_match( *DEFAULT_ACCOUNT_ADDR, vec![*ACCOUNT_2_ADDR, *DEFAULT_ACCOUNT_ADDR], - vec![*DEFAULT_ACCOUNT_ADDR, *ACCOUNT_2_ADDR] + vec![*DEFAULT_ACCOUNT_ADDR, *ACCOUNT_2_ADDR], ), "two signatures should match the expected list" ); @@ -66,7 +64,7 @@ fn should_list_authorization_keys() { test_match( *ACCOUNT_1_ADDR, vec![*ACCOUNT_1_ADDR], - vec![*ACCOUNT_1_ADDR] + vec![*ACCOUNT_1_ADDR], ), "one signature should match the output for non-default account" ); @@ -75,7 +73,7 @@ fn should_list_authorization_keys() { test_match( *DEFAULT_ACCOUNT_ADDR, vec![*ACCOUNT_2_ADDR, *DEFAULT_ACCOUNT_ADDR, *ACCOUNT_1_ADDR], - vec![*ACCOUNT_1_ADDR, *ACCOUNT_2_ADDR, *DEFAULT_ACCOUNT_ADDR] + vec![*ACCOUNT_1_ADDR, *ACCOUNT_2_ADDR, *DEFAULT_ACCOUNT_ADDR], ), "multisig matches expected list" ); @@ -83,7 +81,7 @@ fn should_list_authorization_keys() { !test_match( *DEFAULT_ACCOUNT_ADDR, vec![*ACCOUNT_2_ADDR, *DEFAULT_ACCOUNT_ADDR, *ACCOUNT_1_ADDR], - vec![] + vec![], ), "multisig is not empty" ); @@ -91,7 +89,7 @@ fn should_list_authorization_keys() { !test_match( *DEFAULT_ACCOUNT_ADDR, vec![*ACCOUNT_2_ADDR, *DEFAULT_ACCOUNT_ADDR, *ACCOUNT_1_ADDR], - vec![*ACCOUNT_2_ADDR, *ACCOUNT_1_ADDR] + vec![*ACCOUNT_2_ADDR, *ACCOUNT_1_ADDR], ), "multisig does not include caller account" ); @@ -150,18 +148,13 @@ fn setup() -> LmdbWasmTestBuilder { .build() }; - let transfer_request = { - let transfer_args = runtime_args! { - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_TARGET => account, - mint::ARG_ID => Option::::None, - }; - - ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args).build() - }; + let transfer_request = + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, account).build(); builder.exec(add_key_request).expect_success().commit(); - builder.exec(transfer_request).expect_success().commit(); + builder + .transfer_and_commit(transfer_request) + .expect_success(); } builder diff --git a/execution_engine_testing/tests/src/test/contract_api/transfer_cached.rs b/execution_engine_testing/tests/src/test/contract_api/transfer_cached.rs index 544e10f8ee..52728c603f 100644 --- a/execution_engine_testing/tests/src/test/contract_api/transfer_cached.rs +++ b/execution_engine_testing/tests/src/test/contract_api/transfer_cached.rs @@ -1,17 +1,13 @@ use once_cell::sync::Lazy; -use rand::Rng; use tempfile::TempDir; use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, + LmdbWasmTestBuilder, TransferRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_INITIAL_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, }; -use casper_execution_engine::engine_state::{DeployItem, MAX_PAYMENT_AMOUNT}; +use casper_execution_engine::engine_state::MAX_PAYMENT_AMOUNT; use casper_types::{ - account::AccountHash, - runtime_args, - system::mint::{ARG_AMOUNT, ARG_ID, ARG_TARGET}, - PublicKey, RuntimeArgs, SecretKey, DEFAULT_WASMLESS_TRANSFER_COST, U512, + account::AccountHash, PublicKey, SecretKey, DEFAULT_WASMLESS_TRANSFER_COST, U512, }; static TRANSFER_AMOUNT: Lazy = Lazy::new(|| U512::from(MAX_PAYMENT_AMOUNT)); @@ -28,8 +24,6 @@ static ACCOUNT_2_PUBLIC_KEY: Lazy = Lazy::new(|| PublicKey::from(&*ACCOUNT_2_SECRET_KEY)); static ACCOUNT_2_ADDR: Lazy = Lazy::new(|| ACCOUNT_2_PUBLIC_KEY.to_account_hash()); -const ID_NONE: Option = None; - #[ignore] #[test] fn should_transfer_to_account_with_correct_balances() { @@ -41,21 +35,11 @@ fn should_transfer_to_account_with_correct_balances() { let pre_state_hash = builder.get_post_state_hash(); // Default account to account 1 - let exec_builder = ExecuteRequestBuilder::from_deploy_item(transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - ARG_TARGET => *ACCOUNT_1_ADDR, - ARG_AMOUNT => U512::one(), - ARG_ID => ID_NONE, - }, - )); + let transfer_request = TransferRequestBuilder::new(1, *ACCOUNT_1_ADDR).build(); builder - .scratch_exec_and_commit(exec_builder.build()) + .transfer_and_commit(transfer_request) .expect_success(); - builder.write_scratch_to_db(); - builder.flush_environment(); - assert_ne!( pre_state_hash, builder.get_post_state_hash(), @@ -99,51 +83,30 @@ fn should_transfer_from_default_and_then_to_another_account() { // Default account to account 1 // We must first transfer the amount account 1 will transfer to account 2, along with the fee // account 1 will need to pay for that transfer. - let exec_request = ExecuteRequestBuilder::from_deploy_item(transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - ARG_TARGET => *ACCOUNT_1_ADDR, - ARG_AMOUNT => *TRANSFER_AMOUNT + DEFAULT_WASMLESS_TRANSFER_COST, - ARG_ID => ID_NONE, - }, - )) + let transfer_request = TransferRequestBuilder::new( + *TRANSFER_AMOUNT + DEFAULT_WASMLESS_TRANSFER_COST, + *ACCOUNT_1_ADDR, + ) .build(); builder - .scratch_exec_and_commit(exec_request) + .transfer_and_commit(transfer_request) .expect_success(); - let exec_request = ExecuteRequestBuilder::from_deploy_item(transfer( - *ACCOUNT_1_ADDR, - runtime_args! { - ARG_TARGET => *ACCOUNT_2_ADDR, - ARG_AMOUNT => *TRANSFER_AMOUNT, - ARG_ID => ID_NONE, - }, - )) - .build(); - + let transfer_request = TransferRequestBuilder::new(*TRANSFER_AMOUNT, *ACCOUNT_2_ADDR) + .with_initiator(*ACCOUNT_1_ADDR) + .build(); builder - .scratch_exec_and_commit(exec_request) + .transfer_and_commit(transfer_request) .expect_success(); // Double spend test for account 1 - let exec_request = ExecuteRequestBuilder::from_deploy_item(transfer( - *ACCOUNT_1_ADDR, - runtime_args! { - ARG_TARGET => *ACCOUNT_2_ADDR, - ARG_AMOUNT => *TRANSFER_AMOUNT, - ARG_ID => ID_NONE, - }, - )) - .build(); - + let transfer_request = TransferRequestBuilder::new(*TRANSFER_AMOUNT, *ACCOUNT_2_ADDR) + .with_initiator(*ACCOUNT_1_ADDR) + .build(); builder - .scratch_exec_and_commit(exec_request) + .transfer_and_commit(transfer_request) .expect_failure(); - builder.write_scratch_to_db(); - builder.flush_environment(); - assert_ne!( pre_state_hash, builder.get_post_state_hash(), @@ -186,15 +149,3 @@ fn should_transfer_from_default_and_then_to_another_account() { "account 2 balance should have changed" ); } - -fn transfer(sender: AccountHash, transfer_args: RuntimeArgs) -> DeployItem { - let mut rng = rand::thread_rng(); - let deploy_hash = rng.gen(); - DeployItemBuilder::new() - .with_address(sender) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(transfer_args) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build() -} diff --git a/execution_engine_testing/tests/src/test/deploy/receipts.rs b/execution_engine_testing/tests/src/test/deploy/receipts.rs index ed53694719..4d1ac782c7 100644 --- a/execution_engine_testing/tests/src/test/deploy/receipts.rs +++ b/execution_engine_testing/tests/src/test/deploy/receipts.rs @@ -3,8 +3,8 @@ use std::collections::{BTreeMap, BTreeSet}; use once_cell::sync::Lazy; use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, DEFAULT_ACCOUNT_ADDR, + DEFAULT_ACCOUNT_PUBLIC_KEY, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_types::{ account::AccountHash, runtime_args, system::mint, AccessRights, Gas, InitiatorAddr, PublicKey, @@ -53,21 +53,17 @@ fn should_record_wasmless_transfer() { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); - let id = Some(0); + let id = 0; - let transfer_request = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - TRANSFER_ARG_TARGET => *ALICE_ADDR, - TRANSFER_ARG_AMOUNT => *TRANSFER_AMOUNT_1, - TRANSFER_ARG_ID => id - }, - ) - .build(); + let transfer_request = TransferRequestBuilder::new(*TRANSFER_AMOUNT_1, *ALICE_ADDR) + .with_transfer_id(id) + .build(); - let txn_hash = transfer_request.transaction_hash; + let txn_hash = transfer_request.transaction_hash(); - builder.exec(transfer_request).commit().expect_success(); + builder + .transfer_and_commit(transfer_request) + .expect_success(); let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -88,7 +84,7 @@ fn should_record_wasmless_transfer() { assert_eq!(txn_info.transaction_hash, txn_hash); assert_eq!( txn_info.from, - InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR) + InitiatorAddr::PublicKey(DEFAULT_ACCOUNT_PUBLIC_KEY.clone()) ); assert_eq!(txn_info.source, default_account.main_purse()); @@ -114,7 +110,7 @@ fn should_record_wasmless_transfer() { assert_eq!(transfer.target, alice_attenuated_main_purse); assert_eq!(transfer.amount, *TRANSFER_AMOUNT_1); assert_eq!(transfer.gas, Gas::zero()); - assert_eq!(transfer.id, id); + assert_eq!(transfer.id, Some(id)); } #[ignore] diff --git a/execution_engine_testing/tests/src/test/explorer/faucet.rs b/execution_engine_testing/tests/src/test/explorer/faucet.rs index 5d1f527680..82a6552322 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet.rs @@ -3,12 +3,12 @@ use num_rational::Ratio; use casper_execution_engine::{engine_state, execution}; use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, + DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_types::{ - account::AccountHash, addressable_entity::EntityKindTag, runtime_args, system::mint, ApiError, - Key, PublicKey, SecretKey, U512, + account::AccountHash, addressable_entity::EntityKindTag, runtime_args, ApiError, Key, + PublicKey, SecretKey, U512, }; // test constants. @@ -42,9 +42,8 @@ fn should_install_faucet_contract() { .build(); builder - .exec(fund_installer_account_request) - .expect_success() - .commit(); + .transfer_and_commit(fund_installer_account_request) + .expect_success(); let install_faucet_request = FaucetInstallSessionRequestBuilder::new().build(); @@ -144,9 +143,8 @@ fn should_allow_installer_to_set_variables() { .with_faucet_time_interval(Some(FAUCET_TIME_INTERVAL)); builder - .exec(helper.fund_installer_request()) - .expect_success() - .commit(); + .transfer_and_commit(helper.fund_installer_request()) + .expect_success(); builder .exec(helper.faucet_install_request()) @@ -238,9 +236,8 @@ fn should_fund_new_account() { .with_faucet_distributions_per_interval(Some(faucet_distributions_per_interval)); builder - .exec(helper.fund_installer_request()) - .expect_success() - .commit(); + .transfer_and_commit(helper.fund_installer_request()) + .expect_success(); builder .exec(helper.faucet_install_request()) @@ -305,9 +302,8 @@ fn should_fund_existing_account() { .with_faucet_distributions_per_interval(Some(faucet_distributions_per_interval)); builder - .exec(helper.fund_installer_request()) - .expect_success() - .commit(); + .transfer_and_commit(helper.fund_installer_request()) + .expect_success(); let user_account_initial_balance = U512::from(15_000_000_000u64); @@ -316,7 +312,9 @@ fn should_fund_existing_account() { .with_fund_amount(user_account_initial_balance) .build(); - builder.exec(fund_user_request).expect_success().commit(); + builder + .transfer_and_commit(fund_user_request) + .expect_success(); builder .exec(helper.faucet_install_request()) @@ -383,9 +381,8 @@ fn should_not_fund_once_exhausted() { // fund installer amount builder - .exec(helper.fund_installer_request()) - .expect_success() - .commit(); + .transfer_and_commit(helper.fund_installer_request()) + .expect_success(); // faucet install request builder @@ -579,9 +576,8 @@ fn should_allow_installer_to_fund_freely() { .with_faucet_time_interval(Some(10_000u64)); builder - .exec(helper.fund_installer_request()) - .expect_success() - .commit(); + .transfer_and_commit(helper.fund_installer_request()) + .expect_success(); builder .exec(helper.faucet_install_request()) @@ -674,9 +670,8 @@ fn should_not_fund_if_zero_distributions_per_interval() { .build(); builder - .exec(fund_installer_account_request) - .expect_success() - .commit(); + .transfer_and_commit(fund_installer_account_request) + .expect_success(); let faucet_fund_amount = U512::from(400_000_000_000_000u64); @@ -734,9 +729,8 @@ fn should_allow_funding_by_an_authorized_account() { .with_faucet_time_interval(Some(10_000u64)); builder - .exec(helper.fund_installer_request()) - .expect_success() - .commit(); + .transfer_and_commit(helper.fund_installer_request()) + .expect_success(); builder .exec(helper.faucet_install_request()) @@ -874,9 +868,8 @@ fn should_refund_proper_amount() { let mut helper = FaucetDeployHelper::default(); builder - .exec(helper.fund_installer_request()) - .expect_success() - .commit(); + .transfer_and_commit(helper.fund_installer_request()) + .expect_success(); let user_account_initial_balance = U512::from(15_000_000_000u64); @@ -885,7 +878,9 @@ fn should_refund_proper_amount() { .with_fund_amount(user_account_initial_balance) .build(); - builder.exec(fund_user_request).expect_success().commit(); + builder + .transfer_and_commit(fund_user_request) + .expect_success(); builder .exec(helper.faucet_install_request()) @@ -930,10 +925,10 @@ fn faucet_costs() { // This test will fail if execution costs vary. The expected costs should not be updated // without understanding why the cost has changed. If the costs do change, it should be // reflected in the "Costs by Entry Point" section of the faucet crate's README.md. - const EXPECTED_FAUCET_INSTALL_COST: u64 = 91_331_256_210; - const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_508_680; - const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_087_900; - const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_374_600; + const EXPECTED_FAUCET_INSTALL_COST: u64 = 91_845_549_880; + const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_527_120; + const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_103_080; + const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_410_400; let installer_account = AccountHash::new([1u8; 32]); let user_account: AccountHash = AccountHash::new([2u8; 32]); @@ -941,20 +936,12 @@ fn faucet_costs() { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); - let fund_installer_account_request = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => installer_account, - mint::ARG_AMOUNT => INSTALLER_FUND_AMOUNT, - mint::ARG_ID => >::None - }, - ) - .build(); + let fund_installer_account_request = + TransferRequestBuilder::new(INSTALLER_FUND_AMOUNT, installer_account).build(); builder - .exec(fund_installer_account_request) - .expect_success() - .commit(); + .transfer_and_commit(fund_installer_account_request) + .expect_success(); let faucet_fund_amount = U512::from(400_000_000_000_000u64); let installer_session_request = ExecuteRequestBuilder::standard( diff --git a/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs b/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs index e31a2cfd77..a76c960dd2 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs @@ -2,12 +2,13 @@ use rand::Rng; use casper_engine_test_support::{ DeployItemBuilder, EntityWithNamedKeys, ExecuteRequestBuilder, LmdbWasmTestBuilder, - DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, + TransferRequestBuilder, DEFAULT_PAYMENT, }; use casper_execution_engine::engine_state::ExecuteRequest; +use casper_storage::data_access_layer::TransferRequest; use casper_types::{ account::AccountHash, addressable_entity::EntityKindTag, bytesrepr::FromBytes, runtime_args, - system::mint, AddressableEntityHash, CLTyped, Key, PublicKey, URef, U512, + AddressableEntityHash, CLTyped, Key, PublicKey, URef, U512, }; use super::{ @@ -45,16 +46,12 @@ impl FundAccountRequestBuilder { self } - pub fn build(&self) -> ExecuteRequest { - ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => self.target_account, - mint::ARG_AMOUNT => self.fund_amount, - mint::ARG_ID => self.fund_id - }, - ) - .build() + pub fn build(&self) -> TransferRequest { + let mut builder = TransferRequestBuilder::new(self.fund_amount, self.target_account); + if let Some(id) = self.fund_id { + builder = builder.with_transfer_id(id); + } + builder.build() } } @@ -551,7 +548,7 @@ impl FaucetDeployHelper { self.faucet_time_interval } - pub fn fund_installer_request(&self) -> ExecuteRequest { + pub fn fund_installer_request(&self) -> TransferRequest { self.fund_account_request_builder .with_target_account(self.installer_account) .with_fund_amount(self.installer_fund_amount) diff --git a/execution_engine_testing/tests/src/test/get_balance.rs b/execution_engine_testing/tests/src/test/get_balance.rs index b636fa3e07..9c0a638b26 100644 --- a/execution_engine_testing/tests/src/test/get_balance.rs +++ b/execution_engine_testing/tests/src/test/get_balance.rs @@ -1,18 +1,13 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + LmdbWasmTestBuilder, TransferRequestBuilder, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_storage::tracking_copy::{self, ValidationError}; use casper_types::{ - account::AccountHash, runtime_args, AccessRights, Digest, Key, PublicKey, SecretKey, URef, U512, + account::AccountHash, AccessRights, Digest, Key, PublicKey, SecretKey, URef, U512, }; -const TRANSFER_ARG_TARGET: &str = "target"; -const TRANSFER_ARG_AMOUNT: &str = "amount"; -const TRANSFER_ARG_ID: &str = "id"; - static ALICE_KEY: Lazy = Lazy::new(|| { let secret_key = SecretKey::ed25519_from_bytes([3; SecretKey::ED25519_LENGTH]).unwrap(); PublicKey::from(&secret_key) @@ -27,17 +22,11 @@ fn get_balance_should_work() { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); - let transfer_request = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - TRANSFER_ARG_TARGET => *ALICE_ADDR, - TRANSFER_ARG_AMOUNT => *TRANSFER_AMOUNT_1, - TRANSFER_ARG_ID => >::None, - }, - ) - .build(); + let transfer_request = TransferRequestBuilder::new(*TRANSFER_AMOUNT_1, *ALICE_ADDR).build(); - builder.exec(transfer_request).commit().expect_success(); + builder + .transfer_and_commit(transfer_request) + .expect_success(); let alice_account = builder .get_entity_by_account_hash(*ALICE_ADDR) @@ -117,17 +106,11 @@ fn get_balance_using_public_key_should_work() { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); - let transfer_request = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - TRANSFER_ARG_TARGET => *ALICE_ADDR, - TRANSFER_ARG_AMOUNT => *TRANSFER_AMOUNT_1, - TRANSFER_ARG_ID => >::None, - }, - ) - .build(); + let transfer_request = TransferRequestBuilder::new(*TRANSFER_AMOUNT_1, *ALICE_ADDR).build(); - builder.exec(transfer_request).commit().expect_success(); + builder + .transfer_and_commit(transfer_request) + .expect_success(); let alice_account = builder .get_entity_by_account_hash(*ALICE_ADDR) diff --git a/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs b/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs index 6da9d16116..b745c5a7e3 100644 --- a/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs +++ b/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs @@ -1,11 +1,10 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, + ExecuteRequestBuilder, TransferRequestBuilder, DEFAULT_PAYMENT, + MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_types::{ - runtime_args, - system::{handle_payment::ACCUMULATION_PURSE_KEY, mint}, - EntityAddr, FeeHandling, RefundHandling, RuntimeArgs, DEFAULT_NOP_COST, - DEFAULT_WASMLESS_TRANSFER_COST, U512, + system::handle_payment::ACCUMULATION_PURSE_KEY, EntityAddr, FeeHandling, RefundHandling, + RuntimeArgs, DEFAULT_NOP_COST, DEFAULT_WASMLESS_TRANSFER_COST, U512, }; use num_rational::Ratio; use num_traits::{One, Zero}; @@ -84,6 +83,7 @@ fn should_burn_zero_refund_and_burn_fees() { let expected_fee_amount = *DEFAULT_PAYMENT; // 0% refund + fee test_burning_fees(full_refund_handling, fee_handling, expected_fee_amount); } + #[ignore] #[test] fn should_burn_full_refund_and_burn_fees() { @@ -137,16 +137,14 @@ fn test_burning_fees( expected_burn_amount, "total supply should be burned exactly by the amount of calculated fee after refund" ); - let exec_request_2 = { - let transfer_args = runtime_args! { - mint::ARG_TARGET => *ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => >::None, - }; - ExecuteRequestBuilder::transfer(*DEFAULT_ADMIN_ACCOUNT_ADDR, transfer_args).build() - }; + let transfer_request = + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, *ACCOUNT_1_ADDR) + .with_initiator(*DEFAULT_ADMIN_ACCOUNT_ADDR) + .build(); let total_supply_before = builder.total_supply(None); - builder.exec(exec_request_2).expect_success().commit(); + builder + .transfer_and_commit(transfer_request) + .expect_success(); let total_supply_after = builder.total_supply(None); match fee_handling { diff --git a/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs b/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs index 9876e6e9be..f1dbcf0471 100644 --- a/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs +++ b/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs @@ -1,13 +1,12 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_BLOCK_TIME, DEFAULT_PROPOSER_ADDR, DEFAULT_PROTOCOL_VERSION, + ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, UpgradeRequestBuilder, + DEFAULT_ACCOUNT_ADDR, DEFAULT_BLOCK_TIME, DEFAULT_PROPOSER_ADDR, DEFAULT_PROTOCOL_VERSION, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_execution_engine::engine_state::EngineConfigBuilder; use casper_types::{ - runtime_args, - system::{handle_payment::ACCUMULATION_PURSE_KEY, mint}, - EntityAddr, EraId, FeeHandling, Key, ProtocolVersion, RuntimeArgs, U512, + system::handle_payment::ACCUMULATION_PURSE_KEY, EntityAddr, EraId, FeeHandling, Key, + ProtocolVersion, RuntimeArgs, U512, }; use once_cell::sync::Lazy; @@ -83,21 +82,19 @@ fn should_finalize_and_accumulate_rewards_purse() { "none of the named keys should change before and after execution" ); - let exec_request_2 = { - let transfer_args = runtime_args! { - mint::ARG_TARGET => *ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => >::None, - }; - ExecuteRequestBuilder::transfer(*DEFAULT_ADMIN_ACCOUNT_ADDR, transfer_args).build() - }; + let transfer_request = + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, *ACCOUNT_1_ADDR) + .with_initiator(*DEFAULT_ADMIN_ACCOUNT_ADDR) + .build(); - let exec_request_2_proposer = exec_request_2.proposer.clone(); + let exec_request_2_proposer = transfer_request.proposer().clone(); let proposer_account_2 = builder .get_entity_by_account_hash(exec_request_2_proposer.to_account_hash()) .expect("should have proposer account"); - builder.exec(exec_request_2).expect_success().commit(); + builder + .transfer_and_commit(transfer_request) + .expect_success(); assert_eq!( builder.get_purse_balance(proposer_account_2.main_purse()), U512::zero() diff --git a/execution_engine_testing/tests/src/test/private_chain/management.rs b/execution_engine_testing/tests/src/test/private_chain/management.rs index 7310266b18..4aab6e7287 100644 --- a/execution_engine_testing/tests/src/test/private_chain/management.rs +++ b/execution_engine_testing/tests/src/test/private_chain/management.rs @@ -1,11 +1,11 @@ use std::convert::TryFrom; use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_AUCTION_DELAY, - DEFAULT_CHAINSPEC_REGISTRY, DEFAULT_GENESIS_CONFIG_HASH, DEFAULT_GENESIS_TIMESTAMP_MILLIS, - DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, - DEFAULT_ROUND_SEIGNIORAGE_RATE, DEFAULT_SYSTEM_CONFIG, DEFAULT_UNBONDING_DELAY, - DEFAULT_VALIDATOR_SLOTS, DEFAULT_WASM_CONFIG, + DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, + DEFAULT_AUCTION_DELAY, DEFAULT_CHAINSPEC_REGISTRY, DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_GENESIS_TIMESTAMP_MILLIS, DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, DEFAULT_PAYMENT, + DEFAULT_PROTOCOL_VERSION, DEFAULT_ROUND_SEIGNIORAGE_RATE, DEFAULT_SYSTEM_CONFIG, + DEFAULT_UNBONDING_DELAY, DEFAULT_VALIDATOR_SLOTS, DEFAULT_WASM_CONFIG, }; use casper_execution_engine::{ engine_state::{EngineConfigBuilder, Error, ExecuteRequest}, @@ -417,15 +417,13 @@ fn native_transfer_should_create_new_private_account() { let mut builder = super::private_chain_setup(); // Account 1 can deploy after genesis - let transfer_args = runtime_args! { - mint::ARG_TARGET => *ACCOUNT_2_ADDR, - mint::ARG_AMOUNT => U512::one(), - mint::ARG_ID => Some(1u64), - }; - let transfer_request = - ExecuteRequestBuilder::transfer(*DEFAULT_ADMIN_ACCOUNT_ADDR, transfer_args).build(); + let transfer_request = TransferRequestBuilder::new(1, *ACCOUNT_2_ADDR) + .with_initiator(*DEFAULT_ADMIN_ACCOUNT_ADDR) + .build(); - builder.exec(transfer_request).expect_success().commit(); + builder + .transfer_and_commit(transfer_request) + .expect_success(); let _account_2 = builder .get_entity_by_account_hash(*ACCOUNT_2_ADDR) diff --git a/execution_engine_testing/tests/src/test/private_chain/unrestricted_transfers.rs b/execution_engine_testing/tests/src/test/private_chain/unrestricted_transfers.rs index b354d63dd1..80b23107f3 100644 --- a/execution_engine_testing/tests/src/test/private_chain/unrestricted_transfers.rs +++ b/execution_engine_testing/tests/src/test/private_chain/unrestricted_transfers.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, - SYSTEM_ADDR, + DeployItemBuilder, ExecuteRequestBuilder, TransferRequestBuilder, DEFAULT_PAYMENT, + MINIMUM_ACCOUNT_CREATION_BALANCE, SYSTEM_ADDR, }; use casper_execution_engine::{engine_state::Error, execution}; use casper_storage::system::transfer::TransferError; @@ -30,31 +30,24 @@ const TEST_PAYMENT_STORED_HASH_NAME: &str = "test_payment_hash"; fn should_disallow_native_unrestricted_transfer_to_create_new_account_by_user() { let mut builder = super::private_chain_setup(); - let fund_transfer_1 = ExecuteRequestBuilder::transfer( - *DEFAULT_ADMIN_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => *ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => >::None, - }, - ) - .build(); + let fund_transfer_1 = + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, *ACCOUNT_1_ADDR) + .with_initiator(*DEFAULT_ADMIN_ACCOUNT_ADDR) + .build(); // Admin can transfer funds to create new account. - builder.exec(fund_transfer_1).expect_success().commit(); + builder + .transfer_and_commit(fund_transfer_1) + .expect_success(); - let transfer_request_1 = ExecuteRequestBuilder::transfer( - *ACCOUNT_1_ADDR, - runtime_args! { - mint::ARG_TARGET => *ACCOUNT_2_ADDR, - mint::ARG_AMOUNT => U512::one(), - mint::ARG_ID => >::None, - }, - ) - .build(); + let transfer_request_1 = TransferRequestBuilder::new(1, *ACCOUNT_2_ADDR) + .with_initiator(*ACCOUNT_1_ADDR) + .build(); // User can't transfer funds to create new account. - builder.exec(transfer_request_1).expect_failure().commit(); + builder + .transfer_and_commit(transfer_request_1) + .expect_failure(); let error = builder.get_error().expect("should have error"); assert!( @@ -66,18 +59,14 @@ fn should_disallow_native_unrestricted_transfer_to_create_new_account_by_user() error ); - let transfer_request_2 = ExecuteRequestBuilder::transfer( - *ACCOUNT_1_ADDR, - runtime_args! { - mint::ARG_TARGET => *DEFAULT_ADMIN_ACCOUNT_ADDR, - mint::ARG_AMOUNT => U512::one(), - mint::ARG_ID => >::None, - }, - ) - .build(); + let transfer_request_2 = TransferRequestBuilder::new(1, *DEFAULT_ADMIN_ACCOUNT_ADDR) + .with_initiator(*ACCOUNT_1_ADDR) + .build(); // User can transfer funds back to admin. - builder.exec(transfer_request_2).expect_success().commit(); + builder + .transfer_and_commit(transfer_request_2) + .expect_success(); } #[ignore] @@ -326,28 +315,22 @@ fn should_disallow_transfer_to_own_purse_via_native_transfer() { let account = builder .get_entity_with_named_keys_by_account_hash(*ACCOUNT_1_ADDR) .expect("should have account"); - let source: URef = account.main_purse(); - let target: URef = account + let source = account.main_purse(); + let target = account .named_keys() .get(TEST_PURSE) .unwrap() .into_uref() .expect("should be uref"); - let amount: U512 = U512::one(); - let id: Option = None; - let transfer_request = ExecuteRequestBuilder::transfer( - *ACCOUNT_1_ADDR, - runtime_args! { - mint::ARG_SOURCE => source, - mint::ARG_TARGET => target, - mint::ARG_AMOUNT => amount, - mint::ARG_ID => id, - }, - ) - .build(); + let transfer_request = TransferRequestBuilder::new(1, target) + .with_initiator(*ACCOUNT_1_ADDR) + .with_source(source) + .build(); - builder.exec(transfer_request).expect_failure().commit(); + builder + .transfer_and_commit(transfer_request) + .expect_failure(); let error = builder.get_error().expect("should have error"); assert!( @@ -380,28 +363,22 @@ fn should_allow_admin_to_transfer_to_own_purse_via_native_transfer() { let account = builder .get_entity_with_named_keys_by_account_hash(*DEFAULT_ADMIN_ACCOUNT_ADDR) .expect("should have account"); - let source: URef = account.main_purse(); - let target: URef = account + let source = account.main_purse(); + let target = account .named_keys() .get(TEST_PURSE) .unwrap() .into_uref() .expect("should be uref"); - let amount: U512 = U512::one(); - let id: Option = None; - let transfer_request = ExecuteRequestBuilder::transfer( - *DEFAULT_ADMIN_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_SOURCE => source, - mint::ARG_TARGET => target, - mint::ARG_AMOUNT => amount, - mint::ARG_ID => id, - }, - ) - .build(); + let transfer_request = TransferRequestBuilder::new(1, target) + .with_initiator(*DEFAULT_ADMIN_ACCOUNT_ADDR) + .with_source(source) + .build(); - builder.exec(transfer_request).expect_success().commit(); + builder + .transfer_and_commit(transfer_request) + .expect_success(); } #[ignore] @@ -501,42 +478,32 @@ fn should_not_allow_payment_to_purse_in_stored_payment() { fn should_disallow_native_unrestricted_transfer_to_existing_account_by_user() { let mut builder = super::private_chain_setup(); - let fund_transfer_1 = ExecuteRequestBuilder::transfer( - *DEFAULT_ADMIN_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => *ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => >::None, - }, - ) - .build(); + let fund_transfer_1 = + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, *ACCOUNT_1_ADDR) + .with_initiator(*DEFAULT_ADMIN_ACCOUNT_ADDR) + .build(); - let fund_transfer_2 = ExecuteRequestBuilder::transfer( - *DEFAULT_ADMIN_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => *ACCOUNT_2_ADDR, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => >::None, - }, - ) - .build(); + let fund_transfer_2 = + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, *ACCOUNT_2_ADDR) + .with_initiator(*DEFAULT_ADMIN_ACCOUNT_ADDR) + .build(); // Admin can transfer funds to create new account. - builder.exec(fund_transfer_1).expect_success().commit(); - builder.exec(fund_transfer_2).expect_success().commit(); + builder + .transfer_and_commit(fund_transfer_1) + .expect_success(); + builder + .transfer_and_commit(fund_transfer_2) + .expect_success(); - let transfer_request_1 = ExecuteRequestBuilder::transfer( - *ACCOUNT_1_ADDR, - runtime_args! { - mint::ARG_TARGET => *ACCOUNT_2_ADDR, - mint::ARG_AMOUNT => U512::one(), - mint::ARG_ID => >::None, - }, - ) - .build(); + let transfer_request_1 = TransferRequestBuilder::new(1, *ACCOUNT_2_ADDR) + .with_initiator(*ACCOUNT_1_ADDR) + .build(); // User can't transfer funds to create new account. - builder.exec(transfer_request_1).expect_failure().commit(); + builder + .transfer_and_commit(transfer_request_1) + .expect_failure(); let error = builder.get_error().expect("should have error"); assert!( @@ -548,18 +515,14 @@ fn should_disallow_native_unrestricted_transfer_to_existing_account_by_user() { error ); - let transfer_request_2 = ExecuteRequestBuilder::transfer( - *ACCOUNT_1_ADDR, - runtime_args! { - mint::ARG_TARGET => *DEFAULT_ADMIN_ACCOUNT_ADDR, - mint::ARG_AMOUNT => U512::one(), - mint::ARG_ID => >::None, - }, - ) - .build(); + let transfer_request_2 = TransferRequestBuilder::new(1, *DEFAULT_ADMIN_ACCOUNT_ADDR) + .with_initiator(*ACCOUNT_1_ADDR) + .build(); // User can transfer funds back to admin. - builder.exec(transfer_request_2).expect_success().commit(); + builder + .transfer_and_commit(transfer_request_2) + .expect_success(); } #[ignore] @@ -577,19 +540,16 @@ fn should_disallow_wasm_unrestricted_transfer_to_existing_account_by_user() { ) .build(); - let fund_transfer_2 = ExecuteRequestBuilder::transfer( - *DEFAULT_ADMIN_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => *ACCOUNT_2_ADDR, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => >::None, - }, - ) - .build(); + let fund_transfer_2 = + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, *ACCOUNT_2_ADDR) + .with_initiator(*DEFAULT_ADMIN_ACCOUNT_ADDR) + .build(); // Admin can transfer funds to create new account. builder.exec(fund_transfer_1).expect_success().commit(); - builder.exec(fund_transfer_2).expect_success().commit(); + builder + .transfer_and_commit(fund_transfer_2) + .expect_success(); let transfer_request_1 = ExecuteRequestBuilder::standard( *ACCOUNT_1_ADDR, @@ -821,17 +781,14 @@ fn should_allow_transfer_to_system_in_a_native_transfer() { "payment purse should be empty" ); - let fund_transfer_1 = ExecuteRequestBuilder::transfer( - *DEFAULT_ADMIN_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => *SYSTEM_ADDR, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => >::None, - }, - ) - .build(); + let fund_transfer_1 = + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, *SYSTEM_ADDR) + .with_initiator(*DEFAULT_ADMIN_ACCOUNT_ADDR) + .build(); - builder.exec(fund_transfer_1).expect_success().commit(); + builder + .transfer_and_commit(fund_transfer_1) + .expect_success(); assert_eq!( builder.get_purse_balance(payment_purse_uref), diff --git a/execution_engine_testing/tests/src/test/regression/ee_1160.rs b/execution_engine_testing/tests/src/test/regression/ee_1160.rs index f40d8dba60..95b6a6baf5 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1160.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1160.rs @@ -1,12 +1,9 @@ use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, + LmdbWasmTestBuilder, TransferRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_INITIAL_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_execution_engine::engine_state::WASMLESS_TRANSFER_FIXED_GAS_PRICE; -use casper_types::{ - account::AccountHash, runtime_args, system::mint, Gas, Motes, DEFAULT_WASMLESS_TRANSFER_COST, - U512, -}; +use casper_types::{account::AccountHash, Gas, Motes, DEFAULT_WASMLESS_TRANSFER_COST, U512}; const ACCOUNT_1_ADDR: AccountHash = AccountHash::new([1u8; 32]); @@ -30,27 +27,11 @@ fn ee_1160_wasmless_transfer_should_empty_account() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should get default_account"); - let no_wasm_transfer_request_1 = { - let wasmless_transfer_args = runtime_args! { - mint::ARG_TARGET => ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => transfer_amount, - mint::ARG_ID => >::None - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(wasmless_transfer_args) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([42; 32]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; - + let no_wasm_transfer_request_1 = + TransferRequestBuilder::new(transfer_amount, ACCOUNT_1_ADDR).build(); builder - .exec(no_wasm_transfer_request_1) - .expect_success() - .commit(); + .transfer_and_commit(no_wasm_transfer_request_1) + .expect_success(); let last_result = builder.get_exec_result_owned(0).unwrap(); @@ -85,24 +66,9 @@ fn ee_1160_transfer_larger_than_balance_should_fail() { let balance_before = builder.get_purse_balance(default_account.main_purse()); - let no_wasm_transfer_request_1 = { - let wasmless_transfer_args = runtime_args! { - mint::ARG_TARGET => ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => transfer_amount, - mint::ARG_ID => >::None - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(wasmless_transfer_args) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([42; 32]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; - - builder.exec(no_wasm_transfer_request_1).commit(); + let no_wasm_transfer_request_1 = + TransferRequestBuilder::new(transfer_amount, ACCOUNT_1_ADDR).build(); + builder.transfer_and_commit(no_wasm_transfer_request_1); let balance_after = builder.get_purse_balance(default_account.main_purse()); @@ -146,24 +112,9 @@ fn ee_1160_large_wasmless_transfer_should_avoid_overflow() { let balance_before = builder.get_purse_balance(default_account.main_purse()); - let no_wasm_transfer_request_1 = { - let wasmless_transfer_args = runtime_args! { - mint::ARG_TARGET => ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => transfer_amount, - mint::ARG_ID => >::None - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(wasmless_transfer_args) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([42; 32]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; - - builder.exec(no_wasm_transfer_request_1).commit(); + let no_wasm_transfer_request_1 = + TransferRequestBuilder::new(transfer_amount, ACCOUNT_1_ADDR).build(); + builder.transfer_and_commit(no_wasm_transfer_request_1); let balance_after = builder.get_purse_balance(default_account.main_purse()); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1163.rs b/execution_engine_testing/tests/src/test/regression/ee_1163.rs index f4c56d8a4e..0a7932d23d 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1163.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1163.rs @@ -1,20 +1,16 @@ use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_GAS_PRICE, PRODUCTION_RUN_GENESIS_REQUEST, + LmdbWasmTestBuilder, TransferRequestBuilder, DEFAULT_ACCOUNT_ADDR, + PRODUCTION_RUN_GENESIS_REQUEST, }; -use casper_execution_engine::engine_state::{ - Error, ExecuteRequest, WASMLESS_TRANSFER_FIXED_GAS_PRICE, -}; -use casper_storage::system::transfer::TransferError; +use casper_execution_engine::engine_state::{Error, WASMLESS_TRANSFER_FIXED_GAS_PRICE}; +use casper_storage::{data_access_layer::TransferRequest, system::transfer::TransferError}; use casper_types::{ - account::AccountHash, - runtime_args, - system::{handle_payment, mint}, - Gas, Motes, RuntimeArgs, DEFAULT_WASMLESS_TRANSFER_COST, U512, + account::AccountHash, system::handle_payment, Gas, Motes, RuntimeArgs, + DEFAULT_WASMLESS_TRANSFER_COST, U512, }; -const PRIORITIZED_GAS_PRICE: u64 = DEFAULT_GAS_PRICE * 7; -const ACCOUNT_1_ADDR: AccountHash = AccountHash::new([1u8; 32]); +// const PRIORITIZED_GAS_PRICE: u64 = DEFAULT_GAS_PRICE * 7; +// const ACCOUNT_1_ADDR: AccountHash = AccountHash::new([1u8; 32]); fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); @@ -24,7 +20,7 @@ fn setup() -> LmdbWasmTestBuilder { fn should_charge_for_user_error( builder: &mut LmdbWasmTestBuilder, - request: ExecuteRequest, + request: TransferRequest, ) -> Error { let transfer_cost = Gas::from(DEFAULT_WASMLESS_TRANSFER_COST); let transfer_cost_motes = @@ -37,7 +33,7 @@ fn should_charge_for_user_error( let purse_balance_before = builder.get_purse_balance(main_purse); let proposer_purse_balance_before = builder.get_proposer_purse_balance(); - builder.exec(request).commit(); + builder.transfer_and_commit(request); let purse_balance_after = builder.get_purse_balance(main_purse); let proposer_purse_balance_after = builder.get_proposer_purse_balance(); @@ -72,94 +68,48 @@ fn should_charge_for_user_error( response.as_error().cloned().expect("should have error") } -#[ignore] -#[test] -fn shouldnt_consider_gas_price_when_calculating_minimum_balance() { - let id: Option = None; - - let create_account_request = { - let transfer_amount = Motes::new(U512::from(DEFAULT_WASMLESS_TRANSFER_COST) + U512::one()); - - let transfer_args = runtime_args! { - - mint::ARG_TARGET => ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => transfer_amount.value(), - mint::ARG_ID => id, - }; - - ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args).build() - }; - - let transfer_request = { - let transfer_amount = Motes::new(U512::one()); - - let transfer_args = runtime_args! { - mint::ARG_TARGET => *DEFAULT_ACCOUNT_ADDR, - mint::ARG_AMOUNT => transfer_amount.value(), - mint::ARG_ID => id, - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(ACCOUNT_1_ADDR) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(transfer_args) - .with_authorization_keys(&[ACCOUNT_1_ADDR]) - .with_deploy_hash([42; 32]) - .with_gas_price(PRIORITIZED_GAS_PRICE) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; - - let mut builder = setup(); - builder - .exec(create_account_request) - .expect_success() - .commit(); - builder.exec(transfer_request).expect_success().commit(); -} - +// TODO: reenable when new payment logic is added #[ignore] #[test] fn should_properly_charge_fixed_cost_with_nondefault_gas_price() { - // implies 1:1 gas/motes conversion rate regardless of gas price - let transfer_cost_motes = Motes::new(U512::from(DEFAULT_WASMLESS_TRANSFER_COST)); - - let transfer_amount = Motes::new(U512::one()); - - let id: Option = None; - - let transfer_args = runtime_args! { - mint::ARG_TARGET => ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => transfer_amount.value(), - mint::ARG_ID => id, - }; - - let transfer_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(transfer_args) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([42; 32]) - .with_gas_price(PRIORITIZED_GAS_PRICE) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; - - let mut builder = setup(); - let default_account = builder - .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) - .expect("should have default account"); - let main_purse = default_account.main_purse(); - let purse_balance_before = builder.get_purse_balance(main_purse); - let proposer_purse_balance_before = builder.get_proposer_purse_balance(); - - builder.exec(transfer_request).commit(); - - let purse_balance_after = builder.get_purse_balance(main_purse); - let proposer_purse_balance_after = builder.get_proposer_purse_balance(); - - // TODO: reenable when new payment logic is added + // // implies 1:1 gas/motes conversion rate regardless of gas price + // let transfer_cost_motes = Motes::new(U512::from(DEFAULT_WASMLESS_TRANSFER_COST)); + // + // let transfer_amount = Motes::new(U512::one()); + // + // let id: Option = None; + // + // let transfer_args = runtime_args! { + // mint::ARG_TARGET => ACCOUNT_1_ADDR, + // mint::ARG_AMOUNT => transfer_amount.value(), + // mint::ARG_ID => id, + // }; + // + // let transfer_request = { + // let deploy_item = DeployItemBuilder::new() + // .with_address(*DEFAULT_ACCOUNT_ADDR) + // .with_empty_payment_bytes(runtime_args! {}) + // .with_transfer_args(transfer_args) + // .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + // .with_deploy_hash([42; 32]) + // .with_gas_price(PRIORITIZED_GAS_PRICE) + // .build(); + // ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + // }; + // + // let mut builder = setup(); + // let default_account = builder + // .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) + // .expect("should have default account"); + // let main_purse = default_account.main_purse(); + // let purse_balance_before = builder.get_purse_balance(main_purse); + // let proposer_purse_balance_before = builder.get_proposer_purse_balance(); + // + // builder.transfer(transfer_request).commit(); + // + // let purse_balance_after = builder.get_purse_balance(main_purse); + // let proposer_purse_balance_after = builder.get_proposer_purse_balance(); + // // let transfer_cost = Gas::from(DEFAULT_WASMLESS_TRANSFER_COST); // let response = builder // .get_exec_result_owned(0) @@ -173,22 +123,23 @@ fn should_properly_charge_fixed_cost_with_nondefault_gas_price() { // "expected actual cost is {}", // transfer_cost // ); - assert_eq!( - purse_balance_before - transfer_cost_motes.value() - transfer_amount.value(), - purse_balance_after - ); - assert_eq!( - proposer_purse_balance_before + transfer_cost_motes.value(), - proposer_purse_balance_after - ); + // assert_eq!( + // purse_balance_before - transfer_cost_motes.value() - transfer_amount.value(), + // purse_balance_after + // ); + // assert_eq!( + // proposer_purse_balance_before + transfer_cost_motes.value(), + // proposer_purse_balance_after + // ); } #[ignore] #[test] fn should_charge_for_wasmless_transfer_missing_args() { let transfer_args = RuntimeArgs::new(); - let transfer_request = - ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args).build(); + let transfer_request = TransferRequestBuilder::new(1, AccountHash::default()) + .with_args(transfer_args) + .build(); let mut builder = setup(); let error = should_charge_for_user_error(&mut builder, transfer_request); @@ -208,16 +159,7 @@ fn should_charge_for_wasmless_transfer_invalid_purse() { .expect("should have default account"); let main_purse = default_account.main_purse(); - let id: Option = None; - - let transfer_args = runtime_args! { - mint::ARG_TARGET => main_purse, - mint::ARG_AMOUNT => U512::one(), - mint::ARG_ID => id, - }; - - let transfer_request = - ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args).build(); + let transfer_request = TransferRequestBuilder::new(1, main_purse).build(); let error = should_charge_for_user_error(&mut builder, transfer_request); assert!(matches!( diff --git a/execution_engine_testing/tests/src/test/regression/ee_572.rs b/execution_engine_testing/tests/src/test/regression/ee_572.rs index 975c86ab3d..49341e9924 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_572.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_572.rs @@ -87,7 +87,7 @@ fn should_run_ee_572_regression() { let error_message = builder.get_error_message().unwrap(); assert!( - error_message.contains("ForgedReference"), + error_message.contains("Forged reference"), "{}", error_message ); diff --git a/execution_engine_testing/tests/src/test/regression/ee_599.rs b/execution_engine_testing/tests/src/test/regression/ee_599.rs index b59bf33a55..d64109cc41 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_599.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_599.rs @@ -9,7 +9,7 @@ use casper_types::{account::AccountHash, runtime_args, U512}; const CONTRACT_EE_599_REGRESSION: &str = "ee_599_regression.wasm"; const CONTRACT_TRANSFER_TO_ACCOUNT: &str = "transfer_to_account_u512.wasm"; const DONATION_PURSE_COPY_KEY: &str = "donation_purse_copy"; -const EXPECTED_ERROR: &str = "ForgedReference"; +const EXPECTED_ERROR: &str = "Forged reference"; const TRANSFER_FUNDS_KEY: &str = "transfer_funds"; const VICTIM_ADDR: AccountHash = AccountHash::new([42; 32]); diff --git a/execution_engine_testing/tests/src/test/regression/ee_890.rs b/execution_engine_testing/tests/src/test/regression/ee_890.rs index ce94fdc64a..0de5b8f03e 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_890.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_890.rs @@ -57,7 +57,7 @@ fn should_run_ee_890_gracefully_reject_start_node_in_session() { .commit(); let message = builder.get_error_message().expect("should fail"); assert!( - message.contains("UnsupportedWasmStart"), + message.contains("Unsupported Wasm start"), "Error message {:?} does not contain expected pattern", message ); @@ -85,7 +85,7 @@ fn should_run_ee_890_gracefully_reject_start_node_in_payment() { .commit(); let message = builder.get_error_message().expect("should fail"); assert!( - message.contains("UnsupportedWasmStart"), + message.contains("Unsupported Wasm start"), "Error message {:?} does not contain expected pattern", message ); diff --git a/execution_engine_testing/tests/src/test/regression/gh_1470.rs b/execution_engine_testing/tests/src/test/regression/gh_1470.rs index 02b84de6e8..3cc9f9737f 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1470.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1470.rs @@ -1,8 +1,9 @@ use std::collections::BTreeMap; use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_ACCOUNT_PUBLIC_KEY, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, UpgradeRequestBuilder, + DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, MINIMUM_ACCOUNT_CREATION_BALANCE, + PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_execution_engine::{ engine_state::{EngineConfigBuilder, Error}, @@ -11,7 +12,7 @@ use casper_execution_engine::{ use casper_types::{ account::AccountHash, runtime_args, - system::{auction, auction::DelegationRate, mint}, + system::{auction, auction::DelegationRate}, AccessRights, AddressableEntityHash, CLTyped, CLValue, Digest, EraId, Key, PackageHash, ProtocolVersion, RuntimeArgs, StoredValue, StoredValueTypeMismatch, SystemEntityRegistry, URef, U512, @@ -38,17 +39,11 @@ fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); - let transfer = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE, - mint::ARG_ID => Some(42u64), - }, - ) - .build(); + let transfer = TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, ACCOUNT_1_ADDR) + .with_transfer_id(42) + .build(); - builder.exec(transfer).expect_success().commit(); + builder.transfer_and_commit(transfer).expect_success(); let sem_ver = PROTOCOL_VERSION.value(); let new_protocol_version = @@ -657,17 +652,11 @@ fn should_transfer_after_major_version_bump_from_1_2_0() { .upgrade_with_upgrade_request_and_config(None, &mut upgrade_request) .expect_upgrade_success(); - let transfer_args = runtime_args! { - mint::ARG_AMOUNT => U512::one(), - mint::ARG_TARGET => AccountHash::new([3; 32]), - mint::ARG_ID => Some(1u64), - }; - - let transfer = ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args).build(); - - println!("About to execute"); + let transfer = TransferRequestBuilder::new(1, AccountHash::new([3; 32])) + .with_transfer_id(1) + .build(); - builder.exec(transfer).expect_success().commit(); + builder.transfer_and_commit(transfer).expect_success(); } #[ignore] @@ -676,12 +665,6 @@ fn should_transfer_after_minor_version_bump_from_1_2_0() { let (mut builder, lmdb_fixture_state, _temp_dir) = lmdb_fixture::builder_from_global_state_fixture(lmdb_fixture::RELEASE_1_3_1); - let transfer_args = runtime_args! { - mint::ARG_AMOUNT => U512::one(), - mint::ARG_TARGET => AccountHash::new([3; 32]), - mint::ARG_ID => Some(1u64), - }; - let current_protocol_version = lmdb_fixture_state.genesis_protocol_version(); let new_protocol_version = ProtocolVersion::from_parts( @@ -706,8 +689,10 @@ fn should_transfer_after_minor_version_bump_from_1_2_0() { .upgrade_with_upgrade_request_and_config(None, &mut upgrade_request) .expect_upgrade_success(); - let transfer = ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args).build(); - builder.exec(transfer).expect_success().commit(); + let transfer = TransferRequestBuilder::new(1, AccountHash::new([3; 32])) + .with_transfer_id(1) + .build(); + builder.transfer_and_commit(transfer).expect_success(); } #[ignore] diff --git a/execution_engine_testing/tests/src/test/regression/gh_1902.rs b/execution_engine_testing/tests/src/test/regression/gh_1902.rs index ba03d3fd8c..310534e6b1 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1902.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1902.rs @@ -1,8 +1,9 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_ACCOUNT_PUBLIC_KEY, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, + DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, MINIMUM_ACCOUNT_CREATION_BALANCE, + PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_execution_engine::engine_state::{ engine_config::DEFAULT_MINIMUM_DELEGATION_AMOUNT, ExecuteRequest, @@ -12,7 +13,7 @@ use casper_types::{ runtime_args, system::{ auction::{self, DelegationRate}, - mint, standard_payment, + standard_payment, }, AddressableEntity, Gas, PublicKey, SecretKey, U512, }; @@ -30,15 +31,11 @@ static ACCOUNT_1_ADDR: Lazy = Lazy::new(|| AccountHash::from(&*ACCO fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); - let id: Option = None; - let transfer_args_1 = runtime_args! { - mint::ARG_TARGET => *ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => id, - }; - let transfer_request_1 = - ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args_1).build(); - builder.exec(transfer_request_1).expect_success().commit(); + let transfer_request = + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, *ACCOUNT_1_ADDR).build(); + builder + .transfer_and_commit(transfer_request) + .expect_success(); builder } diff --git a/execution_engine_testing/tests/src/test/regression/gov_116.rs b/execution_engine_testing/tests/src/test/regression/gov_116.rs index ae978e35fb..805af838ac 100644 --- a/execution_engine_testing/tests/src/test/regression/gov_116.rs +++ b/execution_engine_testing/tests/src/test/regression/gov_116.rs @@ -5,18 +5,16 @@ use num_traits::Zero; use once_cell::sync::Lazy; use casper_engine_test_support::{ - utils, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNTS, DEFAULT_ACCOUNT_ADDR, - DEFAULT_ACCOUNT_PUBLIC_KEY, DEFAULT_CHAINSPEC_REGISTRY, DEFAULT_GENESIS_CONFIG_HASH, - DEFAULT_GENESIS_TIMESTAMP_MILLIS, DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, DEFAULT_PROTOCOL_VERSION, - DEFAULT_VALIDATOR_SLOTS, MINIMUM_ACCOUNT_CREATION_BALANCE, + utils, ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, DEFAULT_ACCOUNTS, + DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, DEFAULT_CHAINSPEC_REGISTRY, + DEFAULT_GENESIS_CONFIG_HASH, DEFAULT_GENESIS_TIMESTAMP_MILLIS, + DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, DEFAULT_PROTOCOL_VERSION, DEFAULT_VALIDATOR_SLOTS, + MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_storage::data_access_layer::GenesisRequest; use casper_types::{ runtime_args, - system::{ - auction::{self, DelegationRate, EraValidators, VESTING_SCHEDULE_LENGTH_MILLIS}, - mint, - }, + system::auction::{self, DelegationRate, EraValidators, VESTING_SCHEDULE_LENGTH_MILLIS}, GenesisAccount, GenesisConfigBuilder, GenesisValidator, Motes, PublicKey, SecretKey, U256, U512, }; @@ -107,17 +105,13 @@ fn initialize_builder() -> LmdbWasmTestBuilder { let run_genesis_request = utils::create_run_genesis_request(GENESIS_ACCOUNTS.clone()); builder.run_genesis(run_genesis_request); - let fund_request = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => PublicKey::System.to_account_hash(), - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => >::None, - }, + let fund_request = TransferRequestBuilder::new( + MINIMUM_ACCOUNT_CREATION_BALANCE, + PublicKey::System.to_account_hash(), ) .build(); - builder.exec(fund_request).expect_success().commit(); + builder.transfer_and_commit(fund_request).expect_success(); builder } @@ -269,17 +263,13 @@ fn should_retain_genesis_validator_slot_protection() { let mut builder = LmdbWasmTestBuilder::new_temporary_with_config(engine_config); builder.run_genesis(run_genesis_request); - let fund_request = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => PublicKey::System.to_account_hash(), - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => >::None, - }, + let fund_request = TransferRequestBuilder::new( + MINIMUM_ACCOUNT_CREATION_BALANCE, + PublicKey::System.to_account_hash(), ) .build(); - builder.exec(fund_request).expect_success().commit(); + builder.transfer_and_commit(fund_request).expect_success(); builder }; diff --git a/execution_engine_testing/tests/src/test/regression/gov_42.rs b/execution_engine_testing/tests/src/test/regression/gov_42.rs index 915fe16da7..3de9b90775 100644 --- a/execution_engine_testing/tests/src/test/regression/gov_42.rs +++ b/execution_engine_testing/tests/src/test/regression/gov_42.rs @@ -230,7 +230,7 @@ fn should_charge_session_with_incorrect_wasm_no_memory_section() { fn should_charge_payment_with_incorrect_wasm_start_section() { let wasm_bytes = make_module_with_start_section(); let execution_phase = ExecutionPhase::Payment; - let expected_error = "Unsupported WASM start"; + let expected_error = "Unsupported Wasm start"; run_test_case(&wasm_bytes, expected_error, execution_phase) } @@ -239,6 +239,6 @@ fn should_charge_payment_with_incorrect_wasm_start_section() { fn should_charge_session_with_incorrect_wasm_start_section() { let wasm_bytes = make_module_with_start_section(); let execution_phase = ExecutionPhase::Session; - let expected_error = "Unsupported WASM start"; + let expected_error = "Unsupported Wasm start"; run_test_case(&wasm_bytes, expected_error, execution_phase) } diff --git a/execution_engine_testing/tests/src/test/regression/regression_20210707.rs b/execution_engine_testing/tests/src/test/regression/regression_20210707.rs index 4bf5c6dce9..40de3688d7 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20210707.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20210707.rs @@ -1,10 +1,10 @@ use casper_engine_test_support::{ DeployItemBuilder, EntityWithNamedKeys, ExecuteRequestBuilder, LmdbWasmTestBuilder, - DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, - PRODUCTION_RUN_GENESIS_REQUEST, + TransferRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, + MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_execution_engine::engine_state::{Error as CoreError, ExecError, ExecuteRequest}; -use casper_storage::system::transfer::TransferError; +use casper_storage::{data_access_layer::TransferRequest, system::transfer::TransferError}; use casper_types::{ account::AccountHash, runtime_args, system::mint, AccessRights, AddressableEntityHash, PublicKey, RuntimeArgs, SecretKey, URef, U512, @@ -52,16 +52,10 @@ fn setup_regression_contract() -> ExecuteRequest { .build() } -fn transfer(sender: AccountHash, target: AccountHash, amount: u64) -> ExecuteRequest { - ExecuteRequestBuilder::transfer( - sender, - runtime_args! { - mint::ARG_TARGET => target, - mint::ARG_AMOUNT => U512::from(amount), - mint::ARG_ID => >::None, - }, - ) - .build() +fn transfer(sender: AccountHash, target: AccountHash, amount: u64) -> TransferRequest { + TransferRequestBuilder::new(amount, target) + .with_initiator(sender) + .build() } fn get_account_entity_hash(entity: &EntityWithNamedKeys) -> AddressableEntityHash { @@ -100,7 +94,7 @@ fn should_transfer_funds_from_contract_to_new_account() { ); builder.exec(store_request).commit().expect_success(); - builder.exec(fund_request).commit().expect_success(); + builder.transfer_and_commit(fund_request).expect_success(); let account = builder .get_entity_with_named_keys_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -146,8 +140,8 @@ fn should_transfer_funds_from_contract_to_existing_account() { ); builder.exec(store_request).commit().expect_success(); - builder.exec(fund_request_1).commit().expect_success(); - builder.exec(fund_request_2).commit().expect_success(); + builder.transfer_and_commit(fund_request_1).expect_success(); + builder.transfer_and_commit(fund_request_2).expect_success(); let account = builder .get_entity_with_named_keys_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -185,24 +179,16 @@ fn should_not_transfer_funds_from_forged_purse_to_account_native_transfer() { ); builder.exec(store_request).commit().expect_success(); - builder.exec(fund_request).commit().expect_success(); + builder.transfer_and_commit(fund_request).expect_success(); let take_from = builder.get_expected_addressable_entity_by_account_hash(*ALICE_ADDR); let alice_main_purse = take_from.main_purse(); - let transfer_request = { - let id: Option = None; - let transfer_args = runtime_args! { - mint::ARG_SOURCE => alice_main_purse, - mint::ARG_TARGET => *BOB_ADDR, - mint::ARG_AMOUNT => U512::from(700_000_000_000u64), - mint::ARG_ID => id, - }; - - ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args).build() - }; + let transfer_request = TransferRequestBuilder::new(700_000_000_000_u64, *BOB_ADDR) + .with_source(alice_main_purse) + .build(); - builder.exec(transfer_request).commit(); + builder.transfer_and_commit(transfer_request); let error = builder.get_error().expect("should have error"); @@ -236,8 +222,8 @@ fn should_not_transfer_funds_from_forged_purse_to_owned_purse() { ); builder.exec(store_request).commit().expect_success(); - builder.exec(fund_request_1).commit().expect_success(); - builder.exec(fund_request_2).commit().expect_success(); + builder.transfer_and_commit(fund_request_1).expect_success(); + builder.transfer_and_commit(fund_request_2).expect_success(); let account = builder .get_entity_with_named_keys_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -284,7 +270,7 @@ fn should_not_transfer_funds_into_bob_purse() { ); builder.exec(store_request).commit().expect_success(); - builder.exec(fund_request_1).commit().expect_success(); + builder.transfer_and_commit(fund_request_1).expect_success(); let account = builder .get_entity_with_named_keys_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -329,7 +315,7 @@ fn should_not_transfer_from_hardcoded_purse() { ); builder.exec(store_request).commit().expect_success(); - builder.exec(fund_request_1).commit().expect_success(); + builder.transfer_and_commit(fund_request_1).expect_success(); let account = builder .get_entity_with_named_keys_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -376,8 +362,8 @@ fn should_not_refund_to_bob_and_charge_alice() { ); builder.exec(store_request).commit().expect_success(); - builder.exec(fund_request_1).commit().expect_success(); - builder.exec(fund_request_2).commit().expect_success(); + builder.transfer_and_commit(fund_request_1).expect_success(); + builder.transfer_and_commit(fund_request_2).expect_success(); let account = builder .get_entity_with_named_keys_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -434,8 +420,8 @@ fn should_not_charge_alice_for_execution() { ); builder.exec(store_request).commit().expect_success(); - builder.exec(fund_request_1).commit().expect_success(); - builder.exec(fund_request_2).commit().expect_success(); + builder.transfer_and_commit(fund_request_1).expect_success(); + builder.transfer_and_commit(fund_request_2).expect_success(); let account = builder .get_entity_with_named_keys_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -492,8 +478,8 @@ fn should_not_charge_for_execution_from_hardcoded_purse() { ); builder.exec(store_request).commit().expect_success(); - builder.exec(fund_request_1).commit().expect_success(); - builder.exec(fund_request_2).commit().expect_success(); + builder.transfer_and_commit(fund_request_1).expect_success(); + builder.transfer_and_commit(fund_request_2).expect_success(); let account = builder .get_entity_with_named_keys_by_account_hash(*DEFAULT_ACCOUNT_ADDR) diff --git a/execution_engine_testing/tests/src/test/regression/regression_20210831.rs b/execution_engine_testing/tests/src/test/regression/regression_20210831.rs index 439091098e..83a510ee1c 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20210831.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20210831.rs @@ -1,8 +1,8 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, - MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, DEFAULT_ACCOUNT_ADDR, + DEFAULT_ACCOUNT_PUBLIC_KEY, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_execution_engine::{ engine_state::{engine_config::DEFAULT_MINIMUM_DELEGATION_AMOUNT, Error as CoreError}, @@ -11,10 +11,7 @@ use casper_execution_engine::{ use casper_types::{ account::AccountHash, runtime_args, - system::{ - auction::{self, BidsExt, DelegationRate}, - mint, - }, + system::auction::{self, BidsExt, DelegationRate}, ApiError, PublicKey, RuntimeArgs, SecretKey, U512, }; @@ -49,57 +46,37 @@ fn setup() -> LmdbWasmTestBuilder { builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); - let id: Option = None; - - let transfer_args_1 = runtime_args! { - mint::ARG_TARGET => *ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => id, - }; - let transfer_request_1 = - ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args_1).build(); - - builder.exec(transfer_request_1).expect_success().commit(); + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, *ACCOUNT_1_ADDR).build(); - let transfer_args_2 = runtime_args! { - mint::ARG_TARGET => *ACCOUNT_2_ADDR, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => id, - }; + builder + .transfer_and_commit(transfer_request_1) + .expect_success(); let transfer_request_2 = - ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args_2).build(); + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, *ACCOUNT_2_ADDR).build(); - builder.exec(transfer_request_2).expect_success().commit(); + builder + .transfer_and_commit(transfer_request_2) + .expect_success(); let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); - let id: Option = None; - - let transfer_args_1 = runtime_args! { - mint::ARG_TARGET => *ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => id, - }; - let transfer_request_1 = - ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args_1).build(); - - builder.exec(transfer_request_1).expect_success().commit(); + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, *ACCOUNT_1_ADDR).build(); - let transfer_args_2 = runtime_args! { - mint::ARG_TARGET => *ACCOUNT_2_ADDR, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => id, - }; + builder + .transfer_and_commit(transfer_request_1) + .expect_success(); let transfer_request_2 = - ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args_2).build(); + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, *ACCOUNT_2_ADDR).build(); - builder.exec(transfer_request_2).expect_success().commit(); + builder + .transfer_and_commit(transfer_request_2) + .expect_success(); let install_request_1 = ExecuteRequestBuilder::standard( *ACCOUNT_2_ADDR, diff --git a/execution_engine_testing/tests/src/test/regression/regression_20211110.rs b/execution_engine_testing/tests/src/test/regression/regression_20211110.rs index 4a2877fa8f..46770e8576 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20211110.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20211110.rs @@ -1,13 +1,10 @@ use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, + DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state::Error as CoreError, execution::Error as ExecError}; use casper_types::{ - account::AccountHash, - runtime_args, - system::{mint, standard_payment}, - AddressableEntityHash, Key, U512, + account::AccountHash, runtime_args, system::standard_payment, AddressableEntityHash, Key, U512, }; const RECURSE_ENTRYPOINT: &str = "recurse"; @@ -27,15 +24,7 @@ fn regression_20211110() { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); - let transfer_request = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => U512::from(funds), - mint::ARG_ID => Option::::None - }, - ) - .build(); + let transfer_request = TransferRequestBuilder::new(funds, ACCOUNT_1_ADDR).build(); let install_request = { let session_args = runtime_args! {}; @@ -53,7 +42,9 @@ fn regression_20211110() { ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; - builder.exec(transfer_request).expect_success().commit(); + builder + .transfer_and_commit(transfer_request) + .expect_success(); builder.exec(install_request).expect_success().commit(); funds = funds.checked_sub(INSTALL_COST).unwrap(); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220217.rs b/execution_engine_testing/tests/src/test/regression/regression_20220217.rs index 7f607a88f4..f579a4349a 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220217.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220217.rs @@ -1,5 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, + ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, DEFAULT_ACCOUNT_ADDR, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state, execution}; @@ -258,15 +258,8 @@ fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); - let fund_account_1_request = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => >::None, - }, - ) - .build(); + let fund_account_1_request = + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, ACCOUNT_1_ADDR).build(); let fund_purse_1_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, TRANSFER_TO_NAMED_PURSE_CONTRACT, @@ -296,9 +289,8 @@ fn setup() -> LmdbWasmTestBuilder { .build(); builder - .exec(fund_account_1_request) - .expect_success() - .commit(); + .transfer_and_commit(fund_account_1_request) + .expect_success(); builder.exec(fund_purse_1_request).expect_success().commit(); builder.exec(fund_purse_2_request).expect_success().commit(); builder.exec(fund_purse_3_request).expect_success().commit(); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220221.rs b/execution_engine_testing/tests/src/test/regression/regression_20220221.rs index 1c018d2199..d62f2a79d6 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220221.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220221.rs @@ -1,18 +1,15 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, StepRequestBuilder, UpgradeRequestBuilder, - DEFAULT_ACCOUNT_ADDR, DEFAULT_AUCTION_DELAY, DEFAULT_GENESIS_TIMESTAMP_MILLIS, + ExecuteRequestBuilder, LmdbWasmTestBuilder, StepRequestBuilder, TransferRequestBuilder, + UpgradeRequestBuilder, DEFAULT_AUCTION_DELAY, DEFAULT_GENESIS_TIMESTAMP_MILLIS, DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, DEFAULT_PROTOCOL_VERSION, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, TIMESTAMP_MILLIS_INCREMENT, }; use casper_execution_engine::engine_state::DEFAULT_MAX_RUNTIME_CALL_STACK_HEIGHT; use casper_types::{ runtime_args, - system::{ - auction::{self, DelegationRate, INITIAL_ERA_ID}, - mint, - }, + system::auction::{self, DelegationRate, INITIAL_ERA_ID}, EraId, ProtocolVersion, PublicKey, SecretKey, U256, U512, }; @@ -50,15 +47,8 @@ fn regression_20220221_should_distribute_to_many_validators() { let mut public_keys = generate_public_keys(); - let fund_request = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => PublicKey::System, - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - mint::ARG_ID => >::None, - }, - ) - .build(); + let fund_request = + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, PublicKey::System).build(); let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); @@ -73,23 +63,21 @@ fn regression_20220221_should_distribute_to_many_validators() { builder.upgrade_with_upgrade_request_and_config(None, &mut upgrade_request); - builder.exec(fund_request).expect_success().commit(); + builder.transfer_and_commit(fund_request).expect_success(); // Add validators for _ in 0..DEFAULT_MAX_RUNTIME_CALL_STACK_HEIGHT { let public_key = public_keys.next().unwrap(); - let transfer_request = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => public_key.to_account_hash(), - mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE / 10), - mint::ARG_ID => >::None, - }, + let transfer_request = TransferRequestBuilder::new( + MINIMUM_ACCOUNT_CREATION_BALANCE / 10, + public_key.to_account_hash(), ) .build(); - builder.exec(transfer_request).commit().expect_success(); + builder + .transfer_and_commit(transfer_request) + .expect_success(); let delegation_rate: DelegationRate = 10; diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220222.rs b/execution_engine_testing/tests/src/test/regression/regression_20220222.rs index 5af4c4e7d1..e539c27f4e 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220222.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220222.rs @@ -1,5 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, + ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, DEFAULT_ACCOUNT_ADDR, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state, execution}; @@ -13,17 +13,12 @@ fn regression_20220222_escalate() { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); - let transfer_request = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - "target" => ALICE_ADDR, - "amount" => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), - "id" => >::None, - }, - ) - .build(); + let transfer_request = + TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, ALICE_ADDR).build(); - builder.exec(transfer_request).commit().expect_success(); + builder + .transfer_and_commit(transfer_request) + .expect_success(); let alice = builder .get_entity_by_account_hash(ALICE_ADDR) diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs b/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs index bc82ad009d..2995b8dcbd 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs @@ -1,11 +1,12 @@ use num_traits::Zero; use casper_engine_test_support::{ - utils, ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNTS, - DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, DEFAULT_GENESIS_TIMESTAMP_MILLIS, - DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, DEFAULT_PAYMENT, DEFAULT_PROPOSER_PUBLIC_KEY, - DEFAULT_PROTOCOL_VERSION, DEFAULT_UNBONDING_DELAY, MINIMUM_ACCOUNT_CREATION_BALANCE, - PRODUCTION_RUN_GENESIS_REQUEST, SYSTEM_ADDR, TIMESTAMP_MILLIS_INCREMENT, + utils, ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, + UpgradeRequestBuilder, DEFAULT_ACCOUNTS, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, + DEFAULT_GENESIS_TIMESTAMP_MILLIS, DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, DEFAULT_PAYMENT, + DEFAULT_PROPOSER_PUBLIC_KEY, DEFAULT_PROTOCOL_VERSION, DEFAULT_UNBONDING_DELAY, + MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, SYSTEM_ADDR, + TIMESTAMP_MILLIS_INCREMENT, }; use casper_execution_engine::{engine_state::Error as EngineError, execution::Error}; @@ -200,15 +201,11 @@ fn should_fail_bonding_with_insufficient_funds_directly() { builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); - let transfer_args = runtime_args! { - mint::ARG_TARGET => new_validator_hash, - mint::ARG_AMOUNT => transfer_amount, - mint::ARG_ID => Some(1u64), - }; - let exec_request = - ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args).build(); + let exec_request = TransferRequestBuilder::new(transfer_amount, new_validator_hash) + .with_transfer_id(1) + .build(); - builder.exec(exec_request).expect_success().commit(); + builder.transfer_and_commit(exec_request).expect_success(); let new_validator_account = builder .get_entity_by_account_hash(new_validator_hash) diff --git a/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs b/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs index 4881bc6721..673e6065f1 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs @@ -34,7 +34,7 @@ fn should_raise_insufficient_payment_when_caller_lacks_minimum_balance() { TRANSFER_PURSE_TO_ACCOUNT_WASM, runtime_args! { ARG_TARGET => account_1_account_hash, ARG_AMOUNT => *MAX_PAYMENT - U512::one() }, ) - .build(); + .build(); let mut builder = LmdbWasmTestBuilder::default(); @@ -57,7 +57,7 @@ fn should_raise_insufficient_payment_when_caller_lacks_minimum_balance() { .expect("there should be a response"); assert!( - error_message.contains("InsufficientPayment"), + error_message.contains("Insufficient payment"), "expected insufficient payment, got: {}", error_message ); @@ -85,7 +85,7 @@ fn should_forward_payment_execution_runtime_error() { .with_payment_code(REVERT_WASM, RuntimeArgs::default()) .with_session_code( TRANSFER_PURSE_TO_ACCOUNT_WASM, - runtime_args! { ARG_TARGET => account_1_account_hash, ARG_AMOUNT => transferred_amount } + runtime_args! { ARG_TARGET => account_1_account_hash, ARG_AMOUNT => transferred_amount }, ) .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .build(); @@ -157,7 +157,7 @@ fn should_forward_payment_execution_gas_limit_error() { .with_payment_code(ENDLESS_LOOP_WASM, RuntimeArgs::default()) .with_session_code( TRANSFER_PURSE_TO_ACCOUNT_WASM, - runtime_args! { ARG_TARGET => account_1_account_hash, ARG_AMOUNT => transferred_amount } + runtime_args! { ARG_TARGET => account_1_account_hash, ARG_AMOUNT => transferred_amount }, ) .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .build(); diff --git a/execution_engine_testing/tests/src/test/upgrade.rs b/execution_engine_testing/tests/src/test/upgrade.rs index 9d54094a93..c97a855937 100644 --- a/execution_engine_testing/tests/src/test/upgrade.rs +++ b/execution_engine_testing/tests/src/test/upgrade.rs @@ -1,16 +1,14 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, - MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, UpgradeRequestBuilder, + DEFAULT_ACCOUNT_ADDR, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state, execution::Error}; use casper_types::{ account::AccountHash, addressable_entity::{AssociatedKeys, Weight}, - runtime_args, - system::mint, - AddressableEntityHash, CLValue, EntityVersion, EraId, PackageHash, ProtocolVersion, - RuntimeArgs, StoredValue, ENTITY_INITIAL_VERSION, + runtime_args, AddressableEntityHash, CLValue, EntityVersion, EraId, PackageHash, + ProtocolVersion, RuntimeArgs, StoredValue, ENTITY_INITIAL_VERSION, }; const DO_NOTHING_STORED_CONTRACT_NAME: &str = "do_nothing_stored"; @@ -868,17 +866,11 @@ fn setup_upgrade_threshold_state() -> (LmdbWasmTestBuilder, AccountHash) { ) .expect_upgrade_success(); - let transfer = ExecuteRequestBuilder::transfer( - *DEFAULT_ACCOUNT_ADDR, - runtime_args! { - mint::ARG_TARGET => ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE, - mint::ARG_ID => Some(42u64), - }, - ) - .build(); + let transfer = TransferRequestBuilder::new(MINIMUM_ACCOUNT_CREATION_BALANCE, ACCOUNT_1_ADDR) + .with_transfer_id(42) + .build(); - builder.exec(transfer).expect_success().commit(); + builder.transfer_and_commit(transfer).expect_success(); (builder, ACCOUNT_1_ADDR) } diff --git a/execution_engine_testing/tests/src/test/wasmless_transfer.rs b/execution_engine_testing/tests/src/test/wasmless_transfer.rs index 1839397fab..08f8c23bbb 100644 --- a/execution_engine_testing/tests/src/test/wasmless_transfer.rs +++ b/execution_engine_testing/tests/src/test/wasmless_transfer.rs @@ -1,7 +1,7 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, + ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_MAX_ASSOCIATED_KEYS, DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, PRODUCTION_RUN_GENESIS_REQUEST, }; @@ -26,15 +26,17 @@ const TEST_PURSE_NAME: &str = "test_purse"; const ARG_PURSE_NAME: &str = "purse_name"; const ARG_UREF_NAME: &str = "uref_name"; -static ACCOUNT_1_SK: Lazy = +static ACCOUNT_1_SECRET_KEY: Lazy = Lazy::new(|| SecretKey::secp256k1_from_bytes([234u8; 32]).unwrap()); -static ACCOUNT_1_PK: Lazy = Lazy::new(|| PublicKey::from(&*ACCOUNT_1_SK)); -static ACCOUNT_1_ADDR: Lazy = Lazy::new(|| ACCOUNT_1_PK.to_account_hash()); +static ACCOUNT_1_PUBLIC_KEY: Lazy = + Lazy::new(|| PublicKey::from(&*ACCOUNT_1_SECRET_KEY)); +static ACCOUNT_1_ADDR: Lazy = Lazy::new(|| ACCOUNT_1_PUBLIC_KEY.to_account_hash()); -static ACCOUNT_2_SK: Lazy = +static ACCOUNT_2_SECRET_KEY: Lazy = Lazy::new(|| SecretKey::secp256k1_from_bytes([210u8; 32]).unwrap()); -static ACCOUNT_2_PK: Lazy = Lazy::new(|| PublicKey::from(&*ACCOUNT_2_SK)); -static ACCOUNT_2_ADDR: Lazy = Lazy::new(|| ACCOUNT_2_PK.to_account_hash()); +static ACCOUNT_2_PUBLIC_KEY: Lazy = + Lazy::new(|| PublicKey::from(&*ACCOUNT_2_SECRET_KEY)); +static ACCOUNT_2_ADDR: Lazy = Lazy::new(|| ACCOUNT_2_PUBLIC_KEY.to_account_hash()); #[ignore] #[test] @@ -124,7 +126,7 @@ fn transfer_wasmless(wasmless_transfer: WasmlessTransfer) { } WasmlessTransfer::AccountMainPurseToPublicKeyMainPurse => { runtime_args! { - mint::ARG_TARGET => ACCOUNT_2_PK.clone(), + mint::ARG_TARGET => ACCOUNT_2_PUBLIC_KEY.clone(), mint::ARG_AMOUNT => transfer_amount, mint::ARG_ID => id } @@ -147,7 +149,7 @@ fn transfer_wasmless(wasmless_transfer: WasmlessTransfer) { WasmlessTransfer::PurseToPublicKey => { runtime_args! { mint::ARG_SOURCE => account_1_purse, - mint::ARG_TARGET => ACCOUNT_2_PK.clone(), + mint::ARG_TARGET => ACCOUNT_2_PUBLIC_KEY.clone(), mint::ARG_AMOUNT => transfer_amount, mint::ARG_ID => id } @@ -162,21 +164,14 @@ fn transfer_wasmless(wasmless_transfer: WasmlessTransfer) { } }; - let no_wasm_transfer_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*ACCOUNT_1_ADDR) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(runtime_args) - .with_authorization_keys(&[*ACCOUNT_1_ADDR]) - .with_deploy_hash([42; 32]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let no_wasm_transfer_request = TransferRequestBuilder::new(0, AccountHash::default()) + .with_args(runtime_args) + .with_initiator(*ACCOUNT_1_ADDR) + .build(); builder - .exec(no_wasm_transfer_request) - .expect_success() - .commit(); + .transfer_and_commit(no_wasm_transfer_request) + .expect_success(); let wasmless_transfer_gas_cost = Gas::from(DEFAULT_WASMLESS_TRANSFER_COST); let wasmless_transfer_cost = Motes::from_gas( @@ -498,16 +493,10 @@ fn invalid_transfer_wasmless(invalid_wasmless_transfer: InvalidWasmlessTransfer) } }; - let no_wasm_transfer_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(addr) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(runtime_args) - .with_authorization_keys(&[addr]) - .with_deploy_hash([42; 32]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let no_wasm_transfer_request = TransferRequestBuilder::new(0, AccountHash::default()) + .with_args(runtime_args) + .with_initiator(addr) + .build(); let account_1_purse = builder .get_entity_by_account_hash(*ACCOUNT_1_ADDR) @@ -516,7 +505,7 @@ fn invalid_transfer_wasmless(invalid_wasmless_transfer: InvalidWasmlessTransfer) let account_1_starting_balance = builder.get_purse_balance(account_1_purse); - builder.exec(no_wasm_transfer_request); + builder.transfer_and_commit(no_wasm_transfer_request); let result = builder .get_last_exec_result() @@ -580,27 +569,13 @@ fn transfer_wasmless_should_create_target_if_it_doesnt_exist() { let account_1_starting_balance = builder.get_purse_balance(account_1_purse); - let runtime_args = runtime_args! { - mint::ARG_TARGET => *ACCOUNT_2_ADDR, - mint::ARG_AMOUNT => transfer_amount, - mint::ARG_ID => >::None - }; - - let no_wasm_transfer_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*ACCOUNT_1_ADDR) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(runtime_args) - .with_authorization_keys(&[*ACCOUNT_1_ADDR]) - .with_deploy_hash([42; 32]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let no_wasm_transfer_request = TransferRequestBuilder::new(transfer_amount, *ACCOUNT_2_ADDR) + .with_initiator(*ACCOUNT_1_ADDR) + .build(); builder - .exec(no_wasm_transfer_request) - .expect_success() - .commit(); + .transfer_and_commit(no_wasm_transfer_request) + .expect_success(); let account_2 = builder .get_entity_by_account_hash(*ACCOUNT_2_ADDR) @@ -719,27 +694,14 @@ fn transfer_wasmless_should_fail_without_main_purse_minimum_balance() { let account_1_starting_balance = builder.get_purse_balance(account_1_purse); - let runtime_args = runtime_args! { - mint::ARG_TARGET => *ACCOUNT_2_ADDR, - mint::ARG_AMOUNT => account_1_to_account_2_amount, - mint::ARG_ID => >::None - }; - - let no_wasm_transfer_request_1 = { - let deploy_item = DeployItemBuilder::new() - .with_address(*ACCOUNT_1_ADDR) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(runtime_args) - .with_authorization_keys(&[*ACCOUNT_1_ADDR]) - .with_deploy_hash([42; 32]) + let no_wasm_transfer_request_1 = + TransferRequestBuilder::new(account_1_to_account_2_amount, *ACCOUNT_2_ADDR) + .with_initiator(*ACCOUNT_1_ADDR) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; builder - .exec(no_wasm_transfer_request_1) - .expect_success() - .commit(); + .transfer_and_commit(no_wasm_transfer_request_1) + .expect_success(); let account_2 = builder .get_entity_by_account_hash(*ACCOUNT_2_ADDR) @@ -758,24 +720,12 @@ fn transfer_wasmless_should_fail_without_main_purse_minimum_balance() { ); // Another transfer but this time created account tries to do a transfer - let runtime_args = runtime_args! { - mint::ARG_TARGET => *ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => account_2_to_account_1_amount, - mint::ARG_ID => >::None - }; - - let no_wasm_transfer_request_2 = { - let deploy_item = DeployItemBuilder::new() - .with_address(*ACCOUNT_2_ADDR) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(runtime_args) - .with_authorization_keys(&[*ACCOUNT_2_ADDR]) - .with_deploy_hash([43; 32]) + let no_wasm_transfer_request_2 = + TransferRequestBuilder::new(account_2_to_account_1_amount, *ACCOUNT_1_ADDR) + .with_initiator(*ACCOUNT_2_ADDR) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; - builder.exec(no_wasm_transfer_request_2).commit(); + builder.transfer_and_commit(no_wasm_transfer_request_2); // TODO: reenable when new payment code is added // let exec_result = &builder.get_last_exec_result().unwrap()[0]; // let error = exec_result @@ -818,27 +768,14 @@ fn transfer_wasmless_should_transfer_funds_after_paying_for_transfer() { let account_1_starting_balance = builder.get_purse_balance(account_1_purse); - let runtime_args = runtime_args! { - mint::ARG_TARGET => *ACCOUNT_2_ADDR, - mint::ARG_AMOUNT => account_1_to_account_2_amount, - mint::ARG_ID => >::None - }; - - let no_wasm_transfer_request_1 = { - let deploy_item = DeployItemBuilder::new() - .with_address(*ACCOUNT_1_ADDR) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(runtime_args) - .with_authorization_keys(&[*ACCOUNT_1_ADDR]) - .with_deploy_hash([42; 32]) + let no_wasm_transfer_request_1 = + TransferRequestBuilder::new(account_1_to_account_2_amount, *ACCOUNT_2_ADDR) + .with_initiator(*ACCOUNT_1_ADDR) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; builder - .exec(no_wasm_transfer_request_1) - .expect_success() - .commit(); + .transfer_and_commit(no_wasm_transfer_request_1) + .expect_success(); let account_2 = builder .get_entity_by_account_hash(*ACCOUNT_2_ADDR) @@ -857,26 +794,13 @@ fn transfer_wasmless_should_transfer_funds_after_paying_for_transfer() { ); // Another transfer but this time created account tries to do a transfer - let runtime_args = runtime_args! { - mint::ARG_TARGET => *ACCOUNT_1_ADDR, - mint::ARG_AMOUNT => account_2_to_account_1_amount, - mint::ARG_ID => >::None - }; - - let no_wasm_transfer_request_2 = { - let deploy_item = DeployItemBuilder::new() - .with_address(*ACCOUNT_2_ADDR) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(runtime_args) - .with_authorization_keys(&[*ACCOUNT_2_ADDR]) - .with_deploy_hash([43; 32]) + let no_wasm_transfer_request_2 = + TransferRequestBuilder::new(account_2_to_account_1_amount, *ACCOUNT_1_ADDR) + .with_initiator(*ACCOUNT_2_ADDR) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; builder - .exec(no_wasm_transfer_request_2) - .commit() + .transfer_and_commit(no_wasm_transfer_request_2) .expect_success(); } @@ -911,25 +835,13 @@ fn transfer_wasmless_should_fail_with_secondary_purse_insufficient_funds() { let account_1_starting_balance = builder.get_purse_balance(account_1_purse); assert_eq!(account_1_starting_balance, U512::zero()); - let runtime_args = runtime_args! { - mint::ARG_SOURCE => account_1_purse, - mint::ARG_TARGET => *ACCOUNT_2_ADDR, - mint::ARG_AMOUNT => account_1_to_account_2_amount, - mint::ARG_ID => >::None - }; - - let no_wasm_transfer_request_1 = { - let deploy_item = DeployItemBuilder::new() - .with_address(*ACCOUNT_1_ADDR) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(runtime_args) - .with_authorization_keys(&[*ACCOUNT_1_ADDR]) - .with_deploy_hash([42; 32]) + let no_wasm_transfer_request_1 = + TransferRequestBuilder::new(account_1_to_account_2_amount, *ACCOUNT_2_ADDR) + .with_source(account_1_purse) + .with_initiator(*ACCOUNT_1_ADDR) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; - builder.exec(no_wasm_transfer_request_1).commit(); + builder.transfer_and_commit(no_wasm_transfer_request_1); //TODO: reenable when new payment code is added // let exec_result = &builder.get_last_exec_result().unwrap()[0]; // let error = exec_result.as_error().expect("should have error"); @@ -1001,27 +913,12 @@ fn transfer_wasmless_should_observe_upgraded_cost() { let default_account_balance_before = builder.get_purse_balance(default_account.main_purse()); - let no_wasm_transfer_request_1 = { - let wasmless_transfer_args = runtime_args! { - mint::ARG_TARGET => *ACCOUNT_2_ADDR, - mint::ARG_AMOUNT => transfer_amount, - mint::ARG_ID => >::None - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! {}) - .with_transfer_args(wasmless_transfer_args) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([42; 32]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let no_wasm_transfer_request_1 = + TransferRequestBuilder::new(transfer_amount, *ACCOUNT_2_ADDR).build(); builder - .exec(no_wasm_transfer_request_1) - .expect_success() - .commit(); + .transfer_and_commit(no_wasm_transfer_request_1) + .expect_success(); let default_account_balance_after = builder.get_purse_balance(default_account.main_purse()); diff --git a/node/src/components/contract_runtime.rs b/node/src/components/contract_runtime.rs index a2328461a8..40e9aa4860 100644 --- a/node/src/components/contract_runtime.rs +++ b/node/src/components/contract_runtime.rs @@ -42,7 +42,9 @@ use casper_storage::{ system::{genesis::GenesisError, protocol_upgrade::ProtocolUpgradeError}, tracking_copy::TrackingCopyError, }; -use casper_types::{Chainspec, ChainspecRawBytes, ChainspecRegistry, ProtocolUpgradeConfig}; +use casper_types::{ + Chainspec, ChainspecRawBytes, ChainspecRegistry, ProtocolUpgradeConfig, PublicKey, +}; use crate::{ components::{fetcher::FetchResponse, Component, ComponentState}, @@ -61,7 +63,9 @@ use crate::{ NodeRng, }; pub(crate) use config::Config; -pub(crate) use error::{BlockExecutionError, ConfigError, ContractRuntimeError}; +pub(crate) use error::{ + BlockExecutionError, ConfigError, ContractRuntimeError, NewUserRequestError, +}; pub(crate) use event::Event; use exec_queue::{ExecQueue, QueueItem}; use metrics::Metrics; @@ -565,11 +569,24 @@ impl ContractRuntime { responder, } => { let engine_state = Arc::clone(&self.engine_state); + let administrative_accounts = self + .chainspec + .core_config + .administrators + .iter() + .map(PublicKey::to_account_hash) + .collect(); + let allow_unrestricted_transfers = + self.chainspec.core_config.allow_unrestricted_transfers; + let system_costs = self.chainspec.system_costs_config; async move { let result = run_intensive_task(move || { speculatively_execute( engine_state.as_ref(), execution_prestate, + administrative_accounts, + allow_unrestricted_transfers, + system_costs, *transaction, ) }) diff --git a/node/src/components/contract_runtime/error.rs b/node/src/components/contract_runtime/error.rs index 570b6be3ef..c503305711 100644 --- a/node/src/components/contract_runtime/error.rs +++ b/node/src/components/contract_runtime/error.rs @@ -6,12 +6,12 @@ use serde::Serialize; use thiserror::Error; use casper_execution_engine::engine_state::{ - Error as EngineStateError, NewRequestError, StepError, + Error as EngineStateError, NewRequestError as NewExecuteRequestError, StepError, }; use casper_storage::{ global_state::error::Error as GlobalStateError, tracking_copy::TrackingCopyError, }; -use casper_types::{bytesrepr, CLValueError, Digest, PublicKey, U512}; +use casper_types::{bytesrepr, CLValueError, Digest, PublicKey, TransactionHash, U512}; use crate::{ components::contract_runtime::ExecutionPreState, @@ -43,6 +43,20 @@ pub(crate) enum ContractRuntimeError { ChunkingError(#[source] ChunkingError), } +/// Error returned if constructing a new user request fails. +#[derive(Copy, Clone, Eq, PartialEq, Error, Serialize, Debug)] +pub enum NewUserRequestError { + /// The transaction is a native one, but the wrapped deploy is not a transfer. + #[error("native transaction of deploy variant is not a transfer")] + ExpectedNativeTransferDeploy(TransactionHash), + /// The transaction is a native version 1 variant, but has a custom entry point. + #[error("cannot use custom variant for entry point in native transaction v1 {0}")] + InvalidEntryPoint(TransactionHash), + /// Error constructing a new execution request. + #[error(transparent)] + Execute(#[from] NewExecuteRequestError), +} + /// An error during block execution. #[derive(Debug, Error, Serialize)] pub enum BlockExecutionError { @@ -119,9 +133,5 @@ pub enum BlockExecutionError { RootNotFound(Digest), /// An error that occurred while constructing the execution request. #[error(transparent)] - NewRequest( - #[from] - #[serde(skip_serializing)] - NewRequestError, - ), + NewRequest(#[from] NewUserRequestError), } diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index a4edf18e1b..c5f5fa1ede 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -1,4 +1,9 @@ -use std::{collections::BTreeMap, convert::TryInto, sync::Arc, time::Instant}; +use std::{ + collections::{BTreeMap, BTreeSet}, + convert::TryInto, + sync::Arc, + time::Instant, +}; use itertools::Itertools; use tracing::{debug, error, info, trace, warn}; @@ -11,33 +16,31 @@ use casper_execution_engine::engine_state::{ use casper_storage::{ data_access_layer::{ transfer::TransferConfig, DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, - TransferRequest, + TransferRequest, TransferResult, }, global_state::state::{lmdb::LmdbGlobalState, CommitProvider, StateProvider, StateReader}, }; -// use casper_storage::global_state::error::Error as GlobalStateError; use casper_types::{ + account::AccountHash, bytesrepr::{self, ToBytes, U32_SERIALIZED_LENGTH}, contract_messages::Messages, execution::{Effects, ExecutionResult, ExecutionResultV2, Transform, TransformKind}, - BlockTime, BlockV2, CLValue, ChecksumRegistry, Digest, EraEndV2, EraId, Gas, InitiatorAddr, - Key, ProtocolVersion, PublicKey, Transaction, TransactionHash, TransactionHeader, U512, + BlockTime, BlockV2, CLValue, ChecksumRegistry, Digest, EraEndV2, EraId, Gas, Key, + ProtocolVersion, PublicKey, SystemConfig, Transaction, TransactionEntryPoint, TransactionHash, + TransactionHeader, U512, }; use crate::{ - components::{ - contract_runtime::{ - error::BlockExecutionError, types::StepEffectsAndUpcomingEraValidators, - BlockAndExecutionResults, ExecutionPreState, Metrics, SpeculativeExecutionError, - SpeculativeExecutionState, APPROVALS_CHECKSUM_NAME, EXECUTION_RESULTS_CHECKSUM_NAME, - }, - fetcher::FetchItem, - }, - contract_runtime::utils::calculate_prune_eras, + components::fetcher::FetchItem, types::{self, ApprovalsHashes, Chunkable, ExecutableBlock, InternalEraReport}, }; -use super::ExecutionArtifact; +use super::{ + utils::calculate_prune_eras, BlockAndExecutionResults, BlockExecutionError, ExecutionArtifact, + ExecutionPreState, Metrics, NewUserRequestError, SpeculativeExecutionError, + SpeculativeExecutionState, StepEffectsAndUpcomingEraValidators, APPROVALS_CHECKSUM_NAME, + EXECUTION_RESULTS_CHECKSUM_NAME, +}; /// Executes a finalized block. #[allow(clippy::too_many_arguments)] @@ -51,6 +54,9 @@ pub fn execute_finalized_block( activation_point_era_id: EraId, key_block_height_for_activation_point: u64, prune_batch_size: u64, + administrative_accounts: &BTreeSet, + allow_unrestricted_transfers: bool, + system_costs: SystemConfig, ) -> Result { if executable_block.height != execution_pre_state.next_block_height() { return Err(BlockExecutionError::WrongBlockHeight { @@ -68,7 +74,7 @@ pub fn execute_finalized_block( let mut execution_results: Vec = Vec::with_capacity(executable_block.transactions.len()); // Run any transactions that must be executed - let block_time = executable_block.timestamp.millis(); + let block_time = BlockTime::new(executable_block.timestamp.millis()); let start = Instant::now(); let txn_ids = executable_block .transactions @@ -93,97 +99,70 @@ pub fn execute_finalized_block( )?; } - for transaction in executable_block.transactions { - let (txn_hash, txn) = match transaction { - Transaction::Deploy(deploy) => { - let deploy_hash = *deploy.hash(); - let txn_hash = TransactionHash::Deploy(deploy_hash); - if deploy.is_transfer() { - // native transfers are routed to the data provider - let authorization_keys = deploy - .approvals() - .iter() - .map(|approval| approval.signer().to_account_hash()) - .collect(); - let transfer_req = TransferRequest::with_runtime_args( - TransferConfig::Unadministered, /* TODO: check chainspec & handle - * administered possibility */ - state_root_hash, - block_time, - protocol_version, - PublicKey::clone(&executable_block.proposer), - txn_hash, - InitiatorAddr::PublicKey(deploy.header().account().clone()), - authorization_keys, - deploy.session().args().clone(), - Gas::zero(), /* <-- this should be the native transfer cost from the - * chainspec */ - ); - // native transfer auto-commits - let transfer_result = data_access_layer.transfer(transfer_req); - trace!(%txn_hash, ?transfer_result, "native transfer result"); - match EngineExecutionResult::from_transfer_result(transfer_result, Gas::zero()) - { - Err(_) => return Err(BlockExecutionError::RootNotFound(state_root_hash)), - Ok(exec_result) => { - let ExecutionResultAndMessages { - execution_result, - messages, - } = ExecutionResultAndMessages::from(exec_result); - let versioned_execution_result = - ExecutionResult::from(execution_result); - execution_results.push(ExecutionArtifact::new( - txn_hash, - TransactionHeader::Deploy(deploy.header().clone()), - versioned_execution_result, - messages, - )); - } - } - continue; - } - ( - TransactionHash::Deploy(deploy_hash), - Transaction::Deploy(deploy), - ) - } - txn @ Transaction::V1(_) => (txn.hash(), txn), - }; - - if txn.is_native() { - todo!("route native transactions to data access layer"); - } - + for txn in executable_block.transactions { + let txn_hash = txn.hash(); let txn_header = match &txn { Transaction::Deploy(deploy) => TransactionHeader::from(deploy.header().clone()), Transaction::V1(v1_txn) => TransactionHeader::from(v1_txn.header().clone()), }; - let execute_request = ExecuteRequest::new( + + let request = UserRequest::new( state_root_hash, - BlockTime::new(block_time), + block_time, + protocol_version, txn, (*executable_block.proposer).clone(), + administrative_accounts.clone(), + allow_unrestricted_transfers, + &system_costs, )?; - let exec_result_and_msgs = execute(&scratch_state, metrics.clone(), execute_request)?; - - trace!(%txn_hash, ?exec_result_and_msgs, "transaction execution result"); - // As for now a given state is expected to exist. - let new_state_root_hash = commit_execution_result( - &scratch_state, - // data_access_layer, - metrics.clone(), - state_root_hash, - txn_hash, - &exec_result_and_msgs.execution_result, - )?; - execution_results.push(ExecutionArtifact::new( - txn_hash, - txn_header, - ExecutionResult::from(exec_result_and_msgs.execution_result), - exec_result_and_msgs.messages, - )); - state_root_hash = new_state_root_hash; + match request { + UserRequest::Execute(execute_request) => { + let exec_result_and_msgs = + execute(&scratch_state, metrics.clone(), execute_request)?; + + trace!(%txn_hash, ?exec_result_and_msgs, "transaction execution result"); + // As for now a given state is expected to exist. + let new_state_root_hash = commit_execution_result( + &scratch_state, + // data_access_layer, + metrics.clone(), + state_root_hash, + txn_hash, + &exec_result_and_msgs.execution_result, + )?; + execution_results.push(ExecutionArtifact::new( + txn_hash, + txn_header, + ExecutionResult::from(exec_result_and_msgs.execution_result), + exec_result_and_msgs.messages, + )); + state_root_hash = new_state_root_hash; + } + UserRequest::Transfer(transfer_request) => { + let gas = transfer_request.gas(); + // native transfer auto-commits + let transfer_result = data_access_layer.transfer(transfer_request); + if let TransferResult::Success { + post_state_hash, .. + } = &transfer_result + { + state_root_hash = *post_state_hash; + } + trace!(%txn_hash, ?transfer_result, "native transfer result"); + let Ok(exec_result) = EngineExecutionResult::from_transfer_result(transfer_result, gas) else { + return Err(BlockExecutionError::RootNotFound(state_root_hash)); + }; + let exec_result_and_msgs = ExecutionResultAndMessages::from(exec_result); + execution_results.push(ExecutionArtifact::new( + txn_hash, + txn_header, + ExecutionResult::from(exec_result_and_msgs.execution_result), + exec_result_and_msgs.messages, + )); + } + } } // Write the transaction approvals' and execution results' checksums to global state. @@ -367,7 +346,7 @@ pub fn execute_finalized_block( return Err(BlockExecutionError::FailedToCreateEraEnd { maybe_era_report, maybe_next_era_validator_weights, - }) + }); } }; @@ -397,13 +376,13 @@ pub fn execute_finalized_block( None => { return Err(BlockExecutionError::EngineState( engine_state::Error::MissingChecksumRegistry, - )) + )); } }, None => { return Err(BlockExecutionError::EngineState( engine_state::Error::RootNotFound(state_root_hash), - )) + )); } }; @@ -463,6 +442,9 @@ where pub(super) fn speculatively_execute( engine_state: &EngineState, execution_state: SpeculativeExecutionState, + administrative_accounts: BTreeSet, + allow_unrestricted_transfers: bool, + system_costs: SystemConfig, txn: Transaction, ) -> Result<(ExecutionResultV2, Messages), SpeculativeExecutionError> where @@ -471,20 +453,28 @@ where let SpeculativeExecutionState { state_root_hash, block_time, - protocol_version: _, + protocol_version, } = execution_state; - if txn.is_native() { - todo!("route native transactions to data access layer"); - } - let execute_request = ExecuteRequest::new( + + let request = UserRequest::new( state_root_hash, BlockTime::new(block_time.millis()), + protocol_version, txn, PublicKey::System, + administrative_accounts, + allow_unrestricted_transfers, + &system_costs, )?; - execute(engine_state, None, execute_request) - .map(|res_and_msgs| (res_and_msgs.execution_result, res_and_msgs.messages)) - .map_err(SpeculativeExecutionError::from) + + match request { + UserRequest::Execute(execute_request) => execute(engine_state, None, execute_request) + .map(|res_and_msgs| (res_and_msgs.execution_result, res_and_msgs.messages)) + .map_err(SpeculativeExecutionError::from), + UserRequest::Transfer(_transfer_request) => { + todo!("route native transactions to data access layer, but don't commit them"); + } + } } fn execute( @@ -595,3 +585,80 @@ pub(crate) fn compute_execution_results_checksum<'a>( BlockExecutionError::FailedToComputeExecutionResultsChecksum(bytesrepr::Error::OutOfMemory) }) } + +enum UserRequest { + Execute(ExecuteRequest), + Transfer(TransferRequest), +} + +impl UserRequest { + #[allow(clippy::too_many_arguments)] + fn new( + state_hash: Digest, + block_time: BlockTime, + protocol_version: ProtocolVersion, + txn: Transaction, + proposer: PublicKey, + administrative_accounts: BTreeSet, + allow_unrestricted_transfers: bool, + system_costs: &SystemConfig, + ) -> Result { + if txn.is_native() { + let txn_hash = txn.hash(); + let initiator_addr = txn.initiator_addr(); + let authorization_keys = txn.signers(); + + let v1_txn = match txn { + Transaction::Deploy(deploy) => { + if !deploy.is_transfer() { + return Err(NewUserRequestError::ExpectedNativeTransferDeploy(txn_hash)); + } + let transfer_req = TransferRequest::with_runtime_args( + TransferConfig::new(administrative_accounts, allow_unrestricted_transfers), + state_hash, + block_time, + protocol_version, + proposer, + txn_hash, + initiator_addr, + authorization_keys, + deploy.session().args().clone(), + Gas::new(system_costs.mint_costs().transfer), + ); + return Ok(UserRequest::Transfer(transfer_req)); + } + Transaction::V1(v1_txn) => v1_txn, + }; + + match v1_txn.entry_point() { + TransactionEntryPoint::Custom(_) => { + return Err(NewUserRequestError::InvalidEntryPoint(txn_hash)); + } + TransactionEntryPoint::Transfer => { + let transfer_req = TransferRequest::with_runtime_args( + TransferConfig::new(administrative_accounts, allow_unrestricted_transfers), + state_hash, + block_time, + protocol_version, + proposer, + txn_hash, + initiator_addr, + authorization_keys, + v1_txn.take_args(), + Gas::new(system_costs.mint_costs().transfer), + ); + return Ok(UserRequest::Transfer(transfer_req)); + } + TransactionEntryPoint::AddBid => todo!("make auction request"), + TransactionEntryPoint::WithdrawBid => todo!("make auction request"), + TransactionEntryPoint::Delegate => todo!("make auction request"), + TransactionEntryPoint::Undelegate => todo!("make auction request"), + TransactionEntryPoint::Redelegate => todo!("make auction request"), + } + } + + let execute_req = ExecuteRequest::new(state_hash, block_time, txn, proposer) + .map_err(NewUserRequestError::Execute)?; + Ok(UserRequest::Execute(execute_req)) + } +} diff --git a/node/src/components/contract_runtime/types.rs b/node/src/components/contract_runtime/types.rs index 3534e9ff33..a05095e8f8 100644 --- a/node/src/components/contract_runtime/types.rs +++ b/node/src/components/contract_runtime/types.rs @@ -4,7 +4,7 @@ use datasize::DataSize; use serde::Serialize; use thiserror::Error; -use casper_execution_engine::engine_state::{Error as EngineStateError, NewRequestError}; +use casper_execution_engine::engine_state::Error as EngineStateError; use casper_storage::data_access_layer::EraValidatorsRequest; use casper_types::{ contract_messages::Messages, @@ -13,7 +13,7 @@ use casper_types::{ TransactionHash, TransactionHeader, U512, }; -use crate::types::ApprovalsHashes; +use crate::{contract_runtime::NewUserRequestError, types::ApprovalsHashes}; /// Request for validator weights for a specific era. #[derive(Debug, Clone, PartialEq, Eq)] @@ -181,7 +181,7 @@ impl ExecutionPreState { pub enum SpeculativeExecutionError { /// An error that occurred while constructing the execution request. #[error(transparent)] - NewRequest(#[from] NewRequestError), + NewRequest(#[from] NewUserRequestError), /// An error that occurred while constructing the execution request. #[error(transparent)] EngineState(#[from] EngineStateError), diff --git a/node/src/components/contract_runtime/utils.rs b/node/src/components/contract_runtime/utils.rs index 40b54b1c2f..9cab0ebd94 100644 --- a/node/src/components/contract_runtime/utils.rs +++ b/node/src/components/contract_runtime/utils.rs @@ -17,7 +17,7 @@ use casper_execution_engine::engine_state::EngineState; use casper_storage::{ data_access_layer::DataAccessLayer, global_state::state::lmdb::LmdbGlobalState, }; -use casper_types::{Chainspec, EraId, Key}; +use casper_types::{Chainspec, EraId, Key, PublicKey}; use once_cell::sync::Lazy; use std::{ cmp, @@ -89,7 +89,7 @@ pub(super) async fn exec_or_requeue( { Ok(rewards) => rewards, Err(e) => { - return fatal!(effect_builder, "Failed to compute the rewards: {e:?}").await + return fatal!(effect_builder, "Failed to compute the rewards: {e:?}").await; } }; @@ -102,6 +102,15 @@ pub(super) async fn exec_or_requeue( }); } + let administrative_accounts = chainspec + .core_config + .administrators + .iter() + .map(PublicKey::to_account_hash) + .collect(); + let allow_unrestricted_transfers = chainspec.core_config.allow_unrestricted_transfers; + let system_costs = chainspec.system_costs_config; + let BlockAndExecutionResults { block, approvals_hashes, @@ -119,6 +128,9 @@ pub(super) async fn exec_or_requeue( activation_point.era_id(), key_block_height_for_activation_point, prune_batch_size, + &administrative_accounts, + allow_unrestricted_transfers, + system_costs, ) }) .await @@ -304,9 +316,9 @@ mod tests { #[test] fn calculation_is_safe_with_invalid_input() { - assert_eq!(calculate_prune_eras(EraId::new(0), 0, 0, 0,), None); - assert_eq!(calculate_prune_eras(EraId::new(0), 0, 0, 5,), None); - assert_eq!(calculate_prune_eras(EraId::new(u64::MAX), 0, 0, 0,), None); + assert_eq!(calculate_prune_eras(EraId::new(0), 0, 0, 0), None); + assert_eq!(calculate_prune_eras(EraId::new(0), 0, 0, 5), None); + assert_eq!(calculate_prune_eras(EraId::new(u64::MAX), 0, 0, 0), None); assert_eq!( calculate_prune_eras(EraId::new(u64::MAX), 1, u64::MAX, u64::MAX), None @@ -319,7 +331,7 @@ mod tests { // batch out of u64::MAX of erainfos needs to iterate over all chunks. assert!(calculate_prune_eras(EraId::new(u64::MAX), 0, u64::MAX, 100,).is_none(),); assert_eq!( - calculate_prune_eras(EraId::new(u64::MAX), 1, 100, 100,) + calculate_prune_eras(EraId::new(u64::MAX), 1, 100, 100) .unwrap() .len(), 100 @@ -339,7 +351,7 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height, - 1 + 1, ), Some(vec![Key::EraInfo(EraId::new(0))]) ); @@ -348,7 +360,7 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height + 1, - 1 + 1, ), Some(vec![Key::EraInfo(EraId::new(1))]) ); @@ -357,7 +369,7 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height + 2, - 1 + 1, ), Some(vec![Key::EraInfo(EraId::new(2))]) ); @@ -366,7 +378,7 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height + 3, - 1 + 1, ), Some(vec![Key::EraInfo(EraId::new(3))]) ); @@ -375,7 +387,7 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height + 4, - 1 + 1, ), Some(vec![Key::EraInfo(EraId::new(4))]) ); @@ -400,11 +412,11 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height, - 2 + 2, ), Some(vec![ Key::EraInfo(EraId::new(0)), - Key::EraInfo(EraId::new(1)) + Key::EraInfo(EraId::new(1)), ]) ); assert_eq!( @@ -412,11 +424,11 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height + 1, - 2 + 2, ), Some(vec![ Key::EraInfo(EraId::new(2)), - Key::EraInfo(EraId::new(3)) + Key::EraInfo(EraId::new(3)), ]) ); assert_eq!( @@ -424,7 +436,7 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height + 2, - 2 + 2, ), Some(vec![Key::EraInfo(EraId::new(4))]) ); @@ -433,7 +445,7 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height + 3, - 2 + 2, ), None ); @@ -449,7 +461,7 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height, - 3 + 3, ), Some(vec![ Key::EraInfo(EraId::new(0)), @@ -462,7 +474,7 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height + 1, - 3 + 3, ), Some(vec![ Key::EraInfo(EraId::new(3)), @@ -475,7 +487,7 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height + 2, - 3 + 3, ), None ); @@ -491,7 +503,7 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height, - 4 + 4, ), Some(vec![ Key::EraInfo(EraId::new(0)), @@ -505,9 +517,9 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height + 1, - 4 + 4, ), - Some(vec![Key::EraInfo(EraId::new(4)),]) + Some(vec![Key::EraInfo(EraId::new(4))]) ); assert_eq!( @@ -515,7 +527,7 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height + 2, - 4 + 4, ), None ); @@ -531,7 +543,7 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height, - 5 + 5, ), Some(vec![ Key::EraInfo(EraId::new(0)), @@ -556,7 +568,7 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height + 2, - 5 + 5, ), None ); @@ -572,7 +584,7 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height, - 6 + 6, ), Some(vec![ Key::EraInfo(EraId::new(0)), @@ -597,7 +609,7 @@ mod tests { ACTIVATION_POINT_ERA_ID, activation_height, current_height + 2, - 6 + 6, ), None ); diff --git a/storage/src/data_access_layer.rs b/storage/src/data_access_layer.rs index 3c4f1f84a1..c413db33f0 100644 --- a/storage/src/data_access_layer.rs +++ b/storage/src/data_access_layer.rs @@ -10,7 +10,6 @@ use crate::tracking_copy::TrackingCopy; mod addressable_entity; pub mod balance; pub mod era_validators; -mod execute; mod execution_results_checksum; mod flush; mod genesis; @@ -25,7 +24,6 @@ mod trie; pub use addressable_entity::{AddressableEntityRequest, AddressableEntityResult}; pub use balance::{BalanceRequest, BalanceResult}; pub use era_validators::{EraValidatorsRequest, EraValidatorsResult}; -pub use execute::{ExecuteNativeRequest, NativeEntryPoint, NewNativeRequestError}; pub use execution_results_checksum::{ ExecutionResultsChecksumRequest, ExecutionResultsChecksumResult, EXECUTION_RESULTS_CHECKSUM_NAME, @@ -37,7 +35,7 @@ pub use protocol_upgrade::{ProtocolUpgradeRequest, ProtocolUpgradeResult}; pub use query::{QueryRequest, QueryResult}; pub use round_seigniorage::{RoundSeigniorageRateRequest, RoundSeigniorageRateResult}; pub use total_supply::{TotalSupplyRequest, TotalSupplyResult}; -pub use transfer::{TransferRequest, TransferResult}; +pub use transfer::{TransferConfig, TransferRequest, TransferResult}; pub use trie::{PutTrieRequest, PutTrieResult, TrieElement, TrieRequest, TrieResult}; pub struct Block { diff --git a/storage/src/data_access_layer/execute.rs b/storage/src/data_access_layer/execute.rs deleted file mode 100644 index e9889caaaa..0000000000 --- a/storage/src/data_access_layer/execute.rs +++ /dev/null @@ -1,123 +0,0 @@ -use std::collections::BTreeSet; - -use serde::Serialize; -use thiserror::Error; - -use casper_types::{ - account::AccountHash, BlockTime, DeployHash, Digest, ExecutableDeployItem, InitiatorAddr, - PublicKey, RuntimeArgs, Transaction, TransactionEntryPoint, TransactionHash, -}; - -/// Error returned if constructing a new [`ExecuteNativeRequest`] fails. -#[derive(Clone, Eq, PartialEq, Error, Serialize, Debug)] -pub enum NewNativeRequestError { - /// Attempted to construct an [`ExecuteNativeRequest`] from a deploy which is not a transfer. - #[error("deploy must be a transfer for native execution: {0}")] - ExpectedTransferDeploy(DeployHash), - /// Attempted to construct an [`ExecuteNativeRequest`] from a transaction with an invalid entry - /// point. - #[error( - "cannot use custom entry point '{entry_point}' for native execution: {transaction_hash}" - )] - InvalidEntryPoint { - transaction_hash: TransactionHash, - entry_point: String, - }, -} - -/// The entry point of the native contract to call. -#[derive(Debug)] -pub enum NativeEntryPoint { - /// The `transfer` entry point, used to transfer `Motes` from a source purse to a target purse. - Transfer, - /// The `add_bid` entry point, used to create or top off a bid purse. - AddBid, - /// The `withdraw_bid` entry point, used to decrease a stake. - WithdrawBid, - /// The `delegate` entry point, used to add a new delegator or increase an existing delegator's - /// stake. - Delegate, - /// The `undelegate` entry point, used to reduce a delegator's stake or remove the delegator if - /// the remaining stake is 0. - Undelegate, - /// The `redelegate` entry point, used to reduce a delegator's stake or remove the delegator if - /// the remaining stake is 0, and after the unbonding delay, automatically delegate to a new - /// validator. - Redelegate, -} - -/// A request to execute the given native transaction. -#[derive(Debug)] -pub struct ExecuteNativeRequest { - /// State root hash of the global state in which the transaction will be executed. - pub parent_state_hash: Digest, - /// Block time represented as a unix timestamp. - pub block_time: BlockTime, - /// The hash identifying the transaction. - pub transaction_hash: TransactionHash, - /// The native contract entry point to call. - pub entry_point: NativeEntryPoint, - /// The runtime args to be used in execution. - pub args: RuntimeArgs, - /// The transaction's initiator. - pub initiator_addr: InitiatorAddr, - /// The account hashes of the signers of the transaction. - pub authorization_keys: BTreeSet, - /// The owner of the node that proposed the block containing this request. - pub proposer: PublicKey, -} - -impl ExecuteNativeRequest { - /// Creates a new execute request. - pub fn new( - parent_state_hash: Digest, - block_time: BlockTime, - txn: Transaction, - proposer: PublicKey, - ) -> Result { - let transaction_hash = txn.hash(); - let initiator_addr = txn.initiator_addr(); - let authorization_keys = txn.signers(); - let entry_point: NativeEntryPoint; - let args: RuntimeArgs; - match txn { - Transaction::Deploy(deploy) => { - let (deploy_hash, _header, _payment, session, _approvals) = deploy.destructure(); - args = match session { - ExecutableDeployItem::Transfer { args } => args, - _ => { - return Err(NewNativeRequestError::ExpectedTransferDeploy(deploy_hash)); - } - }; - entry_point = NativeEntryPoint::Transfer; - } - Transaction::V1(v1_txn) => { - entry_point = match v1_txn.entry_point() { - TransactionEntryPoint::Custom(entry_point) => { - return Err(NewNativeRequestError::InvalidEntryPoint { - transaction_hash, - entry_point: entry_point.clone(), - }) - } - TransactionEntryPoint::Transfer => NativeEntryPoint::Transfer, - TransactionEntryPoint::AddBid => NativeEntryPoint::AddBid, - TransactionEntryPoint::WithdrawBid => NativeEntryPoint::WithdrawBid, - TransactionEntryPoint::Delegate => NativeEntryPoint::Delegate, - TransactionEntryPoint::Undelegate => NativeEntryPoint::Undelegate, - TransactionEntryPoint::Redelegate => NativeEntryPoint::Redelegate, - }; - args = v1_txn.take_args(); - } - }; - Ok(Self { - parent_state_hash, - block_time, - transaction_hash, - entry_point, - args, - initiator_addr, - authorization_keys, - proposer, - }) - } -} diff --git a/storage/src/data_access_layer/transfer.rs b/storage/src/data_access_layer/transfer.rs index 42143ee465..d42c776c11 100644 --- a/storage/src/data_access_layer/transfer.rs +++ b/storage/src/data_access_layer/transfer.rs @@ -1,8 +1,8 @@ use std::collections::BTreeSet; use casper_types::{ - account::AccountHash, execution::Effects, Digest, Gas, InitiatorAddr, ProtocolVersion, - PublicKey, RuntimeArgs, TransactionHash, TransferAddr, + account::AccountHash, execution::Effects, BlockTime, Digest, Gas, InitiatorAddr, + ProtocolVersion, PublicKey, RuntimeArgs, TransactionHash, TransferAddr, }; use crate::system::transfer::{TransferArgs, TransferError}; @@ -86,7 +86,7 @@ pub struct TransferRequest { /// State root hash. state_hash: Digest, /// Block time represented as a unix timestamp. - block_time: u64, + block_time: BlockTime, /// Protocol version. protocol_version: ProtocolVersion, /// Public key of the proposer. @@ -109,7 +109,7 @@ impl TransferRequest { pub fn new( config: TransferConfig, state_hash: Digest, - block_time: u64, + block_time: BlockTime, protocol_version: ProtocolVersion, proposer: PublicKey, transaction_hash: TransactionHash, @@ -138,7 +138,7 @@ impl TransferRequest { pub fn with_runtime_args( config: TransferConfig, state_hash: Digest, - block_time: u64, + block_time: BlockTime, protocol_version: ProtocolVersion, proposer: PublicKey, transaction_hash: TransactionHash, @@ -185,9 +185,8 @@ impl TransferRequest { pub fn protocol_version(&self) -> ProtocolVersion { self.protocol_version } - /// Returns block time. - pub fn block_time(&self) -> u64 { + pub fn block_time(&self) -> BlockTime { self.block_time } @@ -215,6 +214,14 @@ impl TransferRequest { pub fn into_args(self) -> TransferRequestArgs { self.args } + + /// Used by `WasmTestBuilder` to set the appropriate state root hash and transfer config before + /// executing the transfer. + #[doc(hidden)] + pub fn set_state_hash_and_config(&mut self, state_hash: Digest, config: TransferConfig) { + self.state_hash = state_hash; + self.config = config; + } } #[derive(Debug, Clone)] diff --git a/storage/src/tracking_copy/error.rs b/storage/src/tracking_copy/error.rs index 877e6fc0bc..48a337d5ad 100644 --- a/storage/src/tracking_copy/error.rs +++ b/storage/src/tracking_copy/error.rs @@ -103,7 +103,7 @@ pub enum Error { #[error("Host buffer is empty")] HostBufferEmpty, /// WASM bytes contains an unsupported "start" section. - #[error("Unsupported WASM start")] + #[error("Unsupported Wasm start")] UnsupportedWasmStart, /// Contract package has no active contract versions. #[error("No active contract versions for contract package")] diff --git a/types/src/block/signed_block_header.rs b/types/src/block/signed_block_header.rs index c616da87f1..f385c5cafd 100644 --- a/types/src/block/signed_block_header.rs +++ b/types/src/block/signed_block_header.rs @@ -9,6 +9,8 @@ use serde::{Deserialize, Serialize}; use super::{BlockHash, BlockHeader, BlockSignatures}; use crate::EraId; +#[cfg(doc)] +use crate::Signature; /// An error which can result from validating a [`SignedBlockHeader`]. #[derive(Copy, Clone, Eq, PartialEq, Debug)] diff --git a/types/src/transaction/transaction_hash.rs b/types/src/transaction/transaction_hash.rs index faadb1dc2e..1425ceb60e 100644 --- a/types/src/transaction/transaction_hash.rs +++ b/types/src/transaction/transaction_hash.rs @@ -3,12 +3,16 @@ use core::fmt::{self, Display, Formatter}; #[cfg(feature = "datasize")] use datasize::DataSize; +#[cfg(any(feature = "testing", test))] +use rand::Rng; #[cfg(feature = "json-schema")] use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use super::{DeployHash, TransactionV1Hash}; use crate::bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}; +#[cfg(any(feature = "testing", test))] +use crate::testing::TestRng; const DEPLOY_TAG: u8 = 0; const V1_TAG: u8 = 1; @@ -26,6 +30,18 @@ pub enum TransactionHash { V1(TransactionV1Hash), } +impl TransactionHash { + /// Returns a random `TransactionHash`. + #[cfg(any(feature = "testing", test))] + pub fn random(rng: &mut TestRng) -> Self { + if rng.gen() { + TransactionHash::Deploy(DeployHash::random(rng)) + } else { + TransactionHash::V1(TransactionV1Hash::random(rng)) + } + } +} + impl From for TransactionHash { fn from(hash: DeployHash) -> Self { Self::Deploy(hash) From a23eb63e459dba1f9241c392ae51d8a87eb27292 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Fri, 23 Feb 2024 22:53:03 +0000 Subject: [PATCH 04/70] disallow non-install/upgrade v1 txns to call add_contract_version --- .../src/engine_state/execute_request.rs | 9 +- .../src/engine_state/execution_kind.rs | 19 +++- execution_engine/src/engine_state/mod.rs | 8 +- execution_engine/src/execution/executor.rs | 18 +++- execution_engine/src/runtime/mod.rs | 4 + execution_engine/src/runtime_context/mod.rs | 10 ++ execution_engine/src/runtime_context/tests.rs | 3 + .../test_support/src/lib.rs | 10 +- .../test/contract_api/add_contract_version.rs | 92 +++++++++++++++++++ .../tests/src/test/contract_api/mod.rs | 1 + .../tests/src/test/explorer/faucet.rs | 8 +- types/src/api_error.rs | 13 +++ types/src/block_time.rs | 2 +- 13 files changed, 175 insertions(+), 22 deletions(-) create mode 100644 execution_engine_testing/tests/src/test/contract_api/add_contract_version.rs diff --git a/execution_engine/src/engine_state/execute_request.rs b/execution_engine/src/engine_state/execute_request.rs index 01238fcea6..b982ca54fe 100644 --- a/execution_engine/src/engine_state/execute_request.rs +++ b/execution_engine/src/engine_state/execute_request.rs @@ -113,13 +113,15 @@ impl TryFrom<(ExecutableDeployItem, DeployHash)> for PaymentInfo { pub enum Session { /// A stored entity or package. Stored(TransactionInvocationTarget), - /// Compiled Wasm as byte code. + /// Compiled Wasm from a transaction >= V1 as byte code. ModuleBytes { /// The kind of session. kind: TransactionSessionKind, /// The compiled Wasm. module_bytes: Bytes, }, + /// Compiled Wasm from a deploy as byte code. + DeployModuleBytes(Bytes), } /// The session-related portion of an `ExecuteRequest`. @@ -143,10 +145,7 @@ impl TryFrom<(ExecutableDeployItem, DeployHash)> for SessionInfo { let session_args: RuntimeArgs; match session_item { ExecutableDeployItem::ModuleBytes { module_bytes, args } => { - session = Session::ModuleBytes { - kind: TransactionSessionKind::Standard, - module_bytes, - }; + session = Session::DeployModuleBytes(module_bytes); session_entry_point = DEFAULT_ENTRY_POINT.to_string(); session_args = args; } diff --git a/execution_engine/src/engine_state/execution_kind.rs b/execution_engine/src/engine_state/execution_kind.rs index 9d4929d740..3fc7a39545 100644 --- a/execution_engine/src/engine_state/execution_kind.rs +++ b/execution_engine/src/engine_state/execution_kind.rs @@ -18,7 +18,10 @@ use crate::{ #[derive(Clone, Debug)] pub(crate) enum ExecutionKind<'a> { /// Standard (non-specialized) Wasm bytes. - Standard(&'a Bytes), + Standard { + module_bytes: &'a Bytes, + allow_casper_add_contract_version: bool, + }, /// Wasm bytes which install a stored entity. Installer(&'a Bytes), /// Wasm bytes which upgrade a stored entity. @@ -36,8 +39,11 @@ pub(crate) enum ExecutionKind<'a> { impl<'a> ExecutionKind<'a> { /// Returns a new `Standard` variant of `ExecutionKind`. - pub fn new_standard(module_bytes: &'a Bytes) -> Self { - ExecutionKind::Standard(module_bytes) + pub fn new_standard(module_bytes: &'a Bytes, allow_casper_add_contract_version: bool) -> Self { + ExecutionKind::Standard { + module_bytes, + allow_casper_add_contract_version, + } } /// Returns a new `Installer` variant of `ExecutionKind`. @@ -61,14 +67,17 @@ impl<'a> ExecutionKind<'a> { if module_bytes.is_empty() { return Err(Error::EmptyCustomPaymentModuleBytes); } - Ok(ExecutionKind::Standard(module_bytes)) + Ok(ExecutionKind::Standard { + module_bytes, + allow_casper_add_contract_version: false, + }) } /// Returns a new `ExecutionKind` cloned from `self`, but converting any Wasm bytes variant to /// `Standard`, and returning an error if they are empty. pub fn convert_for_payment(&self) -> Result { match self { - ExecutionKind::Standard(module_bytes) + ExecutionKind::Standard { module_bytes, .. } | ExecutionKind::Installer(module_bytes) | ExecutionKind::Upgrader(module_bytes) | ExecutionKind::Isolated(module_bytes) => Self::new_for_payment(module_bytes), diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index 369e820d49..c254cc4c6b 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -436,19 +436,25 @@ where Session::ModuleBytes { kind: TransactionSessionKind::Standard, module_bytes, - } => ExecutionKind::new_standard(module_bytes), + } => ExecutionKind::new_standard(module_bytes, false), Session::ModuleBytes { kind: TransactionSessionKind::Installer, module_bytes, + .. } => ExecutionKind::new_installer(module_bytes), Session::ModuleBytes { kind: TransactionSessionKind::Upgrader, module_bytes, + .. } => ExecutionKind::new_upgrader(module_bytes), Session::ModuleBytes { kind: TransactionSessionKind::Isolated, module_bytes, + .. } => ExecutionKind::new_isolated(module_bytes), + Session::DeployModuleBytes(module_bytes) => { + ExecutionKind::new_standard(module_bytes, true) + } }; // Get account main purse balance key diff --git a/execution_engine/src/execution/executor.rs b/execution_engine/src/execution/executor.rs index 0aac111b59..9dfdf7b8ef 100644 --- a/execution_engine/src/execution/executor.rs +++ b/execution_engine/src/execution/executor.rs @@ -87,6 +87,17 @@ impl Executor { let entity_key = Key::addressable_entity_key(entity_kind.tag(), entity_hash); + let allow_casper_add_contract_version = match execution_kind { + ExecutionKind::Standard { + allow_casper_add_contract_version, + .. + } => allow_casper_add_contract_version, + ExecutionKind::Installer(_) + | ExecutionKind::Upgrader(_) + | ExecutionKind::Stored { .. } => true, + ExecutionKind::Isolated(_) => false, + }; + let context = self.create_runtime_context( named_keys, entity, @@ -105,12 +116,13 @@ impl Executor { gas_limit, spending_limit, EntryPointType::Session, + allow_casper_add_contract_version, ); let mut runtime = Runtime::new(context); let result = match execution_kind { - ExecutionKind::Standard(module_bytes) + ExecutionKind::Standard { module_bytes, .. } | ExecutionKind::Installer(module_bytes) | ExecutionKind::Upgrader(module_bytes) | ExecutionKind::Isolated(module_bytes) => { @@ -234,6 +246,7 @@ impl Executor { let access_rights = contract.extract_access_rights(entity_hash, &named_keys); let entity_address = entity_addr.into(); + let allow_casper_add_contract_version = false; let runtime_context = self.create_runtime_context( &mut named_keys, entity, @@ -252,6 +265,7 @@ impl Executor { gas_limit, remaining_spending_limit, EntryPointType::AddressableEntity, + allow_casper_add_contract_version, ); let mut runtime = Runtime::new(runtime_context); @@ -314,6 +328,7 @@ impl Executor { gas_limit: Gas, remaining_spending_limit: U512, entry_point_type: EntryPointType, + allow_casper_add_contract_version: bool, ) -> RuntimeContext<'a, R> where R: StateReader, @@ -342,6 +357,7 @@ impl Executor { transfers, remaining_spending_limit, entry_point_type, + allow_casper_add_contract_version, ) } diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index bb4b4f75a3..be79a031dd 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -1793,6 +1793,10 @@ where mut named_keys: NamedKeys, output_ptr: u32, ) -> Result, Error> { + if !self.context.allow_casper_add_contract_version() { + return Ok(Err(ApiError::NotAllowedToAddContractVersion)); + } + if entry_points.contains_stored_session() { return Err(Error::InvalidEntryPointType); } diff --git a/execution_engine/src/runtime_context/mod.rs b/execution_engine/src/runtime_context/mod.rs index 9a1502f2ae..25f2cff27f 100644 --- a/execution_engine/src/runtime_context/mod.rs +++ b/execution_engine/src/runtime_context/mod.rs @@ -73,6 +73,8 @@ pub struct RuntimeContext<'a, R> { entity_kind: EntityKind, account_hash: AccountHash, emit_message_cost: U512, + // Whether the execution is permitted to call FFI `casper_add_contract_version()` or not. + allow_casper_add_contract_version: bool, } impl<'a, R> RuntimeContext<'a, R> @@ -104,6 +106,7 @@ where transfers: Vec, remaining_spending_limit: U512, entry_point_type: EntryPointType, + allow_casper_add_contract_version: bool, ) -> Self { let emit_message_cost = engine_config .wasm_config() @@ -133,6 +136,7 @@ where remaining_spending_limit, entity_kind, emit_message_cost, + allow_casper_add_contract_version, } } @@ -188,6 +192,7 @@ where remaining_spending_limit, entity_kind, emit_message_cost: self.emit_message_cost, + allow_casper_add_contract_version: self.allow_casper_add_contract_version, } } @@ -338,6 +343,11 @@ where self.phase } + /// Returns `true` if the execution is permitted to call `casper_add_contract_version()`. + pub fn allow_casper_add_contract_version(&self) -> bool { + self.allow_casper_add_contract_version + } + /// Generates new deterministic hash for uses as an address. pub fn new_hash_address(&mut self) -> Result<[u8; KEY_HASH_LENGTH], Error> { Ok(self.address_generator.borrow_mut().new_hash_address()) diff --git a/execution_engine/src/runtime_context/tests.rs b/execution_engine/src/runtime_context/tests.rs index cdaa963e6e..da220c7e73 100644 --- a/execution_engine/src/runtime_context/tests.rs +++ b/execution_engine/src/runtime_context/tests.rs @@ -163,6 +163,7 @@ fn new_runtime_context<'a>( Vec::default(), U512::MAX, EntryPointType::Session, + false, ); (runtime_context, tempdir) @@ -427,6 +428,7 @@ fn contract_key_addable_valid() { Vec::default(), U512::zero(), EntryPointType::Session, + false, ); assert!(runtime_context @@ -485,6 +487,7 @@ fn contract_key_addable_invalid() { Vec::default(), U512::zero(), EntryPointType::Session, + false, ); let result = runtime_context.metered_add_gs(contract_key, named_uref_tuple); diff --git a/execution_engine_testing/test_support/src/lib.rs b/execution_engine_testing/test_support/src/lib.rs index 32ab3f21ca..d7ff1cf893 100644 --- a/execution_engine_testing/test_support/src/lib.rs +++ b/execution_engine_testing/test_support/src/lib.rs @@ -17,7 +17,6 @@ mod transfer_request_builder; mod upgrade_request_builder; pub mod utils; mod wasm_test_builder; -// mod execute_request_builder; use num_rational::Ratio; use once_cell::sync::Lazy; @@ -80,11 +79,12 @@ pub const TIMESTAMP_MILLIS_INCREMENT: u64 = 30_000; // 30 seconds /// Default genesis config hash. pub static DEFAULT_GENESIS_CONFIG_HASH: Lazy = Lazy::new(|| [42; 32].into()); +/// Default account secret key. +pub static DEFAULT_ACCOUNT_SECRET_KEY: Lazy = + Lazy::new(|| SecretKey::ed25519_from_bytes([199; SecretKey::ED25519_LENGTH]).unwrap()); /// Default account public key. -pub static DEFAULT_ACCOUNT_PUBLIC_KEY: Lazy = Lazy::new(|| { - let secret_key = SecretKey::ed25519_from_bytes([199; SecretKey::ED25519_LENGTH]).unwrap(); - PublicKey::from(&secret_key) -}); +pub static DEFAULT_ACCOUNT_PUBLIC_KEY: Lazy = + Lazy::new(|| PublicKey::from(&*DEFAULT_ACCOUNT_SECRET_KEY)); /// Default test account address. pub static DEFAULT_ACCOUNT_ADDR: Lazy = Lazy::new(|| AccountHash::from(&*DEFAULT_ACCOUNT_PUBLIC_KEY)); diff --git a/execution_engine_testing/tests/src/test/contract_api/add_contract_version.rs b/execution_engine_testing/tests/src/test/contract_api/add_contract_version.rs new file mode 100644 index 0000000000..799d513d58 --- /dev/null +++ b/execution_engine_testing/tests/src/test/contract_api/add_contract_version.rs @@ -0,0 +1,92 @@ +use casper_engine_test_support::{ + utils, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, + DEFAULT_ACCOUNT_SECRET_KEY, DEFAULT_PROPOSER_PUBLIC_KEY, PRODUCTION_RUN_GENESIS_REQUEST, +}; +use casper_execution_engine::{ + engine_state::{Error as StateError, ExecuteRequest}, + execution::Error as ExecError, +}; +use casper_types::{ + ApiError, BlockTime, Digest, RuntimeArgs, Transaction, TransactionSessionKind, + TransactionV1Builder, +}; + +const CONTRACT: &str = "do_nothing_stored.wasm"; +const ENTRY_POINT: &str = "call"; +const PAYMENT_AMOUNT: u64 = 100_000_000_000; +const CHAIN_NAME: &str = "a"; +const STATE_HASH: Digest = Digest::from_raw([1; 32]); +const BLOCK_TIME: BlockTime = BlockTime::new(10); + +#[ignore] +#[test] +fn should_allow_add_contract_version_via_deploy() { + let mut builder = LmdbWasmTestBuilder::default(); + builder + .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .commit(); + + let deploy_request = + ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CONTRACT, RuntimeArgs::new()) + .build(); + + builder.exec(deploy_request).expect_success().commit(); +} + +fn try_add_contract_version(kind: TransactionSessionKind, should_succeed: bool) { + let mut builder = LmdbWasmTestBuilder::default(); + builder + .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .commit(); + + let module_bytes = utils::read_wasm_file(CONTRACT); + + let txn = TransactionV1Builder::new_session(kind, module_bytes, ENTRY_POINT) + .with_secret_key(&DEFAULT_ACCOUNT_SECRET_KEY) + .with_chain_name(CHAIN_NAME) + .with_payment_amount(PAYMENT_AMOUNT) + .build() + .unwrap(); + + let txn_request = ExecuteRequest::new( + STATE_HASH, + BLOCK_TIME, + Transaction::from(txn), + DEFAULT_PROPOSER_PUBLIC_KEY.clone(), + ) + .unwrap(); + + builder.exec(txn_request); + + if should_succeed { + builder.expect_success(); + } else { + builder.assert_error(StateError::Exec(ExecError::Revert( + ApiError::NotAllowedToAddContractVersion, + ))) + } +} + +#[ignore] +#[test] +fn should_allow_add_contract_version_via_transaction_v1_installer() { + try_add_contract_version(TransactionSessionKind::Installer, true) +} + +#[ignore] +#[test] +fn should_allow_add_contract_version_via_transaction_v1_upgrader() { + try_add_contract_version(TransactionSessionKind::Upgrader, true) +} + +#[ignore] +#[test] +fn should_disallow_add_contract_version_via_transaction_v1_standard() { + try_add_contract_version(TransactionSessionKind::Standard, false) +} + +#[ignore] +#[test] +fn should_allow_add_contract_version_via_transaction_v1_isolated() { + try_add_contract_version(TransactionSessionKind::Isolated, false) +} diff --git a/execution_engine_testing/tests/src/test/contract_api/mod.rs b/execution_engine_testing/tests/src/test/contract_api/mod.rs index a1a5354aea..1f2a6bb52c 100644 --- a/execution_engine_testing/tests/src/test/contract_api/mod.rs +++ b/execution_engine_testing/tests/src/test/contract_api/mod.rs @@ -1,4 +1,5 @@ mod account; +mod add_contract_version; mod create_purse; mod dictionary; mod get_arg; diff --git a/execution_engine_testing/tests/src/test/explorer/faucet.rs b/execution_engine_testing/tests/src/test/explorer/faucet.rs index 82a6552322..4cba932bbc 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet.rs @@ -925,10 +925,10 @@ fn faucet_costs() { // This test will fail if execution costs vary. The expected costs should not be updated // without understanding why the cost has changed. If the costs do change, it should be // reflected in the "Costs by Entry Point" section of the faucet crate's README.md. - const EXPECTED_FAUCET_INSTALL_COST: u64 = 91_845_549_880; - const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_527_120; - const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_103_080; - const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_410_400; + const EXPECTED_FAUCET_INSTALL_COST: u64 = 91_863_194_740; + const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_534_140; + const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_113_880; + const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_425_520; let installer_account = AccountHash::new([1u8; 32]); let user_account: AccountHash = AccountHash::new([2u8; 32]); diff --git a/types/src/api_error.rs b/types/src/api_error.rs index 9efe7716f3..0e14e857c1 100644 --- a/types/src/api_error.rs +++ b/types/src/api_error.rs @@ -432,6 +432,13 @@ pub enum ApiError { /// assert_eq!(ApiError::from(46), ApiError::MessageTooLarge); /// ``` MessageTooLarge, + /// Attempt to call FFI function `casper_add_contract_version()` from a transaction not defined + /// as an installer/upgrader. + /// ``` + /// # use casper_types::ApiError; + /// assert_eq!(ApiError::from(47), ApiError::NotAllowedToAddContractVersion); + /// ``` + NotAllowedToAddContractVersion, } impl From for ApiError { @@ -594,6 +601,7 @@ impl From for u32 { ApiError::MessageTopicNotRegistered => 44, ApiError::MessageTopicFull => 45, ApiError::MessageTooLarge => 46, + ApiError::NotAllowedToAddContractVersion => 47, ApiError::AuctionError(value) => AUCTION_ERROR_OFFSET + u32::from(value), ApiError::ContractHeader(value) => HEADER_ERROR_OFFSET + u32::from(value), ApiError::Mint(value) => MINT_ERROR_OFFSET + u32::from(value), @@ -652,6 +660,7 @@ impl From for ApiError { 44 => ApiError::MessageTopicNotRegistered, 45 => ApiError::MessageTopicFull, 46 => ApiError::MessageTooLarge, + 47 => ApiError::NotAllowedToAddContractVersion, USER_ERROR_MIN..=USER_ERROR_MAX => ApiError::User(value as u16), HP_ERROR_MIN..=HP_ERROR_MAX => ApiError::HandlePayment(value as u8), MINT_ERROR_MIN..=MINT_ERROR_MAX => ApiError::Mint(value as u8), @@ -720,6 +729,9 @@ impl Debug for ApiError { } ApiError::MessageTopicFull => write!(f, "ApiError::MessageTopicFull")?, ApiError::MessageTooLarge => write!(f, "ApiError::MessageTooLarge")?, + ApiError::NotAllowedToAddContractVersion => { + write!(f, "ApiError::NotAllowedToAddContractVersion")? + } ApiError::ExceededRecursionDepth => write!(f, "ApiError::ExceededRecursionDepth")?, ApiError::AuctionError(value) => write!( f, @@ -945,5 +957,6 @@ mod tests { round_trip(Err(ApiError::MessageTopicNotRegistered)); round_trip(Err(ApiError::MessageTopicFull)); round_trip(Err(ApiError::MessageTooLarge)); + round_trip(Err(ApiError::NotAllowedToAddContractVersion)); } } diff --git a/types/src/block_time.rs b/types/src/block_time.rs index 935afa6e2b..30c585e021 100644 --- a/types/src/block_time.rs +++ b/types/src/block_time.rs @@ -19,7 +19,7 @@ pub struct BlockTime(u64); impl BlockTime { /// Constructs a `BlockTime`. - pub fn new(value: u64) -> Self { + pub const fn new(value: u64) -> Self { BlockTime(value) } From f0b58f6380b60be33ce8f94f1c407358d5acc154 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Mon, 26 Feb 2024 11:11:33 +0000 Subject: [PATCH 05/70] remove unused file --- .../json_compatibility/addressable_entity.rs | 72 ------------------- 1 file changed, 72 deletions(-) delete mode 100644 node/src/types/json_compatibility/addressable_entity.rs diff --git a/node/src/types/json_compatibility/addressable_entity.rs b/node/src/types/json_compatibility/addressable_entity.rs deleted file mode 100644 index 3ec488020f..0000000000 --- a/node/src/types/json_compatibility/addressable_entity.rs +++ /dev/null @@ -1,72 +0,0 @@ -// TODO - remove once schemars stops causing warning. -#![allow(clippy::field_reassign_with_default)] - -use datasize::DataSize; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use crate::types::json_compatibility::vectorize; -use casper_types::{ - account::AccountHash, addressable_entity::AddressableEntity as DomainEntity, - ContractPackageHash, ContractWasmHash, EntryPoint, NamedKey, ProtocolVersion, URef, -}; - -#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize, DataSize, JsonSchema)] -#[serde(deny_unknown_fields)] -struct AssociatedKey { - account_hash: AccountHash, - weight: u8, -} - -/// Thresholds that have to be met when executing an action of a certain type. -#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize, DataSize, JsonSchema)] -#[serde(deny_unknown_fields)] -struct ActionThresholds { - deployment: u8, - key_management: u8, -} - -/// A contract struct that can be serialized as JSON object. -#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize, DataSize, JsonSchema)] -#[serde(deny_unknown_fields)] -pub struct AddressableEntity { - contract_package_hash: ContractPackageHash, - contract_wasm_hash: ContractWasmHash, - #[data_size(skip)] - named_keys: Vec, - #[data_size(skip)] - entry_points: Vec, - #[data_size(skip)] - #[schemars(with = "String")] - protocol_version: ProtocolVersion, - #[data_size(skip)] - main_purse: URef, - associated_keys: Vec, - action_thresholds: ActionThresholds, -} - -impl From<&DomainEntity> for AddressableEntity { - fn from(entity: &DomainEntity) -> Self { - let entry_points = entity.entry_points().clone().take_entry_points(); - Self { - contract_package_hash: entity.contract_package_hash(), - contract_wasm_hash: entity.contract_wasm_hash(), - named_keys: vectorize(entity.named_keys()), - entry_points, - protocol_version: entity.protocol_version(), - main_purse: entity.main_purse(), - associated_keys: entity - .associated_keys() - .iter() - .map(|(account_hash, weight)| AssociatedKey { - account_hash: *account_hash, - weight: weight.value(), - }) - .collect(), - action_thresholds: ActionThresholds { - deployment: entity.action_thresholds().deployment().value(), - key_management: entity.action_thresholds().key_management().value(), - }, - } - } -} From 89fd4ca0a57885cdf94aa376ecf0aaf58bbcd9fb Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Fri, 8 Mar 2024 00:00:05 +0000 Subject: [PATCH 06/70] update default values --- .../src/engine_state/engine_config.rs | 2 +- .../test_support/src/chainspec_config.rs | 2 +- .../test_support/src/lib.rs | 12 ++++----- .../src/transfer_request_builder.rs | 2 +- .../test_support/src/utils.rs | 4 +-- .../test_support/src/wasm_test_builder.rs | 2 +- .../tests/src/test/chainspec_registry.rs | 27 +++++++++---------- .../tests/src/test/check_transfer_success.rs | 12 ++++----- .../tests/src/test/contract_api/dictionary.rs | 4 +-- .../tests/src/test/groups.rs | 2 +- .../tests/src/test/private_chain.rs | 4 +-- .../test/private_chain/fees_accumulation.rs | 24 ++++++++--------- .../src/test/private_chain/management.rs | 4 +-- .../test/private_chain/restricted_auction.rs | 8 +++--- .../tests/src/test/regression/ee_966.rs | 16 +++++------ .../tests/src/test/regression/gh_2280.rs | 18 ++++++------- .../tests/src/test/regression/gh_3208.rs | 16 +++++------ .../tests/src/test/regression/gov_116.rs | 4 +-- .../tests/src/test/regression/gov_74.rs | 21 ++++++--------- .../test/regression/regression_20220221.rs | 22 +++++++-------- .../tests/src/test/storage_costs.rs | 2 +- .../src/test/system_contracts/auction/bids.rs | 16 +++++------ .../system_contracts/auction/distribute.rs | 2 +- .../test/system_contracts/auction_bidding.rs | 2 +- .../tests/src/test/system_costs.rs | 26 +++++++++--------- .../tests/src/test/wasmless_transfer.rs | 4 +-- .../components/contract_runtime/operations.rs | 2 +- node/src/components/contract_runtime/types.rs | 3 +++ types/src/protocol_version.rs | 2 +- 29 files changed, 124 insertions(+), 141 deletions(-) diff --git a/execution_engine/src/engine_state/engine_config.rs b/execution_engine/src/engine_state/engine_config.rs index 31d2e16d6c..e14dfffc99 100644 --- a/execution_engine/src/engine_state/engine_config.rs +++ b/execution_engine/src/engine_state/engine_config.rs @@ -46,7 +46,7 @@ pub const DEFAULT_FEE_HANDLING: FeeHandling = FeeHandling::PayToProposer; /// Default compute rewards. pub const DEFAULT_COMPUTE_REWARDS: bool = true; /// Default protocol version. -pub const DEFAULT_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::V1_0_0; +pub const DEFAULT_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::V2_0_0; /// The runtime configuration of the execution engine #[derive(Debug, Clone)] diff --git a/execution_engine_testing/test_support/src/chainspec_config.rs b/execution_engine_testing/test_support/src/chainspec_config.rs index bd992f2ee7..eedf1ca997 100644 --- a/execution_engine_testing/test_support/src/chainspec_config.rs +++ b/execution_engine_testing/test_support/src/chainspec_config.rs @@ -135,7 +135,7 @@ impl ChainspecConfig { .build(); Ok(GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_GENESIS_CONFIG_HASH, protocol_version, genesis_config, DEFAULT_CHAINSPEC_REGISTRY.clone(), diff --git a/execution_engine_testing/test_support/src/lib.rs b/execution_engine_testing/test_support/src/lib.rs index 95ee3c58a0..e2b6ba2c90 100644 --- a/execution_engine_testing/test_support/src/lib.rs +++ b/execution_engine_testing/test_support/src/lib.rs @@ -81,9 +81,9 @@ pub const DEFAULT_MAX_QUERY_DEPTH: u64 = 5; pub const DEFAULT_MAX_RUNTIME_CALL_STACK_HEIGHT: u32 = 12; /// Default value for minimum delegation amount in motes. pub const DEFAULT_MINIMUM_DELEGATION_AMOUNT: u64 = 500 * 1_000_000_000; - /// Default genesis config hash. -pub static DEFAULT_GENESIS_CONFIG_HASH: Lazy = Lazy::new(|| [42; 32].into()); +pub const DEFAULT_GENESIS_CONFIG_HASH: Digest = Digest::from_raw([42; 32]); + /// Default account secret key. pub static DEFAULT_ACCOUNT_SECRET_KEY: Lazy = Lazy::new(|| SecretKey::ed25519_from_bytes([199; SecretKey::ED25519_LENGTH]).unwrap()); @@ -98,9 +98,9 @@ pub static DEFAULT_ACCOUNT_ADDR: Lazy = pub static DEFAULT_ACCOUNT_KEY: Lazy = Lazy::new(|| AccountHash::from(&*DEFAULT_ACCOUNT_PUBLIC_KEY)); /// Default initial balance of a test account in motes. -pub const DEFAULT_ACCOUNT_INITIAL_BALANCE: u64 = 100_000_000_000_000_000u64; +pub const DEFAULT_ACCOUNT_INITIAL_BALANCE: u64 = 100_000_000_000_000_000_u64; /// Minimal amount for a transfer that creates new accounts. -pub const MINIMUM_ACCOUNT_CREATION_BALANCE: u64 = 7_500_000_000_000_000u64; +pub const MINIMUM_ACCOUNT_CREATION_BALANCE: u64 = 7_500_000_000_000_000_u64; /// Default proposer public key. pub static DEFAULT_PROPOSER_PUBLIC_KEY: Lazy = Lazy::new(|| { let secret_key = SecretKey::ed25519_from_bytes([198; SecretKey::ED25519_LENGTH]).unwrap(); @@ -127,7 +127,7 @@ pub static DEFAULT_ACCOUNTS: Lazy> = Lazy::new(|| { ret }); /// Default [`ProtocolVersion`]. -pub static DEFAULT_PROTOCOL_VERSION: Lazy = Lazy::new(|| ProtocolVersion::V2_0_0); +pub const DEFAULT_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::V2_0_0; /// Default payment. pub static DEFAULT_PAYMENT: Lazy = Lazy::new(|| U512::from(1_500_000_000_000u64)); /// Default [`WasmConfig`]. @@ -160,7 +160,7 @@ pub static DEFAULT_CHAINSPEC_REGISTRY: Lazy = pub static PRODUCTION_RUN_GENESIS_REQUEST: Lazy = Lazy::new(|| { ChainspecConfig::create_genesis_request_from_production_chainspec( DEFAULT_ACCOUNTS.clone(), - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_PROTOCOL_VERSION, ) .expect("must create the request") }); diff --git a/execution_engine_testing/test_support/src/transfer_request_builder.rs b/execution_engine_testing/test_support/src/transfer_request_builder.rs index 50498179e6..71a4e8f499 100644 --- a/execution_engine_testing/test_support/src/transfer_request_builder.rs +++ b/execution_engine_testing/test_support/src/transfer_request_builder.rs @@ -80,7 +80,7 @@ impl TransferRequestBuilder { config: Self::DEFAULT_CONFIG, state_hash: Self::DEFAULT_STATE_HASH, block_time: BlockTime::new(DEFAULT_BLOCK_TIME), - protocol_version: *DEFAULT_PROTOCOL_VERSION, + protocol_version: DEFAULT_PROTOCOL_VERSION, transaction_hash: None, initiator: InitiatorAddr::PublicKey(DEFAULT_ACCOUNT_PUBLIC_KEY.clone()), authorization_keys: iter::once(*DEFAULT_ACCOUNT_ADDR).collect(), diff --git a/execution_engine_testing/test_support/src/utils.rs b/execution_engine_testing/test_support/src/utils.rs index c1c8aaca1c..55ecd4b21f 100644 --- a/execution_engine_testing/test_support/src/utils.rs +++ b/execution_engine_testing/test_support/src/utils.rs @@ -157,8 +157,8 @@ pub fn create_genesis_config(accounts: Vec) -> GenesisConfig { pub fn create_run_genesis_request(accounts: Vec) -> GenesisRequest { let config = create_genesis_config(accounts); GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_PROTOCOL_VERSION, config, DEFAULT_CHAINSPEC_REGISTRY.clone(), ) diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index 84d0e52f8d..0f37c49b07 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -1333,7 +1333,7 @@ where /// Gets [`EraValidators`]. pub fn get_era_validators(&mut self) -> EraValidators { let state_hash = self.get_post_state_hash(); - let request = EraValidatorsRequest::new(state_hash, *DEFAULT_PROTOCOL_VERSION); + let request = EraValidatorsRequest::new(state_hash, DEFAULT_PROTOCOL_VERSION); let result = self.data_access_layer.era_validators(request); if let EraValidatorsResult::Success { era_validators } = result { diff --git a/execution_engine_testing/tests/src/test/chainspec_registry.rs b/execution_engine_testing/tests/src/test/chainspec_registry.rs index 8f00fd7fc0..f5a92a30c5 100644 --- a/execution_engine_testing/tests/src/test/chainspec_registry.rs +++ b/execution_engine_testing/tests/src/test/chainspec_registry.rs @@ -1,4 +1,3 @@ -use once_cell::sync::Lazy; use rand::Rng; use tempfile::TempDir; @@ -13,14 +12,12 @@ use crate::lmdb_fixture; const DEFAULT_ACTIVATION_POINT: EraId = EraId::new(1); -static OLD_PROTOCOL_VERSION: Lazy = Lazy::new(|| *DEFAULT_PROTOCOL_VERSION); -static NEW_PROTOCOL_VERSION: Lazy = Lazy::new(|| { - ProtocolVersion::from_parts( - OLD_PROTOCOL_VERSION.value().major, - OLD_PROTOCOL_VERSION.value().minor, - OLD_PROTOCOL_VERSION.value().patch + 1, - ) -}); +const OLD_PROTOCOL_VERSION: ProtocolVersion = DEFAULT_PROTOCOL_VERSION; +const NEW_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::from_parts( + OLD_PROTOCOL_VERSION.value().major, + OLD_PROTOCOL_VERSION.value().minor, + OLD_PROTOCOL_VERSION.value().patch + 1, +); #[ignore] #[test] @@ -35,8 +32,8 @@ fn should_commit_chainspec_registry_during_genesis() { ChainspecRegistry::new_with_genesis(&chainspec_bytes, &genesis_account); let run_genesis_request = GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_PROTOCOL_VERSION, DEFAULT_EXEC_CONFIG.clone(), chainspec_registry, ); @@ -73,8 +70,8 @@ fn should_fail_to_commit_genesis_when_missing_genesis_accounts_hash() { ChainspecRegistry::new_with_optional_global_state(&chainspec_bytes, None); let run_genesis_request = GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_PROTOCOL_VERSION, DEFAULT_EXEC_CONFIG.clone(), incomplete_chainspec_registry, ); @@ -116,8 +113,8 @@ fn should_upgrade_chainspec_registry(cfg: TestConfig) { let mut upgrade_request = { UpgradeRequestBuilder::new() - .with_current_protocol_version(*OLD_PROTOCOL_VERSION) - .with_new_protocol_version(*NEW_PROTOCOL_VERSION) + .with_current_protocol_version(OLD_PROTOCOL_VERSION) + .with_new_protocol_version(NEW_PROTOCOL_VERSION) .with_activation_point(DEFAULT_ACTIVATION_POINT) .with_chainspec_registry(upgraded_chainspec_registry) .build() diff --git a/execution_engine_testing/tests/src/test/check_transfer_success.rs b/execution_engine_testing/tests/src/test/check_transfer_success.rs index 80d194330d..3598908995 100644 --- a/execution_engine_testing/tests/src/test/check_transfer_success.rs +++ b/execution_engine_testing/tests/src/test/check_transfer_success.rs @@ -32,8 +32,8 @@ fn test_check_transfer_success_with_source_only() { accounts.extend((*DEFAULT_ACCOUNTS).clone()); let genesis_config = create_genesis_config(accounts); let genesis_request = GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_PROTOCOL_VERSION, genesis_config, DEFAULT_CHAINSPEC_REGISTRY.clone(), ); @@ -93,8 +93,8 @@ fn test_check_transfer_success_with_source_only_errors() { accounts.extend((*DEFAULT_ACCOUNTS).clone()); let genesis_config = create_genesis_config(accounts); let genesis_request = GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_PROTOCOL_VERSION, genesis_config, DEFAULT_CHAINSPEC_REGISTRY.clone(), ); @@ -154,8 +154,8 @@ fn test_check_transfer_success_with_source_and_target() { accounts.extend((*DEFAULT_ACCOUNTS).clone()); let genesis_config = create_genesis_config(accounts); let genesis_request = GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_PROTOCOL_VERSION, genesis_config, DEFAULT_CHAINSPEC_REGISTRY.clone(), ); diff --git a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs index 0dfff737cc..3b1c7bbe94 100644 --- a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs +++ b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs @@ -522,8 +522,8 @@ fn should_query_dictionary_items_with_test_builder() { accounts.extend((*DEFAULT_ACCOUNTS).clone()); let genesis_config = create_genesis_config(accounts); let genesis_request = GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_PROTOCOL_VERSION, genesis_config, DEFAULT_CHAINSPEC_REGISTRY.clone(), ); diff --git a/execution_engine_testing/tests/src/test/groups.rs b/execution_engine_testing/tests/src/test/groups.rs index 88f0386611..43828af440 100644 --- a/execution_engine_testing/tests/src/test/groups.rs +++ b/execution_engine_testing/tests/src/test/groups.rs @@ -242,7 +242,7 @@ fn should_call_group_restricted_contract() { let mut upgrade_request = { UpgradeRequestBuilder::new() - .with_new_protocol_version(*DEFAULT_PROTOCOL_VERSION) + .with_new_protocol_version(DEFAULT_PROTOCOL_VERSION) .build() }; diff --git a/execution_engine_testing/tests/src/test/private_chain.rs b/execution_engine_testing/tests/src/test/private_chain.rs index 22b783f68d..64401d0c2f 100644 --- a/execution_engine_testing/tests/src/test/private_chain.rs +++ b/execution_engine_testing/tests/src/test/private_chain.rs @@ -155,8 +155,8 @@ static DEFUALT_PRIVATE_CHAIN_EXEC_CONFIG: Lazy = Lazy::new(|| { static DEFAULT_PRIVATE_CHAIN_GENESIS: Lazy = Lazy::new(|| { GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_PROTOCOL_VERSION, DEFUALT_PRIVATE_CHAIN_EXEC_CONFIG.clone(), DEFAULT_CHAINSPEC_REGISTRY.clone(), ) diff --git a/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs b/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs index 4b5eff5b1b..aa9bc3373b 100644 --- a/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs +++ b/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs @@ -1,3 +1,5 @@ +use std::collections::BTreeSet; + use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_BLOCK_TIME, DEFAULT_PROPOSER_ADDR, DEFAULT_PROTOCOL_VERSION, @@ -7,8 +9,6 @@ use casper_types::{ account::AccountHash, system::handle_payment::ACCUMULATION_PURSE_KEY, EntityAddr, EraId, FeeHandling, Key, ProtocolVersion, RuntimeArgs, U512, }; -use once_cell::sync::Lazy; -use std::collections::BTreeSet; use crate::{ lmdb_fixture, @@ -16,14 +16,12 @@ use crate::{ wasm_utils, }; -static OLD_PROTOCOL_VERSION: Lazy = Lazy::new(|| *DEFAULT_PROTOCOL_VERSION); -static NEW_PROTOCOL_VERSION: Lazy = Lazy::new(|| { - ProtocolVersion::from_parts( - OLD_PROTOCOL_VERSION.value().major, - OLD_PROTOCOL_VERSION.value().minor, - OLD_PROTOCOL_VERSION.value().patch + 1, - ) -}); +const OLD_PROTOCOL_VERSION: ProtocolVersion = DEFAULT_PROTOCOL_VERSION; +const NEW_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::from_parts( + OLD_PROTOCOL_VERSION.value().major, + OLD_PROTOCOL_VERSION.value().minor, + OLD_PROTOCOL_VERSION.value().patch + 1, +); #[ignore] #[test] @@ -212,7 +210,7 @@ fn should_distribute_accumulated_fees_to_admins() { let mut administrative_accounts: BTreeSet = BTreeSet::new(); administrative_accounts.insert(*DEFAULT_ADMIN_ACCOUNT_ADDR); - let result = builder.distribute_fees(None, *DEFAULT_PROTOCOL_VERSION, DEFAULT_BLOCK_TIME); + let result = builder.distribute_fees(None, DEFAULT_PROTOCOL_VERSION, DEFAULT_BLOCK_TIME); assert!(result.is_success(), "expected success not: {:?}", result); @@ -267,8 +265,8 @@ fn should_accumulate_fees_after_upgrade() { let mut upgrade_request = { UpgradeRequestBuilder::new() - .with_current_protocol_version(*OLD_PROTOCOL_VERSION) - .with_new_protocol_version(*NEW_PROTOCOL_VERSION) + .with_current_protocol_version(OLD_PROTOCOL_VERSION) + .with_new_protocol_version(NEW_PROTOCOL_VERSION) .with_activation_point(EraId::default()) .with_fee_handling(FeeHandling::Accumulate) .build() diff --git a/execution_engine_testing/tests/src/test/private_chain/management.rs b/execution_engine_testing/tests/src/test/private_chain/management.rs index 7f6aeac3b9..3088246360 100644 --- a/execution_engine_testing/tests/src/test/private_chain/management.rs +++ b/execution_engine_testing/tests/src/test/private_chain/management.rs @@ -110,8 +110,8 @@ fn should_not_run_genesis_with_duplicated_administrator_accounts() { .build(); let modified_genesis_request = GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_PROTOCOL_VERSION, genesis_config, DEFAULT_CHAINSPEC_REGISTRY.clone(), ); diff --git a/execution_engine_testing/tests/src/test/private_chain/restricted_auction.rs b/execution_engine_testing/tests/src/test/private_chain/restricted_auction.rs index 0e522b6188..e779f3d3af 100644 --- a/execution_engine_testing/tests/src/test/private_chain/restricted_auction.rs +++ b/execution_engine_testing/tests/src/test/private_chain/restricted_auction.rs @@ -23,13 +23,13 @@ fn should_not_distribute_rewards_but_compute_next_set() { for _ in 0..3 { builder.distribute( None, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_PROTOCOL_VERSION, IntoIterator::into_iter([(VALIDATOR_1_PUBLIC_KEY.clone(), U512::from(0))]).collect(), DEFAULT_BLOCK_TIME, ); let step_request = StepRequestBuilder::new() .with_parent_state_hash(builder.get_post_state_hash()) - .with_protocol_version(*DEFAULT_PROTOCOL_VERSION) + .with_protocol_version(DEFAULT_PROTOCOL_VERSION) .with_next_era_id(builder.get_era().successor()) .with_era_end_timestamp_millis(timestamp_millis) .with_run_auction(true) @@ -49,14 +49,14 @@ fn should_not_distribute_rewards_but_compute_next_set() { builder.distribute( None, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_PROTOCOL_VERSION, IntoIterator::into_iter([(VALIDATOR_1_PUBLIC_KEY.clone(), U512::from(0))]).collect(), DEFAULT_BLOCK_TIME, ); let step_request = StepRequestBuilder::new() .with_parent_state_hash(builder.get_post_state_hash()) - .with_protocol_version(*DEFAULT_PROTOCOL_VERSION) + .with_protocol_version(DEFAULT_PROTOCOL_VERSION) .with_reward_item(RewardItem::new( VALIDATOR_1_PUBLIC_KEY.clone(), VALIDATOR_1_REWARD_FACTOR, diff --git a/execution_engine_testing/tests/src/test/regression/ee_966.rs b/execution_engine_testing/tests/src/test/regression/ee_966.rs index 310c185eb8..b229b339c2 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_966.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_966.rs @@ -31,13 +31,11 @@ static DOUBLED_WASM_MEMORY_LIMIT: Lazy = Lazy::new(|| { MessageLimits::default(), ) }); -static NEW_PROTOCOL_VERSION: Lazy = Lazy::new(|| { - ProtocolVersion::from_parts( - DEFAULT_PROTOCOL_VERSION.value().major, - DEFAULT_PROTOCOL_VERSION.value().minor, - DEFAULT_PROTOCOL_VERSION.value().patch + 1, - ) -}); +const NEW_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::from_parts( + DEFAULT_PROTOCOL_VERSION.value().major, + DEFAULT_PROTOCOL_VERSION.value().minor, + DEFAULT_PROTOCOL_VERSION.value().patch + 1, +); fn make_session_code_with_memory_pages(initial_pages: u32, max_pages: Option) -> Vec { let module = builder::module() @@ -261,8 +259,8 @@ fn should_run_ee_966_regression_when_growing_mem_after_upgrade() { // let mut upgrade_request = UpgradeRequestBuilder::new() - .with_current_protocol_version(*DEFAULT_PROTOCOL_VERSION) - .with_new_protocol_version(*NEW_PROTOCOL_VERSION) + .with_current_protocol_version(DEFAULT_PROTOCOL_VERSION) + .with_new_protocol_version(NEW_PROTOCOL_VERSION) .with_activation_point(DEFAULT_ACTIVATION_POINT) .build(); diff --git a/execution_engine_testing/tests/src/test/regression/gh_2280.rs b/execution_engine_testing/tests/src/test/regression/gh_2280.rs index d7291ef42a..da44a029e8 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_2280.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_2280.rs @@ -45,14 +45,12 @@ const TOKEN_AMOUNT: u64 = 1_000_000; const ARG_PURSE_NAME: &str = "purse_name"; const TEST_PURSE_NAME: &str = "test"; -static OLD_PROTOCOL_VERSION: Lazy = Lazy::new(|| *DEFAULT_PROTOCOL_VERSION); -static NEW_PROTOCOL_VERSION: Lazy = Lazy::new(|| { - ProtocolVersion::from_parts( - OLD_PROTOCOL_VERSION.value().major, - OLD_PROTOCOL_VERSION.value().minor, - OLD_PROTOCOL_VERSION.value().patch + 1, - ) -}); +const OLD_PROTOCOL_VERSION: ProtocolVersion = DEFAULT_PROTOCOL_VERSION; +const NEW_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::from_parts( + OLD_PROTOCOL_VERSION.value().major, + OLD_PROTOCOL_VERSION.value().minor, + OLD_PROTOCOL_VERSION.value().patch + 1, +); const DEFAULT_ACTIVATION_POINT: EraId = EraId::new(1); const HOST_FUNCTION_COST_CHANGE: HostFunctionCost = 13_730_593; // random prime number @@ -720,8 +718,8 @@ fn make_wasm_config( fn make_upgrade_request() -> ProtocolUpgradeConfig { UpgradeRequestBuilder::new() - .with_current_protocol_version(*OLD_PROTOCOL_VERSION) - .with_new_protocol_version(*NEW_PROTOCOL_VERSION) + .with_current_protocol_version(OLD_PROTOCOL_VERSION) + .with_new_protocol_version(NEW_PROTOCOL_VERSION) .with_activation_point(DEFAULT_ACTIVATION_POINT) .build() } diff --git a/execution_engine_testing/tests/src/test/regression/gh_3208.rs b/execution_engine_testing/tests/src/test/regression/gh_3208.rs index d4a28dcb4d..6f972cbf99 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_3208.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_3208.rs @@ -133,7 +133,7 @@ fn should_initialize_default_vesting_schedule() { StepRequestBuilder::default() .with_era_end_timestamp_millis(era_end_timestamp_millis) .with_parent_state_hash(builder.get_post_state_hash()) - .with_protocol_version(*DEFAULT_PROTOCOL_VERSION) + .with_protocol_version(DEFAULT_PROTOCOL_VERSION) .build(), ) .is_success(), @@ -171,8 +171,8 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule() }; let genesis_request = GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_PROTOCOL_VERSION, exec_config, DEFAULT_CHAINSPEC_REGISTRY.clone(), ); @@ -258,7 +258,7 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule() StepRequestBuilder::default() .with_era_end_timestamp_millis(era_end_timestamp_millis) .with_parent_state_hash(builder.get_post_state_hash()) - .with_protocol_version(*DEFAULT_PROTOCOL_VERSION) + .with_protocol_version(DEFAULT_PROTOCOL_VERSION) .with_run_auction(true) .build(), ) @@ -274,7 +274,7 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule() StepRequestBuilder::default() .with_era_end_timestamp_millis(era_end_timestamp_millis) .with_parent_state_hash(builder.get_post_state_hash()) - .with_protocol_version(*DEFAULT_PROTOCOL_VERSION) + .with_protocol_version(DEFAULT_PROTOCOL_VERSION) .with_run_auction(true) .build(), ) @@ -303,8 +303,8 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule_a }; let genesis_request = GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_PROTOCOL_VERSION, exec_config, DEFAULT_CHAINSPEC_REGISTRY.clone(), ); @@ -337,7 +337,7 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule_a StepRequestBuilder::default() .with_era_end_timestamp_millis(era_end_timestamp_millis) .with_parent_state_hash(builder.get_post_state_hash()) - .with_protocol_version(*DEFAULT_PROTOCOL_VERSION) + .with_protocol_version(DEFAULT_PROTOCOL_VERSION) .with_run_auction(true) .build(), ) diff --git a/execution_engine_testing/tests/src/test/regression/gov_116.rs b/execution_engine_testing/tests/src/test/regression/gov_116.rs index 70777a87e2..c46ae5e674 100644 --- a/execution_engine_testing/tests/src/test/regression/gov_116.rs +++ b/execution_engine_testing/tests/src/test/regression/gov_116.rs @@ -251,8 +251,8 @@ fn should_retain_genesis_validator_slot_protection() { .build(); GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_PROTOCOL_VERSION, exec_config, DEFAULT_CHAINSPEC_REGISTRY.clone(), ) diff --git a/execution_engine_testing/tests/src/test/regression/gov_74.rs b/execution_engine_testing/tests/src/test/regression/gov_74.rs index 365bc05af7..0e5aa180d2 100644 --- a/execution_engine_testing/tests/src/test/regression/gov_74.rs +++ b/execution_engine_testing/tests/src/test/regression/gov_74.rs @@ -1,5 +1,3 @@ -use once_cell::sync::Lazy; - use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_PROTOCOL_VERSION, PRODUCTION_RUN_GENESIS_REQUEST, @@ -17,15 +15,12 @@ const ARITY_INTERPRETER_LIMIT: usize = DEFAULT_MAX_PARAMETER_COUNT as usize; const DEFAULT_ACTIVATION_POINT: EraId = EraId::new(1); const I32_WAT_TYPE: &str = "i64"; const NEW_WASM_STACK_HEIGHT: u32 = 16; - -static OLD_PROTOCOL_VERSION: Lazy = Lazy::new(|| *DEFAULT_PROTOCOL_VERSION); -static NEW_PROTOCOL_VERSION: Lazy = Lazy::new(|| { - ProtocolVersion::from_parts( - OLD_PROTOCOL_VERSION.value().major, - OLD_PROTOCOL_VERSION.value().minor, - OLD_PROTOCOL_VERSION.value().patch + 1, - ) -}); +const OLD_PROTOCOL_VERSION: ProtocolVersion = DEFAULT_PROTOCOL_VERSION; +const NEW_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::from_parts( + OLD_PROTOCOL_VERSION.value().major, + OLD_PROTOCOL_VERSION.value().minor, + OLD_PROTOCOL_VERSION.value().patch + 1, +); fn initialize_builder() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); @@ -111,8 +106,8 @@ fn should_observe_stack_height_limit() { builder.with_chainspec(updated_chainspec); let mut upgrade_request = UpgradeRequestBuilder::new() - .with_current_protocol_version(*OLD_PROTOCOL_VERSION) - .with_new_protocol_version(*NEW_PROTOCOL_VERSION) + .with_current_protocol_version(OLD_PROTOCOL_VERSION) + .with_new_protocol_version(NEW_PROTOCOL_VERSION) .with_activation_point(DEFAULT_ACTIVATION_POINT) .build(); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220221.rs b/execution_engine_testing/tests/src/test/regression/regression_20220221.rs index 9c3cead1a3..cd1eca7db0 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220221.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220221.rs @@ -1,5 +1,3 @@ -use once_cell::sync::Lazy; - use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, StepRequestBuilder, TransferRequestBuilder, UpgradeRequestBuilder, DEFAULT_AUCTION_DELAY, DEFAULT_GENESIS_TIMESTAMP_MILLIS, @@ -17,14 +15,12 @@ const VALIDATOR_STAKE: u64 = 1_000_000_000; const DEFAULT_ACTIVATION_POINT: EraId = EraId::new(1); -static OLD_PROTOCOL_VERSION: Lazy = Lazy::new(|| *DEFAULT_PROTOCOL_VERSION); -static NEW_PROTOCOL_VERSION: Lazy = Lazy::new(|| { - ProtocolVersion::from_parts( - OLD_PROTOCOL_VERSION.value().major, - OLD_PROTOCOL_VERSION.value().minor, - OLD_PROTOCOL_VERSION.value().patch + 1, - ) -}); +const OLD_PROTOCOL_VERSION: ProtocolVersion = DEFAULT_PROTOCOL_VERSION; +const NEW_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::from_parts( + OLD_PROTOCOL_VERSION.value().major, + OLD_PROTOCOL_VERSION.value().minor, + OLD_PROTOCOL_VERSION.value().patch + 1, +); fn generate_secret_keys() -> impl Iterator { (1u64..).map(|i| { @@ -56,8 +52,8 @@ fn regression_20220221_should_distribute_to_many_validators() { let mut upgrade_request = UpgradeRequestBuilder::default() .with_new_validator_slots(DEFAULT_MAX_RUNTIME_CALL_STACK_HEIGHT + 1) .with_pre_state_hash(builder.get_post_state_hash()) - .with_current_protocol_version(*OLD_PROTOCOL_VERSION) - .with_new_protocol_version(*NEW_PROTOCOL_VERSION) + .with_current_protocol_version(OLD_PROTOCOL_VERSION) + .with_new_protocol_version(NEW_PROTOCOL_VERSION) .with_activation_point(DEFAULT_ACTIVATION_POINT) .build(); @@ -118,7 +114,7 @@ fn regression_20220221_should_distribute_to_many_validators() { let step_request = StepRequestBuilder::new() .with_parent_state_hash(builder.get_post_state_hash()) - .with_protocol_version(*NEW_PROTOCOL_VERSION) + .with_protocol_version(NEW_PROTOCOL_VERSION) // Next era id is used for returning future era validators, which we don't need to inspect // in this test. .with_next_era_id(era_id) diff --git a/execution_engine_testing/tests/src/test/storage_costs.rs b/execution_engine_testing/tests/src/test/storage_costs.rs index 9cc1a43e68..c66542ab79 100644 --- a/execution_engine_testing/tests/src/test/storage_costs.rs +++ b/execution_engine_testing/tests/src/test/storage_costs.rs @@ -118,7 +118,7 @@ fn initialize_isolated_storage_costs() -> LmdbWasmTestBuilder { builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); let mut upgrade_request = UpgradeRequestBuilder::new() - .with_current_protocol_version(*DEFAULT_PROTOCOL_VERSION) + .with_current_protocol_version(DEFAULT_PROTOCOL_VERSION) .with_new_protocol_version(*NEW_PROTOCOL_VERSION) .with_activation_point(DEFAULT_ACTIVATION_POINT) .build(); diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs b/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs index ef8083030d..d9c6bba0e1 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs @@ -704,8 +704,8 @@ fn should_get_first_seigniorage_recipients() { .with_locked_funds_period_millis(CASPER_LOCKED_FUNDS_PERIOD_MILLIS) .build(); let run_genesis_request = GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_PROTOCOL_VERSION, exec_config, DEFAULT_CHAINSPEC_REGISTRY.clone(), ); @@ -869,8 +869,8 @@ fn should_release_founder_stake() { .build(); GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_PROTOCOL_VERSION, exec_config, DEFAULT_CHAINSPEC_REGISTRY.clone(), ) @@ -2468,8 +2468,8 @@ fn should_not_undelegate_vfta_holder_stake() { .build(); GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_PROTOCOL_VERSION, exec_config, DEFAULT_CHAINSPEC_REGISTRY.clone(), ) @@ -2658,8 +2658,8 @@ fn should_release_vfta_holder_stake() { .build(); GenesisRequest::new( - *DEFAULT_GENESIS_CONFIG_HASH, - *DEFAULT_PROTOCOL_VERSION, + DEFAULT_GENESIS_CONFIG_HASH, + DEFAULT_PROTOCOL_VERSION, genesis_config, DEFAULT_CHAINSPEC_REGISTRY.clone(), ) diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs b/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs index ed2a0ee4f8..d1f9eedb09 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs @@ -3043,7 +3043,7 @@ fn should_distribute_delegation_rate_full_after_upgrading() { let new_seigniorage_multiplier = Ratio::new_raw(1, 10); let new_round_seigniorage_rate = DEFAULT_ROUND_SEIGNIORAGE_RATE * new_seigniorage_multiplier; - let old_protocol_version = *DEFAULT_PROTOCOL_VERSION; + let old_protocol_version = DEFAULT_PROTOCOL_VERSION; let sem_ver = old_protocol_version.value(); let new_protocol_version = ProtocolVersion::from_parts(sem_ver.major, sem_ver.minor, sem_ver.patch + 1); diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs b/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs index 7046e97fc0..4feb05e03f 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs @@ -549,7 +549,7 @@ fn should_run_successful_unbond_funds_after_changing_unbonding_delay() { let new_unbonding_delay = DEFAULT_UNBONDING_DELAY + 5; - let old_protocol_version = *DEFAULT_PROTOCOL_VERSION; + let old_protocol_version = DEFAULT_PROTOCOL_VERSION; let sem_ver = old_protocol_version.value(); let new_protocol_version = ProtocolVersion::from_parts(sem_ver.major, sem_ver.minor, sem_ver.patch + 1); diff --git a/execution_engine_testing/tests/src/test/system_costs.rs b/execution_engine_testing/tests/src/test/system_costs.rs index 7c73f187b5..e931dc6402 100644 --- a/execution_engine_testing/tests/src/test/system_costs.rs +++ b/execution_engine_testing/tests/src/test/system_costs.rs @@ -46,14 +46,12 @@ const NEW_UNDELEGATE_COST: u32 = 2_500_000_000; const NEW_REDELEGATE_COST: u32 = 2_500_000_000; const DEFAULT_ACTIVATION_POINT: EraId = EraId::new(1); -static OLD_PROTOCOL_VERSION: Lazy = Lazy::new(|| *DEFAULT_PROTOCOL_VERSION); -static NEW_PROTOCOL_VERSION: Lazy = Lazy::new(|| { - ProtocolVersion::from_parts( - OLD_PROTOCOL_VERSION.value().major, - OLD_PROTOCOL_VERSION.value().minor, - OLD_PROTOCOL_VERSION.value().patch + 1, - ) -}); +const OLD_PROTOCOL_VERSION: ProtocolVersion = DEFAULT_PROTOCOL_VERSION; +const NEW_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::from_parts( + OLD_PROTOCOL_VERSION.value().major, + OLD_PROTOCOL_VERSION.value().minor, + OLD_PROTOCOL_VERSION.value().patch + 1, +); const ARG_PURSE_NAME: &str = "purse_name"; const NAMED_PURSE_NAME: &str = "purse_1"; @@ -185,8 +183,8 @@ fn upgraded_add_bid_and_withdraw_bid_have_expected_costs() { let mut upgrade_request = { UpgradeRequestBuilder::new() - .with_current_protocol_version(*OLD_PROTOCOL_VERSION) - .with_new_protocol_version(*NEW_PROTOCOL_VERSION) + .with_current_protocol_version(OLD_PROTOCOL_VERSION) + .with_new_protocol_version(NEW_PROTOCOL_VERSION) .with_activation_point(DEFAULT_ACTIVATION_POINT) .build() }; @@ -455,8 +453,8 @@ fn upgraded_delegate_and_undelegate_have_expected_costs() { let mut upgrade_request = { UpgradeRequestBuilder::new() - .with_current_protocol_version(*OLD_PROTOCOL_VERSION) - .with_new_protocol_version(*NEW_PROTOCOL_VERSION) + .with_current_protocol_version(OLD_PROTOCOL_VERSION) + .with_new_protocol_version(NEW_PROTOCOL_VERSION) .with_activation_point(DEFAULT_ACTIVATION_POINT) .build() }; @@ -900,8 +898,8 @@ fn should_verify_wasm_add_bid_wasm_cost_is_not_recursive() { let mut upgrade_request = { UpgradeRequestBuilder::new() - .with_current_protocol_version(*OLD_PROTOCOL_VERSION) - .with_new_protocol_version(*NEW_PROTOCOL_VERSION) + .with_current_protocol_version(OLD_PROTOCOL_VERSION) + .with_new_protocol_version(NEW_PROTOCOL_VERSION) .with_activation_point(DEFAULT_ACTIVATION_POINT) .build() }; diff --git a/execution_engine_testing/tests/src/test/wasmless_transfer.rs b/execution_engine_testing/tests/src/test/wasmless_transfer.rs index 1998f04e50..0fcf338785 100644 --- a/execution_engine_testing/tests/src/test/wasmless_transfer.rs +++ b/execution_engine_testing/tests/src/test/wasmless_transfer.rs @@ -868,7 +868,7 @@ fn transfer_wasmless_should_observe_upgraded_cost() { const DEFAULT_ACTIVATION_POINT: EraId = EraId::new(1); - let old_protocol_version = *DEFAULT_PROTOCOL_VERSION; + let old_protocol_version = DEFAULT_PROTOCOL_VERSION; let new_protocol_version = ProtocolVersion::from_parts( old_protocol_version.value().major, old_protocol_version.value().minor, @@ -884,7 +884,7 @@ fn transfer_wasmless_should_observe_upgraded_cost() { let mut upgrade_request = { UpgradeRequestBuilder::new() - .with_current_protocol_version(*DEFAULT_PROTOCOL_VERSION) + .with_current_protocol_version(DEFAULT_PROTOCOL_VERSION) .with_new_protocol_version(new_protocol_version) .with_activation_point(DEFAULT_ACTIVATION_POINT) .build() diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index fbf7427cac..95af2608c3 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -522,7 +522,7 @@ where .map_err(SpeculativeExecutionError::from) } UserRequest::Transfer(_transfer_request) => { - todo!("route native transactions to data access layer, but don't commit them"); + Err(SpeculativeExecutionError::NativeNotSupported) } } } diff --git a/node/src/components/contract_runtime/types.rs b/node/src/components/contract_runtime/types.rs index a013a81589..e811414391 100644 --- a/node/src/components/contract_runtime/types.rs +++ b/node/src/components/contract_runtime/types.rs @@ -188,6 +188,9 @@ pub enum SpeculativeExecutionError { /// An error that occurred while constructing the execution request. #[error(transparent)] EngineState(#[from] EngineStateError), + /// Native transactions are not supported. + #[error("native transactions cannot be speculatively executed")] + NativeNotSupported, } impl From for binary_port::ErrorCode { diff --git a/types/src/protocol_version.rs b/types/src/protocol_version.rs index 2651772fa4..7be95caae0 100644 --- a/types/src/protocol_version.rs +++ b/types/src/protocol_version.rs @@ -73,7 +73,7 @@ impl ProtocolVersion { } /// Returns the inner [`SemVer`]. - pub fn value(&self) -> SemVer { + pub const fn value(&self) -> SemVer { self.0 } From 889a27cbed69e5b044eebe31a2ee2c99a6b18ee5 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Fri, 8 Mar 2024 11:35:04 +0000 Subject: [PATCH 07/70] fixes after merge --- .../test_support/src/wasm_test_builder.rs | 17 ++++++++++++++--- .../tests/src/lmdb_fixture.rs | 1 + .../tests/src/test/explorer/faucet.rs | 8 ++++---- .../tests/src/test/regression/gh_3208.rs | 2 +- node/src/components/contract_runtime/types.rs | 3 +++ storage/src/system/mint/mint_native.rs | 13 +++++++------ storage/src/system/runtime_native.rs | 7 ------- 7 files changed, 30 insertions(+), 21 deletions(-) diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index 0f37c49b07..2786f3c8ae 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -337,6 +337,7 @@ impl LmdbWasmTestBuilder { fn create_or_open>( global_state_dir: T, chainspec: ChainspecConfig, + protocol_version: ProtocolVersion, mode: GlobalStateMode, ) -> Self { let _ = env_logger::try_init(); @@ -383,7 +384,8 @@ impl LmdbWasmTestBuilder { state: global_state, max_query_depth, }); - let engine_config = chainspec.engine_config(); + let mut engine_config = chainspec.engine_config(); + engine_config.set_protocol_version(protocol_version); let engine_state = ExecutionEngineV1::new(engine_config); let post_state_hash = mode.post_state_hash(); @@ -436,10 +438,16 @@ impl LmdbWasmTestBuilder { pub fn open + ?Sized>( data_dir: &T, chainspec: ChainspecConfig, + protocol_version: ProtocolVersion, post_state_hash: Digest, ) -> Self { let global_state_path = Self::global_state_dir(data_dir); - Self::open_raw(global_state_path, chainspec, post_state_hash) + Self::open_raw( + global_state_path, + chainspec, + protocol_version, + post_state_hash, + ) } /// Creates a new instance of builder using the supplied configurations, opening wrapped LMDBs @@ -448,11 +456,13 @@ impl LmdbWasmTestBuilder { pub fn open_raw>( global_state_dir: T, chainspec: ChainspecConfig, + protocol_version: ProtocolVersion, post_state_hash: Digest, ) -> Self { Self::create_or_open( global_state_dir, chainspec, + protocol_version, GlobalStateMode::Open(post_state_hash), ) } @@ -469,6 +479,7 @@ impl LmdbWasmTestBuilder { let mut builder = Self::create_or_open( temp_dir.path(), chainspec, + DEFAULT_PROTOCOL_VERSION, GlobalStateMode::Create(database_flags), ); @@ -536,7 +547,7 @@ impl LmdbWasmTestBuilder { self } - /// Runs a [`TransferRequest`]. + /// Runs a [`TransferRequest`] and commits the resulting effects. pub fn transfer_and_commit(&mut self, mut transfer_request: TransferRequest) -> &mut Self { let pre_state_hash = self.post_state_hash.expect("expected post_state_hash"); transfer_request.set_state_hash_and_config(pre_state_hash, self.native_runtime_config()); diff --git a/execution_engine_testing/tests/src/lmdb_fixture.rs b/execution_engine_testing/tests/src/lmdb_fixture.rs index ee7d2e6dee..2260c6fd4f 100644 --- a/execution_engine_testing/tests/src/lmdb_fixture.rs +++ b/execution_engine_testing/tests/src/lmdb_fixture.rs @@ -88,6 +88,7 @@ pub fn builder_from_global_state_fixture( LmdbWasmTestBuilder::open( &path_to_gs, ChainspecConfig::default(), + lmdb_fixture_state.genesis_protocol_version(), lmdb_fixture_state.post_state_hash, ), lmdb_fixture_state, diff --git a/execution_engine_testing/tests/src/test/explorer/faucet.rs b/execution_engine_testing/tests/src/test/explorer/faucet.rs index f82e463cef..74cbc2f984 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet.rs @@ -925,10 +925,10 @@ fn faucet_costs() { // This test will fail if execution costs vary. The expected costs should not be updated // without understanding why the cost has changed. If the costs do change, it should be // reflected in the "Costs by Entry Point" section of the faucet crate's README.md. - const EXPECTED_FAUCET_INSTALL_COST: u64 = 91_861_205_540; - const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_534_140; - const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_113_880; - const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_425_520; + const EXPECTED_FAUCET_INSTALL_COST: u64 = 91_881_365_540; + const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_727_890; + const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_307_630; + const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_774_270; let installer_account = AccountHash::new([1u8; 32]); let user_account: AccountHash = AccountHash::new([2u8; 32]); diff --git a/execution_engine_testing/tests/src/test/regression/gh_3208.rs b/execution_engine_testing/tests/src/test/regression/gh_3208.rs index 6f972cbf99..1e6b9973bf 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_3208.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_3208.rs @@ -399,7 +399,7 @@ mod fixture { StepRequestBuilder::default() .with_era_end_timestamp_millis(era_end_timestamp_millis) .with_parent_state_hash(builder.get_post_state_hash()) - .with_protocol_version(*DEFAULT_PROTOCOL_VERSION) + .with_protocol_version(DEFAULT_PROTOCOL_VERSION) .build(), ); }) diff --git a/node/src/components/contract_runtime/types.rs b/node/src/components/contract_runtime/types.rs index e811414391..edaa29fee2 100644 --- a/node/src/components/contract_runtime/types.rs +++ b/node/src/components/contract_runtime/types.rs @@ -198,6 +198,9 @@ impl From for binary_port::ErrorCode { match error { SpeculativeExecutionError::NewRequest(_) => binary_port::ErrorCode::InvalidTransaction, SpeculativeExecutionError::EngineState(error) => error.into(), + SpeculativeExecutionError::NativeNotSupported => { + binary_port::ErrorCode::UnsupportedRequest + } } } } diff --git a/storage/src/system/mint/mint_native.rs b/storage/src/system/mint/mint_native.rs index c6bef1a939..ab3104dbd7 100644 --- a/storage/src/system/mint/mint_native.rs +++ b/storage/src/system/mint/mint_native.rs @@ -8,7 +8,7 @@ use crate::{ runtime_provider::RuntimeProvider, storage_provider::StorageProvider, system_provider::SystemProvider, Mint, }, - runtime_native::RuntimeNative, + runtime_native::{Id, RuntimeNative}, }, tracking_copy::{TrackingCopyEntityExt, TrackingCopyExt}, }; @@ -16,9 +16,9 @@ use casper_types::{ account::AccountHash, bytesrepr::{FromBytes, ToBytes}, system::{mint::Error, Caller}, - AccessRights, AddressableEntity, CLTyped, CLValue, Gas, InitiatorAddr, Key, Phase, PublicKey, - StoredValue, SystemEntityRegistry, Transfer, TransferAddr, TransferV2, TransferV2Addr, URef, - U512, + AccessRights, AddressableEntity, CLTyped, CLValue, Digest, Gas, InitiatorAddr, Key, Phase, + PublicKey, StoredValue, SystemEntityRegistry, TransactionHash, TransactionV1Hash, Transfer, + TransferAddr, TransferV2, TransferV2Addr, URef, U512, }; impl RuntimeProvider for RuntimeNative @@ -218,8 +218,9 @@ where self.address_generator().create_address(), )); let key = Key::Transfer(transfer_addr); - let Some(txn_hash) = self.maybe_transaction_hash() else { - return Err(Error::RecordTransferFailure) + let txn_hash = match self.id() { + Id::Transaction(txn_hash) => *txn_hash, + Id::Seed(seed) => TransactionHash::V1(TransactionV1Hash::new(Digest::hash(seed))), }; let from = InitiatorAddr::AccountHash(self.get_caller()); let fee = Gas::zero(); // TODO diff --git a/storage/src/system/runtime_native.rs b/storage/src/system/runtime_native.rs index 5de9cb580e..0fd559076a 100644 --- a/storage/src/system/runtime_native.rs +++ b/storage/src/system/runtime_native.rs @@ -363,13 +363,6 @@ where &self.id } - pub fn maybe_transaction_hash(&self) -> Option { - match self.id { - Id::Transaction(ret) => Some(ret), - Id::Seed(_) => None, - } - } - pub fn phase(&self) -> Phase { self.phase } From 5f898f8e1141fd9dbd023818cd2b2ed91e1d8ab4 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Fri, 8 Mar 2024 11:53:04 +0000 Subject: [PATCH 08/70] further fixes after merge --- utils/global-state-update-gen/src/admins.rs | 8 +++++++- utils/global-state-update-gen/src/balances.rs | 8 +++++++- utils/global-state-update-gen/src/generic.rs | 8 +++++++- .../src/system_entity_registry.rs | 9 +++++++-- utils/global-state-update-gen/src/validators.rs | 8 +++++++- 5 files changed, 35 insertions(+), 6 deletions(-) diff --git a/utils/global-state-update-gen/src/admins.rs b/utils/global-state-update-gen/src/admins.rs index 23b5e0c4e0..4cc9fd63c2 100644 --- a/utils/global-state-update-gen/src/admins.rs +++ b/utils/global-state-update-gen/src/admins.rs @@ -1,4 +1,5 @@ use casper_engine_test_support::LmdbWasmTestBuilder; +use casper_execution_engine::engine_state::engine_config::DEFAULT_PROTOCOL_VERSION; use casper_types::{ account::Account, addressable_entity::NamedKeys, bytesrepr::ToBytes, system::mint, AccessRights, AsymmetricType, CLTyped, CLValue, Key, PublicKey, StoredValue, URef, U512, @@ -25,7 +26,12 @@ pub(crate) fn generate_admins(matches: &ArgMatches<'_>) { // Open the global state that should be in the supplied directory. let post_state_hash = hash_from_str(state_hash); - let test_builder = LmdbWasmTestBuilder::open_raw(data_dir, Default::default(), post_state_hash); + let test_builder = LmdbWasmTestBuilder::open_raw( + data_dir, + Default::default(), + DEFAULT_PROTOCOL_VERSION, + post_state_hash, + ); let admin_values = matches.values_of("admin").expect("at least one argument"); diff --git a/utils/global-state-update-gen/src/balances.rs b/utils/global-state-update-gen/src/balances.rs index dfc8450c39..e9a7a5d4a4 100644 --- a/utils/global-state-update-gen/src/balances.rs +++ b/utils/global-state-update-gen/src/balances.rs @@ -1,6 +1,7 @@ use clap::ArgMatches; use casper_engine_test_support::LmdbWasmTestBuilder; +use casper_execution_engine::engine_state::engine_config::DEFAULT_PROTOCOL_VERSION; use casper_types::{account::AccountHash, U512}; use crate::{ @@ -33,6 +34,11 @@ pub(crate) fn generate_balances_update(matches: &ArgMatches<'_>) { protocol_version, }; - let builder = LmdbWasmTestBuilder::open_raw(data_dir, Default::default(), state_hash); + let builder = LmdbWasmTestBuilder::open_raw( + data_dir, + Default::default(), + DEFAULT_PROTOCOL_VERSION, + state_hash, + ); update_from_config(builder, config); } diff --git a/utils/global-state-update-gen/src/generic.rs b/utils/global-state-update-gen/src/generic.rs index cbb6d81a26..075d4bba46 100644 --- a/utils/global-state-update-gen/src/generic.rs +++ b/utils/global-state-update-gen/src/generic.rs @@ -14,6 +14,7 @@ use clap::ArgMatches; use itertools::Itertools; use casper_engine_test_support::LmdbWasmTestBuilder; +use casper_execution_engine::engine_state::engine_config::DEFAULT_PROTOCOL_VERSION; use casper_types::{ system::auction::{ Bid, BidKind, BidsExt, Delegator, SeigniorageRecipient, SeigniorageRecipientsSnapshot, @@ -39,7 +40,12 @@ pub(crate) fn generate_generic_update(matches: &ArgMatches<'_>) { let config_bytes = fs::read(config_path).expect("couldn't read the config file"); let config: Config = toml::from_slice(&config_bytes).expect("couldn't parse the config file"); - let builder = LmdbWasmTestBuilder::open_raw(data_dir, Default::default(), state_hash); + let builder = LmdbWasmTestBuilder::open_raw( + data_dir, + Default::default(), + DEFAULT_PROTOCOL_VERSION, + state_hash, + ); update_from_config(builder, config); } diff --git a/utils/global-state-update-gen/src/system_entity_registry.rs b/utils/global-state-update-gen/src/system_entity_registry.rs index b245b2705e..12c0723280 100644 --- a/utils/global-state-update-gen/src/system_entity_registry.rs +++ b/utils/global-state-update-gen/src/system_entity_registry.rs @@ -4,6 +4,7 @@ use clap::ArgMatches; use lmdb::{self, Cursor, Environment, EnvironmentFlags, Transaction}; use casper_engine_test_support::LmdbWasmTestBuilder; +use casper_execution_engine::engine_state::engine_config::DEFAULT_PROTOCOL_VERSION; use casper_storage::{ data_access_layer::{ SystemEntityRegistryPayload, SystemEntityRegistryRequest, SystemEntityRegistrySelector, @@ -111,8 +112,12 @@ fn generate_system_entity_registry_using_protocol_data(data_dir: &Path) { } fn generate_system_entity_registry_using_global_state(data_dir: &Path, state_hash: &str) { - let builder = - LmdbWasmTestBuilder::open_raw(data_dir, Default::default(), hash_from_str(state_hash)); + let builder = LmdbWasmTestBuilder::open_raw( + data_dir, + Default::default(), + DEFAULT_PROTOCOL_VERSION, + hash_from_str(state_hash), + ); let registry_req = SystemEntityRegistryRequest::new( builder.get_post_state_hash(), diff --git a/utils/global-state-update-gen/src/validators.rs b/utils/global-state-update-gen/src/validators.rs index 8517d4f281..b3db70d084 100644 --- a/utils/global-state-update-gen/src/validators.rs +++ b/utils/global-state-update-gen/src/validators.rs @@ -1,4 +1,5 @@ use casper_engine_test_support::LmdbWasmTestBuilder; +use casper_execution_engine::engine_state::engine_config::DEFAULT_PROTOCOL_VERSION; use casper_types::{AsymmetricType, PublicKey, U512}; use clap::ArgMatches; @@ -59,6 +60,11 @@ pub(crate) fn generate_validators_update(matches: &ArgMatches<'_>) { protocol_version, }; - let builder = LmdbWasmTestBuilder::open_raw(data_dir, Default::default(), state_hash); + let builder = LmdbWasmTestBuilder::open_raw( + data_dir, + Default::default(), + DEFAULT_PROTOCOL_VERSION, + state_hash, + ); update_from_config(builder, config); } From e3354fa3d49623b8771b69a8527eaee1b440bdc5 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Fri, 8 Mar 2024 12:30:10 +0000 Subject: [PATCH 09/70] handle removal of transfer auto-commit functionality --- .../components/contract_runtime/operations.rs | 54 ++++++++----------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 95af2608c3..9d8c1c7651 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -158,7 +158,7 @@ pub fn execute_finalized_block( &system_costs, )?; - match request { + let (exec_result_and_msgs, should_commit) = match request { UserRequest::Execute(execute_request) => { let exec_result_and_msgs = execute( &scratch_state, @@ -166,47 +166,39 @@ pub fn execute_finalized_block( metrics.clone(), execute_request, )?; - trace!(%txn_hash, ?exec_result_and_msgs, "transaction execution result"); - // As for now a given state is expected to exist. - let new_state_root_hash = commit_execution_result( - &scratch_state, - metrics.clone(), - state_root_hash, - txn_hash, - &exec_result_and_msgs.execution_result, - )?; - execution_artifacts.push(ExecutionArtifact::new( - txn_hash, - txn_header, - ExecutionResult::from(exec_result_and_msgs.execution_result), - exec_result_and_msgs.messages, - )); - state_root_hash = new_state_root_hash; + (exec_result_and_msgs, true) } UserRequest::Transfer(transfer_request) => { let gas = transfer_request.gas(); - // native transfer auto-commits let transfer_result = data_access_layer.transfer(transfer_request); - // if let TransferResult::Success { - // post_state_hash, .. - // } = &transfer_result - // { - // state_root_hash = *post_state_hash; - // } trace!(%txn_hash, ?transfer_result, "native transfer result"); let Ok(exec_result) = EngineExecutionResult::from_transfer_result(transfer_result, gas) else { return Err(BlockExecutionError::RootNotFound(state_root_hash)); }; - let exec_result_and_msgs = ExecutionResultAndMessages::from(exec_result); - execution_artifacts.push(ExecutionArtifact::new( - txn_hash, - txn_header, - ExecutionResult::from(exec_result_and_msgs.execution_result), - exec_result_and_msgs.messages, - )); + (ExecutionResultAndMessages::from(exec_result), true) } + }; + + if should_commit { + let new_state_root_hash = commit_execution_result( + &scratch_state, + metrics.clone(), + state_root_hash, + txn_hash, + &exec_result_and_msgs.execution_result, + )?; + state_root_hash = new_state_root_hash; } + + let exec_result = ExecutionResult::from(exec_result_and_msgs.execution_result); + let msgs = exec_result_and_msgs.messages; + execution_artifacts.push(ExecutionArtifact::new( + txn_hash, + txn_header, + exec_result, + msgs, + )); } // Write the transaction approvals' and execution results' checksums to global state. From 6a4028286399b94a42e849377003df0bf331f50b Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Fri, 8 Mar 2024 16:49:22 +0000 Subject: [PATCH 10/70] handle native auction transactions --- .../src/engine_state/execution_result.rs | 50 +++-- execution_engine/src/runtime/mod.rs | 7 +- .../tests/src/test/regression/ee_1217.rs | 4 +- .../test/regression/regression_20210831.rs | 2 +- .../src/test/system_contracts/auction/bids.rs | 4 +- node/src/components/contract_runtime/error.rs | 9 +- .../components/contract_runtime/operations.rs | 172 ++++++++++------ .../contracts/client/activate-bid/src/main.rs | 6 +- .../test/ee-1217-regression/src/main.rs | 4 +- .../test/regression-20210831/src/main.rs | 14 +- storage/src/data_access_layer/bidding.rs | 188 ++++++++---------- storage/src/global_state/state/mod.rs | 22 +- storage/src/system/auction.rs | 7 +- types/src/system/auction/constants.rs | 4 - types/src/system/auction/entry_points.rs | 8 +- types/src/transaction.rs | 62 +----- .../transaction_v1_body/arg_handling.rs | 5 +- 17 files changed, 270 insertions(+), 298 deletions(-) diff --git a/execution_engine/src/engine_state/execution_result.rs b/execution_engine/src/engine_state/execution_result.rs index 9a3e89c696..51c2c35b72 100644 --- a/execution_engine/src/engine_state/execution_result.rs +++ b/execution_engine/src/engine_state/execution_result.rs @@ -1,9 +1,10 @@ //! Outcome of an `ExecutionRequest`. use std::collections::VecDeque; + use tracing::{debug, trace}; -use casper_storage::data_access_layer::TransferResult; +use casper_storage::data_access_layer::{BiddingResult, TransferResult}; use casper_types::{ bytesrepr::FromBytes, contract_messages::Messages, @@ -316,28 +317,41 @@ impl ExecutionResult { (None, self) } - /// A temporary measure to keep things functioning mid-refactor. - #[allow(clippy::result_unit_err)] - pub fn from_transfer_result(transfer_result: TransferResult, gas: Gas) -> Result { + /// Converts a transfer result to an execution result. + pub fn from_transfer_result(transfer_result: TransferResult, gas: Gas) -> Option { match transfer_result { - TransferResult::RootNotFound => { - Err(()) - } - // native transfer is auto-commit...but execution results does not currently allow - // for a post state hash to be returned. - TransferResult::Success { - transfers, effects, .. // post_state_hash - } => { - Ok(ExecutionResult::Success { - transfers, + TransferResult::RootNotFound => None, + TransferResult::Success { transfers, effects } => Some(ExecutionResult::Success { + transfers, + gas, + effects, + messages: Messages::default(), + }), + TransferResult::Failure(te) => { + Some(ExecutionResult::Failure { + error: Error::Transfer(te), + transfers: vec![], gas, - effects, + effects: Effects::default(), // currently not returning effects on failure messages: Messages::default(), }) } - TransferResult::Failure(te) => { - Ok(ExecutionResult::Failure { - error: Error::Transfer(te), + } + } + + /// Converts a bidding result to an execution result. + pub fn from_bidding_result(bidding_result: BiddingResult, gas: Gas) -> Option { + match bidding_result { + BiddingResult::RootNotFound => None, + BiddingResult::Success { effects, .. } => Some(ExecutionResult::Success { + transfers: vec![], + gas, + effects, + messages: Messages::default(), + }), + BiddingResult::Failure(te) => { + Some(ExecutionResult::Failure { + error: Error::TrackingCopy(te), transfers: vec![], gas, effects: Effects::default(), // currently not returning effects on failure diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index 19859d51b2..25c49642a5 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -985,12 +985,9 @@ where auction::METHOD_ACTIVATE_BID => (|| { runtime.charge_system_contract_call(auction_costs.activate_bid)?; - let validator_public_key: PublicKey = - Self::get_named_argument(runtime_args, auction::ARG_VALIDATOR_PUBLIC_KEY)?; + let validator = Self::get_named_argument(runtime_args, auction::ARG_VALIDATOR)?; - runtime - .activate_bid(validator_public_key) - .map_err(Self::reverter)?; + runtime.activate_bid(validator).map_err(Self::reverter)?; CLValue::from_t(()).map_err(Self::reverter) })(), diff --git a/execution_engine_testing/tests/src/test/regression/ee_1217.rs b/execution_engine_testing/tests/src/test/regression/ee_1217.rs index ff530caa2d..f5d64f1ff9 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1217.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1217.rs @@ -623,7 +623,7 @@ fn should_fail_to_activate_bid_from_stored_session_code() { None, CONTRACT_ACTIVATE_BID_ENTRYPOINT_SESSION, runtime_args! { - auction::ARG_VALIDATOR_PUBLIC_KEY => default_public_key_arg, + auction::ARG_VALIDATOR => default_public_key_arg, }, ) .build(); @@ -689,7 +689,7 @@ fn should_fail_to_activate_bid_from_stored_contract_code() { None, CONTRACT_ACTIVATE_BID_ENTRYPOINT_CONTRACT, runtime_args! { - auction::ARG_VALIDATOR_PUBLIC_KEY => default_public_key_arg, + auction::ARG_VALIDATOR => default_public_key_arg, }, ) .build(); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20210831.rs b/execution_engine_testing/tests/src/test/regression/regression_20210831.rs index c495e16efe..ff907fd06f 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20210831.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20210831.rs @@ -444,7 +444,7 @@ fn regression_20210831_should_fail_to_activate_bid() { let sender = *ACCOUNT_2_ADDR; let activate_bid_args = runtime_args! { - auction::ARG_VALIDATOR_PUBLIC_KEY => DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), + auction::ARG_VALIDATOR => DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), }; let activate_bid_request_1 = ExecuteRequestBuilder::contract_call_by_hash( diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs b/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs index d9c6bba0e1..eb31decaf1 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs @@ -1893,12 +1893,12 @@ fn should_undelegate_delegators_when_validator_fully_unbonds() { #[test] fn should_handle_evictions() { let activate_bid = |builder: &mut LmdbWasmTestBuilder, validator_public_key: PublicKey| { - const ARG_VALIDATOR_PUBLIC_KEY: &str = "validator_public_key"; + const ARG_VALIDATOR: &str = "validator"; let run_request = ExecuteRequestBuilder::standard( AccountHash::from(&validator_public_key), CONTRACT_ACTIVATE_BID, runtime_args! { - ARG_VALIDATOR_PUBLIC_KEY => validator_public_key, + ARG_VALIDATOR => validator_public_key, }, ) .build(); diff --git a/node/src/components/contract_runtime/error.rs b/node/src/components/contract_runtime/error.rs index 2f4ab869aa..0dcdf5b837 100644 --- a/node/src/components/contract_runtime/error.rs +++ b/node/src/components/contract_runtime/error.rs @@ -9,7 +9,9 @@ use casper_execution_engine::engine_state::{ Error as EngineStateError, NewRequestError as NewExecuteRequestError, }; use casper_storage::{ - data_access_layer::{BlockRewardsError, FeeError, StepError}, + data_access_layer::{ + bidding::InvalidAuctionRuntimeArgs, BlockRewardsError, FeeError, StepError, + }, global_state::error::Error as GlobalStateError, tracking_copy::TrackingCopyError, }; @@ -46,7 +48,7 @@ pub(crate) enum ContractRuntimeError { } /// Error returned if constructing a new user request fails. -#[derive(Copy, Clone, Eq, PartialEq, Error, Serialize, Debug)] +#[derive(Clone, Eq, PartialEq, Error, Serialize, Debug)] pub enum NewUserRequestError { /// The transaction is a native one, but the wrapped deploy is not a transfer. #[error("native transaction of deploy variant is not a transfer")] @@ -54,6 +56,9 @@ pub enum NewUserRequestError { /// The transaction is a native version 1 variant, but has a custom entry point. #[error("cannot use custom variant for entry point in native transaction v1 {0}")] InvalidEntryPoint(TransactionHash), + /// The transaction is a native auction one, but the runtime args are invalid. + #[error(transparent)] + InvalidAuctionRuntimeArgs(#[from] InvalidAuctionRuntimeArgs), /// Error constructing a new execution request. #[error(transparent)] Execute(#[from] NewExecuteRequestError), diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 9d8c1c7651..1f7836ed7f 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -10,9 +10,10 @@ use casper_execution_engine::engine_state::{ use casper_storage::{ block_store::types::ApprovalsHashes, data_access_layer::{ - BlockRewardsRequest, BlockRewardsResult, DataAccessLayer, EraValidatorsRequest, - EraValidatorsResult, EvictItem, FeeRequest, FeeResult, FlushRequest, PruneRequest, - PruneResult, StepRequest, StepResult, TransferRequest, + AuctionMethod, BiddingRequest, BiddingResult, BlockRewardsRequest, BlockRewardsResult, + DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, EvictItem, FeeRequest, + FeeResult, FlushRequest, PruneRequest, PruneResult, StepRequest, StepResult, + TransferRequest, }, global_state::state::{ lmdb::LmdbGlobalState, scratch::ScratchGlobalState, CommitProvider, ScratchProvider, @@ -169,15 +170,32 @@ pub fn execute_finalized_block( trace!(%txn_hash, ?exec_result_and_msgs, "transaction execution result"); (exec_result_and_msgs, true) } - UserRequest::Transfer(transfer_request) => { + UserRequest::Mint(transfer_request) => { let gas = transfer_request.gas(); - let transfer_result = data_access_layer.transfer(transfer_request); + let transfer_result = scratch_state.transfer(transfer_request); trace!(%txn_hash, ?transfer_result, "native transfer result"); - let Ok(exec_result) = EngineExecutionResult::from_transfer_result(transfer_result, gas) else { + let Some(exec_result) = EngineExecutionResult::from_transfer_result(transfer_result, gas) else { return Err(BlockExecutionError::RootNotFound(state_root_hash)); }; (ExecutionResultAndMessages::from(exec_result), true) } + UserRequest::Auction(bidding_request) => { + // NOTE: native auction transactions auto-commit. + let gas = auction_gas(bidding_request.auction_method(), &system_costs); + let bidding_result = scratch_state.bidding(bidding_request); + trace!(?txn_hash, ?bidding_result, "native auction result"); + if let BiddingResult::Success { + post_state_hash, .. + } = &bidding_result + { + state_root_hash = *post_state_hash; + } + + let Some(exec_result) = EngineExecutionResult::from_bidding_result(bidding_result, gas) else { + return Err(BlockExecutionError::RootNotFound(state_root_hash)); + }; + (ExecutionResultAndMessages::from(exec_result), false) + } }; if should_commit { @@ -513,7 +531,7 @@ where }) .map_err(SpeculativeExecutionError::from) } - UserRequest::Transfer(_transfer_request) => { + UserRequest::Mint(_) | UserRequest::Auction(_) => { Err(SpeculativeExecutionError::NativeNotSupported) } } @@ -631,7 +649,8 @@ pub(crate) fn compute_execution_results_checksum<'a>( enum UserRequest { Execute(ExecuteRequest), - Transfer(TransferRequest), + Mint(TransferRequest), + Auction(BiddingRequest), } impl UserRequest { @@ -644,61 +663,94 @@ impl UserRequest { native_runtime_config: NativeRuntimeConfig, system_costs: &SystemConfig, ) -> Result { - if txn.is_native_mint() { - let txn_hash = txn.hash(); - let initiator_addr = txn.initiator_addr(); - let authorization_keys = txn.signers(); - - let v1_txn = match txn { - Transaction::Deploy(deploy) => { - if !deploy.is_transfer() { - return Err(NewUserRequestError::ExpectedNativeTransferDeploy(txn_hash)); - } - let transfer_req = TransferRequest::with_runtime_args( - native_runtime_config, - state_hash, - block_time, - protocol_version, - txn_hash, - initiator_addr, - authorization_keys, - deploy.session().args().clone(), - Gas::new(system_costs.mint_costs().transfer), - ); - return Ok(UserRequest::Transfer(transfer_req)); - } - Transaction::V1(v1_txn) => v1_txn, - }; + if !txn.is_native() { + let execute_req = ExecuteRequest::new(state_hash, block_time, txn, proposer) + .map_err(NewUserRequestError::Execute)?; + return Ok(UserRequest::Execute(execute_req)); + } - match v1_txn.entry_point() { - TransactionEntryPoint::Custom(_) => { - return Err(NewUserRequestError::InvalidEntryPoint(txn_hash)); - } - TransactionEntryPoint::Transfer => { - let transfer_req = TransferRequest::with_runtime_args( - native_runtime_config, - state_hash, - block_time, - protocol_version, - txn_hash, - initiator_addr, - authorization_keys, - v1_txn.take_args(), - Gas::new(system_costs.mint_costs().transfer), - ); - return Ok(UserRequest::Transfer(transfer_req)); + let txn_hash = txn.hash(); + let initiator_addr = txn.initiator_addr(); + let authorization_keys = txn.signers(); + + // Return early for native deploy, i.e. a transfer. + let v1_txn = match txn { + Transaction::Deploy(deploy) => { + if !deploy.is_transfer() { + return Err(NewUserRequestError::ExpectedNativeTransferDeploy(txn_hash)); } - TransactionEntryPoint::AddBid => todo!("make auction request"), - TransactionEntryPoint::WithdrawBid => todo!("make auction request"), - TransactionEntryPoint::Delegate => todo!("make auction request"), - TransactionEntryPoint::Undelegate => todo!("make auction request"), - TransactionEntryPoint::Redelegate => todo!("make auction request"), - TransactionEntryPoint::ActivateBid => todo!("make auction request"), + let transfer_req = TransferRequest::with_runtime_args( + native_runtime_config, + state_hash, + block_time, + protocol_version, + txn_hash, + initiator_addr, + authorization_keys, + deploy.session().args().clone(), + Gas::new(system_costs.mint_costs().transfer), + ); + return Ok(UserRequest::Mint(transfer_req)); } - } + Transaction::V1(v1_txn) => v1_txn, + }; + + // Return early for native V1 mint transaction, i.e. a transfer. + let auction_method = match v1_txn.entry_point() { + TransactionEntryPoint::Custom(_) => { + return Err(NewUserRequestError::InvalidEntryPoint(txn_hash)); + } + TransactionEntryPoint::Transfer => { + let transfer_req = TransferRequest::with_runtime_args( + native_runtime_config, + state_hash, + block_time, + protocol_version, + txn_hash, + initiator_addr, + authorization_keys, + v1_txn.take_args(), + Gas::new(system_costs.mint_costs().transfer), + ); + return Ok(UserRequest::Mint(transfer_req)); + } + TransactionEntryPoint::AddBid => AuctionMethod::new_add_bid(v1_txn.args())?, + TransactionEntryPoint::WithdrawBid => AuctionMethod::new_withdraw_bid(v1_txn.args())?, + TransactionEntryPoint::Delegate => AuctionMethod::new_delegate( + v1_txn.args(), + native_runtime_config.max_delegators_per_validator(), + native_runtime_config.minimum_delegation_amount(), + )?, + TransactionEntryPoint::Undelegate => AuctionMethod::new_undelegate(v1_txn.args())?, + TransactionEntryPoint::Redelegate => AuctionMethod::new_redelegate( + v1_txn.args(), + native_runtime_config.minimum_delegation_amount(), + )?, + TransactionEntryPoint::ActivateBid => AuctionMethod::new_activate_bid(v1_txn.args())?, + }; + + // We're left with only native V1 auction transactions. + let bidding_req = BiddingRequest::new( + native_runtime_config, + state_hash, + block_time, + protocol_version, + txn_hash, + initiator_addr, + authorization_keys, + auction_method, + ); + Ok(UserRequest::Auction(bidding_req)) + } +} - let execute_req = ExecuteRequest::new(state_hash, block_time, txn, proposer) - .map_err(NewUserRequestError::Execute)?; - Ok(UserRequest::Execute(execute_req)) +fn auction_gas(method: &AuctionMethod, system_costs: &SystemConfig) -> Gas { + match method { + AuctionMethod::ActivateBid { .. } => Gas::new(system_costs.auction_costs().activate_bid), + AuctionMethod::AddBid { .. } => Gas::new(system_costs.auction_costs().add_bid), + AuctionMethod::WithdrawBid { .. } => Gas::new(system_costs.auction_costs().withdraw_bid), + AuctionMethod::Delegate { .. } => Gas::new(system_costs.auction_costs().delegate), + AuctionMethod::Undelegate { .. } => Gas::new(system_costs.auction_costs().undelegate), + AuctionMethod::Redelegate { .. } => Gas::new(system_costs.auction_costs().redelegate), } } diff --git a/smart_contracts/contracts/client/activate-bid/src/main.rs b/smart_contracts/contracts/client/activate-bid/src/main.rs index 327406e028..2e040b2aa6 100644 --- a/smart_contracts/contracts/client/activate-bid/src/main.rs +++ b/smart_contracts/contracts/client/activate-bid/src/main.rs @@ -4,12 +4,12 @@ use casper_contract::contract_api::{runtime, system}; use casper_types::{runtime_args, system::auction, PublicKey}; -const ARG_VALIDATOR_PUBLIC_KEY: &str = "validator_public_key"; +const ARG_VALIDATOR: &str = "validator"; fn activate_bid(public_key: PublicKey) { let contract_hash = system::get_auction(); let args = runtime_args! { - auction::ARG_VALIDATOR_PUBLIC_KEY => public_key, + auction::ARG_VALIDATOR => public_key, }; runtime::call_contract::<()>(contract_hash, auction::METHOD_ACTIVATE_BID, args); } @@ -17,6 +17,6 @@ fn activate_bid(public_key: PublicKey) { // Accepts a public key. Issues an activate-bid bid to the auction contract. #[no_mangle] pub extern "C" fn call() { - let public_key: PublicKey = runtime::get_named_arg(ARG_VALIDATOR_PUBLIC_KEY); + let public_key: PublicKey = runtime::get_named_arg(ARG_VALIDATOR); activate_bid(public_key); } diff --git a/smart_contracts/contracts/test/ee-1217-regression/src/main.rs b/smart_contracts/contracts/test/ee-1217-regression/src/main.rs index e73848d1e4..f80faa7527 100644 --- a/smart_contracts/contracts/test/ee-1217-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-1217-regression/src/main.rs @@ -68,10 +68,10 @@ pub extern "C" fn withdraw_bid_session() { } fn activate_bid() { - let public_key: PublicKey = runtime::get_named_arg(auction::ARG_VALIDATOR_PUBLIC_KEY); + let public_key: PublicKey = runtime::get_named_arg(auction::ARG_VALIDATOR); let auction = system::get_auction(); let args = runtime_args! { - auction::ARG_VALIDATOR_PUBLIC_KEY => public_key, + auction::ARG_VALIDATOR => public_key, }; runtime::call_contract::<()>(auction, auction::METHOD_ACTIVATE_BID, args); } diff --git a/smart_contracts/contracts/test/regression-20210831/src/main.rs b/smart_contracts/contracts/test/regression-20210831/src/main.rs index 9d3209575b..8007369039 100644 --- a/smart_contracts/contracts/test/regression-20210831/src/main.rs +++ b/smart_contracts/contracts/test/regression-20210831/src/main.rs @@ -85,10 +85,10 @@ fn forwarded_undelegate_args() -> RuntimeArgs { } fn forwarded_activate_bid_args() -> RuntimeArgs { - let validator_public_key: PublicKey = runtime::get_named_arg(auction::ARG_VALIDATOR_PUBLIC_KEY); + let validator_public_key: PublicKey = runtime::get_named_arg(auction::ARG_VALIDATOR); runtime_args! { - auction::ARG_VALIDATOR_PUBLIC_KEY => validator_public_key, + auction::ARG_VALIDATOR => validator_public_key, } } @@ -271,20 +271,14 @@ pub extern "C" fn call() { let activate_bid_proxy_call = EntryPoint::new( METHOD_ACTIVATE_BID_CALL, - vec![Parameter::new( - auction::ARG_VALIDATOR_PUBLIC_KEY, - CLType::PublicKey, - )], + vec![Parameter::new(auction::ARG_VALIDATOR, CLType::PublicKey)], CLType::Unit, EntryPointAccess::Public, EntryPointType::AddressableEntity, ); let activate_bid_proxy_call_1 = EntryPoint::new( METHOD_ACTIVATE_BID_CALL_1, - vec![Parameter::new( - auction::ARG_VALIDATOR_PUBLIC_KEY, - CLType::PublicKey, - )], + vec![Parameter::new(auction::ARG_VALIDATOR, CLType::PublicKey)], CLType::Unit, EntryPointAccess::Public, EntryPointType::AddressableEntity, diff --git a/storage/src/data_access_layer/bidding.rs b/storage/src/data_access_layer/bidding.rs index e46dcae41f..fa1fbfef7b 100644 --- a/storage/src/data_access_layer/bidding.rs +++ b/storage/src/data_access_layer/bidding.rs @@ -1,21 +1,42 @@ -use crate::{ - system::runtime_native::Config as NativeRuntimeConfig, tracking_copy::TrackingCopyError, -}; +use std::collections::BTreeSet; + +use serde::Serialize; +use thiserror::Error; +use tracing::error; + use casper_types::{ account::AccountHash, bytesrepr::FromBytes, execution::Effects, system::{auction, auction::DelegationRate}, - CLTyped, CLValue, Chainspec, Digest, ProtocolVersion, PublicKey, RuntimeArgs, - TransactionEntryPoint, TransactionHash, U512, + BlockTime, CLTyped, CLValue, CLValueError, Digest, InitiatorAddr, ProtocolVersion, PublicKey, + RuntimeArgs, TransactionHash, U512, }; -use std::collections::BTreeSet; -use tracing::error; + +use crate::{ + system::runtime_native::Config as NativeRuntimeConfig, tracking_copy::TrackingCopyError, +}; + +/// An error returned when constructing an [`AuctionMethod`] using invalid runtime args. +#[derive(Clone, Eq, PartialEq, Error, Serialize, Debug)] +pub enum InvalidAuctionRuntimeArgs { + /// Required arg missing. + #[error("missing '{0}' arg")] + MissingArg(String), + /// Failed to parse the given arg. + #[error("failed to parse '{arg}' arg: {error}")] + CLValue { + /// The arg name. + arg: String, + /// The failure. + error: CLValueError, + }, +} #[derive(Debug, Clone, PartialEq, Eq)] pub enum AuctionMethod { ActivateBid { - validator_public_key: PublicKey, + validator: PublicKey, }, AddBid { public_key: PublicKey, @@ -27,73 +48,33 @@ pub enum AuctionMethod { amount: U512, }, Delegate { - delegator_public_key: PublicKey, - validator_public_key: PublicKey, + delegator: PublicKey, + validator: PublicKey, amount: U512, max_delegators_per_validator: u32, minimum_delegation_amount: u64, }, Undelegate { - delegator_public_key: PublicKey, - validator_public_key: PublicKey, + delegator: PublicKey, + validator: PublicKey, amount: U512, }, Redelegate { - delegator_public_key: PublicKey, - validator_public_key: PublicKey, + delegator: PublicKey, + validator: PublicKey, amount: U512, new_validator: PublicKey, minimum_delegation_amount: u64, }, } -#[allow(clippy::result_unit_err)] impl AuctionMethod { - pub fn from_parts( - entry_point: TransactionEntryPoint, - runtime_args: &RuntimeArgs, - chainspec: &Chainspec, - ) -> Result { - match entry_point { - TransactionEntryPoint::Custom(_) | TransactionEntryPoint::Transfer => { - error!( - "attempt to get auction method using a non-auction entry point {}", - entry_point - ); - Err(()) - } - TransactionEntryPoint::ActivateBid => { - Self::activate_bid_from_args(runtime_args, chainspec) - } - TransactionEntryPoint::AddBid => Self::add_bid_from_args(runtime_args, chainspec), - TransactionEntryPoint::WithdrawBid => { - Self::withdraw_bid_from_args(runtime_args, chainspec) - } - TransactionEntryPoint::Delegate => Self::delegate_from_args(runtime_args, chainspec), - TransactionEntryPoint::Undelegate => { - Self::undelegate_from_args(runtime_args, chainspec) - } - TransactionEntryPoint::Redelegate => { - Self::redelegate_from_args(runtime_args, chainspec) - } - } - } - - pub fn activate_bid_from_args( - runtime_args: &RuntimeArgs, - _chainspec: &Chainspec, - ) -> Result { - let validator_public_key: PublicKey = - Self::get_named_argument(runtime_args, auction::ARG_VALIDATOR_PUBLIC_KEY)?; - Ok(Self::ActivateBid { - validator_public_key, - }) + pub fn new_activate_bid(runtime_args: &RuntimeArgs) -> Result { + let validator = Self::get_named_argument(runtime_args, auction::ARG_VALIDATOR)?; + Ok(Self::ActivateBid { validator }) } - pub fn add_bid_from_args( - runtime_args: &RuntimeArgs, - _chainspec: &Chainspec, - ) -> Result { + pub fn new_add_bid(runtime_args: &RuntimeArgs) -> Result { let public_key = Self::get_named_argument(runtime_args, auction::ARG_PUBLIC_KEY)?; let delegation_rate = Self::get_named_argument(runtime_args, auction::ARG_DELEGATION_RATE)?; let amount = Self::get_named_argument(runtime_args, auction::ARG_AMOUNT)?; @@ -104,79 +85,72 @@ impl AuctionMethod { }) } - pub fn withdraw_bid_from_args( - runtime_args: &RuntimeArgs, - _chainspec: &Chainspec, - ) -> Result { + pub fn new_withdraw_bid(runtime_args: &RuntimeArgs) -> Result { let public_key = Self::get_named_argument(runtime_args, auction::ARG_PUBLIC_KEY)?; let amount = Self::get_named_argument(runtime_args, auction::ARG_AMOUNT)?; Ok(Self::WithdrawBid { public_key, amount }) } - pub fn delegate_from_args( + pub fn new_delegate( runtime_args: &RuntimeArgs, - chainspec: &Chainspec, - ) -> Result { - let delegator_public_key = Self::get_named_argument(runtime_args, auction::ARG_DELEGATOR)?; - let validator_public_key = Self::get_named_argument(runtime_args, auction::ARG_VALIDATOR)?; + max_delegators_per_validator: u32, + minimum_delegation_amount: u64, + ) -> Result { + let delegator = Self::get_named_argument(runtime_args, auction::ARG_DELEGATOR)?; + let validator = Self::get_named_argument(runtime_args, auction::ARG_VALIDATOR)?; let amount = Self::get_named_argument(runtime_args, auction::ARG_AMOUNT)?; - let max_delegators_per_validator = chainspec.core_config.max_delegators_per_validator; - let minimum_delegation_amount = chainspec.core_config.minimum_delegation_amount; - Ok(Self::Delegate { - delegator_public_key, - validator_public_key, + delegator, + validator, amount, max_delegators_per_validator, minimum_delegation_amount, }) } - pub fn undelegate_from_args( - runtime_args: &RuntimeArgs, - _chainspec: &Chainspec, - ) -> Result { - let delegator_public_key = Self::get_named_argument(runtime_args, auction::ARG_DELEGATOR)?; - let validator_public_key = Self::get_named_argument(runtime_args, auction::ARG_VALIDATOR)?; + pub fn new_undelegate(runtime_args: &RuntimeArgs) -> Result { + let delegator = Self::get_named_argument(runtime_args, auction::ARG_DELEGATOR)?; + let validator = Self::get_named_argument(runtime_args, auction::ARG_VALIDATOR)?; let amount = Self::get_named_argument(runtime_args, auction::ARG_AMOUNT)?; Ok(Self::Undelegate { - delegator_public_key, - validator_public_key, + delegator, + validator, amount, }) } - pub fn redelegate_from_args( + pub fn new_redelegate( runtime_args: &RuntimeArgs, - chainspec: &Chainspec, - ) -> Result { - let delegator_public_key = Self::get_named_argument(runtime_args, auction::ARG_DELEGATOR)?; - let validator_public_key = Self::get_named_argument(runtime_args, auction::ARG_VALIDATOR)?; + minimum_delegation_amount: u64, + ) -> Result { + let delegator = Self::get_named_argument(runtime_args, auction::ARG_DELEGATOR)?; + let validator = Self::get_named_argument(runtime_args, auction::ARG_VALIDATOR)?; let amount = Self::get_named_argument(runtime_args, auction::ARG_AMOUNT)?; let new_validator = Self::get_named_argument(runtime_args, auction::ARG_NEW_VALIDATOR)?; - let minimum_delegation_amount = chainspec.core_config.minimum_delegation_amount; - Ok(Self::Redelegate { - delegator_public_key, - validator_public_key, + delegator, + validator, amount, new_validator, minimum_delegation_amount, }) } - fn get_named_argument(args: &RuntimeArgs, name: &str) -> Result { - let arg: CLValue = args.get(name).cloned().ok_or(())?; - match arg.into_t() { - Ok(val) => Ok(val), - Err(err) => { - error!("{:?}", err); - Err(()) - } - } + fn get_named_argument( + args: &RuntimeArgs, + name: &str, + ) -> Result { + let arg: &CLValue = args + .get(name) + .ok_or_else(|| InvalidAuctionRuntimeArgs::MissingArg(name.to_string()))?; + arg.to_t() + .map_err(|error| InvalidAuctionRuntimeArgs::CLValue { + arg: name.to_string(), + error, + }) } } @@ -187,7 +161,7 @@ pub struct BiddingRequest { /// State root hash. state_hash: Digest, /// Block time represented as a unix timestamp. - block_time: u64, + block_time: BlockTime, /// The protocol version. protocol_version: ProtocolVersion, /// The auction method. @@ -195,7 +169,7 @@ pub struct BiddingRequest { /// Transaction hash. transaction_hash: TransactionHash, /// Base account. - address: AccountHash, + initiator: InitiatorAddr, /// List of authorizing accounts. authorization_keys: BTreeSet, } @@ -206,10 +180,10 @@ impl BiddingRequest { pub fn new( config: NativeRuntimeConfig, state_hash: Digest, - block_time: u64, + block_time: BlockTime, protocol_version: ProtocolVersion, transaction_hash: TransactionHash, - address: AccountHash, + initiator: InitiatorAddr, authorization_keys: BTreeSet, auction_method: AuctionMethod, ) -> Self { @@ -219,7 +193,7 @@ impl BiddingRequest { block_time, protocol_version, transaction_hash, - address, + initiator, authorization_keys, auction_method, } @@ -237,16 +211,16 @@ impl BiddingRequest { self.protocol_version } - pub fn auction_method(&self) -> AuctionMethod { - self.auction_method.clone() + pub fn auction_method(&self) -> &AuctionMethod { + &self.auction_method } pub fn transaction_hash(&self) -> TransactionHash { self.transaction_hash } - pub fn address(&self) -> AccountHash { - self.address + pub fn initiator(&self) -> &InitiatorAddr { + &self.initiator } pub fn authorization_keys(&self) -> &BTreeSet { diff --git a/storage/src/global_state/state/mod.rs b/storage/src/global_state/state/mod.rs index ff43dda31a..457abbaec4 100644 --- a/storage/src/global_state/state/mod.rs +++ b/storage/src/global_state/state/mod.rs @@ -620,7 +620,7 @@ pub trait CommitProvider: StateProvider { let config = request.config(); let id = crate::system::runtime_native::Id::Transaction(request.transaction_hash()); - let initiating_address = request.address(); + let initiating_address = request.initiator().account_hash(); let authorization_keys = request.authorization_keys(); let transfer_config = config.transfer_config(); let administrative_accounts = transfer_config.administrative_accounts(); @@ -651,13 +651,11 @@ pub trait CommitProvider: StateProvider { Phase::Session, ); - let auction_method = request.auction_method(); + let auction_method = request.auction_method().clone(); let result = match auction_method { - AuctionMethod::ActivateBid { - validator_public_key, - } => runtime - .activate_bid(validator_public_key) + AuctionMethod::ActivateBid { validator } => runtime + .activate_bid(validator) .map(|_| AuctionMethodRet::Unit) .map_err(|auc_err| { TrackingCopyError::SystemContract(system::Error::Auction(auc_err)) @@ -677,8 +675,8 @@ pub trait CommitProvider: StateProvider { TrackingCopyError::SystemContract(system::Error::Auction(auc_err)) }), AuctionMethod::Delegate { - delegator_public_key, - validator_public_key, + delegator: delegator_public_key, + validator: validator_public_key, amount, max_delegators_per_validator, minimum_delegation_amount, @@ -693,8 +691,8 @@ pub trait CommitProvider: StateProvider { .map(AuctionMethodRet::UpdatedAmount) .map_err(TrackingCopyError::Api), AuctionMethod::Undelegate { - delegator_public_key, - validator_public_key, + delegator: delegator_public_key, + validator: validator_public_key, amount, } => runtime .undelegate(delegator_public_key, validator_public_key, amount) @@ -703,8 +701,8 @@ pub trait CommitProvider: StateProvider { TrackingCopyError::SystemContract(system::Error::Auction(auc_err)) }), AuctionMethod::Redelegate { - delegator_public_key, - validator_public_key, + delegator: delegator_public_key, + validator: validator_public_key, amount, new_validator, minimum_delegation_amount, diff --git a/storage/src/system/auction.rs b/storage/src/system/auction.rs index 61b2b8e44f..735962d190 100644 --- a/storage/src/system/auction.rs +++ b/storage/src/system/auction.rs @@ -683,15 +683,14 @@ pub trait Auction: /// Activates a given validator's bid. To be used when a validator has been marked as inactive /// by consensus (aka "evicted"). - fn activate_bid(&mut self, validator_public_key: PublicKey) -> Result<(), Error> { - let provided_account_hash = - AccountHash::from_public_key(&validator_public_key, |x| self.blake2b(x)); + fn activate_bid(&mut self, validator: PublicKey) -> Result<(), Error> { + let provided_account_hash = AccountHash::from_public_key(&validator, |x| self.blake2b(x)); if !self.is_allowed_session_caller(&provided_account_hash) { return Err(Error::InvalidContext); } - let key = BidAddr::from(validator_public_key).into(); + let key = BidAddr::from(validator).into(); if let Some(BidKind::Validator(mut validator_bid)) = self.read_bid(&key)? { validator_bid.activate(); self.write_bid(key, BidKind::Validator(validator_bid))?; diff --git a/types/src/system/auction/constants.rs b/types/src/system/auction/constants.rs index f3038f8e90..63b414bfab 100644 --- a/types/src/system/auction/constants.rs +++ b/types/src/system/auction/constants.rs @@ -36,10 +36,6 @@ pub const ARG_VALIDATOR_PUBLIC_KEYS: &str = "validator_public_keys"; pub const ARG_NEW_VALIDATOR: &str = "new_validator"; /// Named constant for `era_id`. pub const ARG_ERA_ID: &str = "era_id"; -/// Named constant for `validator_public_key`. -pub const ARG_VALIDATOR_PUBLIC_KEY: &str = "validator_public_key"; -/// Named constant for `delegator_public_key`. -pub const ARG_DELEGATOR_PUBLIC_KEY: &str = "delegator_public_key"; /// Named constant for `validator_slots` argument. pub const ARG_VALIDATOR_SLOTS: &str = VALIDATOR_SLOTS_KEY; /// Named constant for `mint_contract_package_hash` diff --git a/types/src/system/auction/entry_points.rs b/types/src/system/auction/entry_points.rs index 252550e548..717ed96620 100644 --- a/types/src/system/auction/entry_points.rs +++ b/types/src/system/auction/entry_points.rs @@ -2,9 +2,9 @@ use crate::{ system::auction::{ DelegationRate, ValidatorWeights, ARG_AMOUNT, ARG_DELEGATION_RATE, ARG_DELEGATOR, ARG_ERA_END_TIMESTAMP_MILLIS, ARG_NEW_VALIDATOR, ARG_PUBLIC_KEY, ARG_VALIDATOR, - ARG_VALIDATOR_PUBLIC_KEY, METHOD_ACTIVATE_BID, METHOD_ADD_BID, METHOD_DELEGATE, - METHOD_DISTRIBUTE, METHOD_GET_ERA_VALIDATORS, METHOD_READ_ERA_ID, METHOD_REDELEGATE, - METHOD_RUN_AUCTION, METHOD_SLASH, METHOD_UNDELEGATE, METHOD_WITHDRAW_BID, + METHOD_ACTIVATE_BID, METHOD_ADD_BID, METHOD_DELEGATE, METHOD_DISTRIBUTE, + METHOD_GET_ERA_VALIDATORS, METHOD_READ_ERA_ID, METHOD_REDELEGATE, METHOD_RUN_AUCTION, + METHOD_SLASH, METHOD_UNDELEGATE, METHOD_WITHDRAW_BID, }, CLType, CLTyped, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Parameter, PublicKey, U512, @@ -131,7 +131,7 @@ pub fn auction_entry_points() -> EntryPoints { let entry_point = EntryPoint::new( METHOD_ACTIVATE_BID, - vec![Parameter::new(ARG_VALIDATOR_PUBLIC_KEY, CLType::PublicKey)], + vec![Parameter::new(ARG_VALIDATOR, CLType::PublicKey)], CLType::Unit, EntryPointAccess::Public, EntryPointType::AddressableEntity, diff --git a/types/src/transaction.rs b/types/src/transaction.rs index b06bce2dec..5c3bf8cb33 100644 --- a/types/src/transaction.rs +++ b/types/src/transaction.rs @@ -229,67 +229,11 @@ impl Transaction { } } - /// Is this a native mint transaction. - pub fn is_native_mint(&self) -> bool { + /// Returns `true` if `self` represents a native transfer deploy or a native V1 transaction. + pub fn is_native(&self) -> bool { match self { Transaction::Deploy(deploy) => deploy.is_transfer(), - Transaction::V1(transaction_v1) => match transaction_v1.target() { - TransactionTarget::Stored { .. } | TransactionTarget::Session { .. } => false, - TransactionTarget::Native => { - &TransactionEntryPoint::Transfer == transaction_v1.entry_point() - } - }, - } - } - - /// Is this a native auction transaction. - pub fn is_native_auction(&self) -> bool { - match self { - Transaction::Deploy(_) => false, - Transaction::V1(transaction_v1) => match transaction_v1.target() { - TransactionTarget::Stored { .. } | TransactionTarget::Session { .. } => false, - TransactionTarget::Native => match transaction_v1.entry_point() { - TransactionEntryPoint::Custom(_) | TransactionEntryPoint::Transfer => false, - TransactionEntryPoint::AddBid - | TransactionEntryPoint::WithdrawBid - | TransactionEntryPoint::Delegate - | TransactionEntryPoint::Undelegate - | TransactionEntryPoint::Redelegate - | TransactionEntryPoint::ActivateBid => true, - }, - }, - } - } - - /// Authorization keys. - pub fn authorization_keys(&self) -> BTreeSet { - match self { - Transaction::Deploy(deploy) => deploy - .approvals() - .iter() - .map(|approval| approval.signer().to_account_hash()) - .collect(), - Transaction::V1(transaction_v1) => transaction_v1 - .approvals() - .iter() - .map(|approval| approval.signer().to_account_hash()) - .collect(), - } - } - - /// The session args. - pub fn session_args(&self) -> &RuntimeArgs { - match self { - Transaction::Deploy(deploy) => deploy.session().args(), - Transaction::V1(transaction_v1) => transaction_v1.body().args(), - } - } - - /// The entry point. - pub fn entry_point(&self) -> TransactionEntryPoint { - match self { - Transaction::Deploy(deploy) => deploy.session().entry_point_name().into(), - Transaction::V1(transaction_v1) => transaction_v1.entry_point().clone(), + Transaction::V1(v1_txn) => *v1_txn.target() == TransactionTarget::Native, } } diff --git a/types/src/transaction/transaction_v1/transaction_v1_body/arg_handling.rs b/types/src/transaction/transaction_v1/transaction_v1_body/arg_handling.rs index 677bf99f75..0175c13bbe 100644 --- a/types/src/transaction/transaction_v1/transaction_v1_body/arg_handling.rs +++ b/types/src/transaction/transaction_v1/transaction_v1_body/arg_handling.rs @@ -6,7 +6,7 @@ use super::super::TransactionV1ConfigFailure; use crate::{ account::AccountHash, bytesrepr::{FromBytes, ToBytes}, - system::auction::ARG_VALIDATOR_PUBLIC_KEY, + system::auction::ARG_VALIDATOR, CLType, CLTyped, CLValue, CLValueError, PublicKey, RuntimeArgs, TransferTarget, URef, U512, }; @@ -35,8 +35,7 @@ const REDELEGATE_ARG_VALIDATOR: RequiredArg = RequiredArg::new("valid const REDELEGATE_ARG_AMOUNT: RequiredArg = RequiredArg::new("amount"); const REDELEGATE_ARG_NEW_VALIDATOR: RequiredArg = RequiredArg::new("new_validator"); -const ACTIVATE_BID_ARG_VALIDATOR: RequiredArg = - RequiredArg::new(ARG_VALIDATOR_PUBLIC_KEY); +const ACTIVATE_BID_ARG_VALIDATOR: RequiredArg = RequiredArg::new(ARG_VALIDATOR); struct RequiredArg { name: &'static str, From d8cbbdfe05181fbe83a5f667364f18bd2a8ab052 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Fri, 8 Mar 2024 18:49:20 +0000 Subject: [PATCH 11/70] several minor cleanups --- execution_engine/src/engine_state/error.rs | 8 ++- .../src/engine_state/execution_kind.rs | 58 +++++++++---------- execution_engine/src/engine_state/mod.rs | 22 +++---- execution_engine/src/execution/executor.rs | 30 +++++----- execution_engine/src/runtime/mod.rs | 7 +-- execution_engine/src/runtime_context/mod.rs | 20 +++++-- execution_engine/src/runtime_context/tests.rs | 8 +-- .../test/contract_api/add_contract_version.rs | 2 +- .../tests/src/test/regression/ee_1129.rs | 10 ++-- types/src/byte_code.rs | 3 - types/src/lib.rs | 2 +- 11 files changed, 89 insertions(+), 81 deletions(-) diff --git a/execution_engine/src/engine_state/error.rs b/execution_engine/src/engine_state/error.rs index 2362fc3bfe..7a466bfc08 100644 --- a/execution_engine/src/engine_state/error.rs +++ b/execution_engine/src/engine_state/error.rs @@ -66,8 +66,8 @@ pub enum Error { #[error("Mint error: {0}")] Mint(String), /// Invalid key variant. - #[error("Unsupported key type")] - InvalidKeyVariant, + #[error("Unsupported key type: {0}")] + InvalidKeyVariant(Key), /// Protocol upgrade error. #[error("Protocol upgrade error: {0}")] ProtocolUpgrade(#[from] ProtocolUpgradeError), @@ -131,6 +131,9 @@ pub enum Error { /// Deprecated functionality. #[error("Deprecated: {0}")] Deprecated(String), + /// Failed to get the payment purse from the handle-payment named keys. + #[error("Failed to get the payment purse from the handle-payment named keys")] + FailedToGetPaymentPurse, } impl Error { @@ -198,7 +201,6 @@ impl From for binary_port::ErrorCode { Error::InvalidDeployItemVariant(_) => binary_port::ErrorCode::InvalidDeployItemVariant, Error::WasmPreprocessing(_) => binary_port::ErrorCode::WasmPreprocessing, Error::InvalidProtocolVersion(_) => binary_port::ErrorCode::UnsupportedProtocolVersion, - Error::Deploy => binary_port::ErrorCode::InvalidTransaction, _ => binary_port::ErrorCode::InternalError, } } diff --git a/execution_engine/src/engine_state/execution_kind.rs b/execution_engine/src/engine_state/execution_kind.rs index fdb59a9c2f..63b4261e90 100644 --- a/execution_engine/src/engine_state/execution_kind.rs +++ b/execution_engine/src/engine_state/execution_kind.rs @@ -14,11 +14,8 @@ use crate::{engine_state::error::Error, execution::ExecError}; /// The type of execution about to be performed. #[derive(Clone, Debug)] pub(crate) enum ExecutionKind<'a> { - /// Standard (non-specialized) Wasm bytes. - Standard { - module_bytes: &'a Bytes, - allow_casper_add_contract_version: bool, - }, + /// Standard (non-specialized) Wasm bytes related to a transaction of version 1 or later. + Standard(&'a Bytes), /// Wasm bytes which install a stored entity. Installer(&'a Bytes), /// Wasm bytes which upgrade a stored entity. @@ -32,15 +29,17 @@ pub(crate) enum ExecutionKind<'a> { /// Entry point. entry_point: String, }, + /// Standard (non-specialized) Wasm bytes related to a `Deploy`. + /// + /// This is equivalent to the `Standard` variant with the exception that this kind will be + /// allowed to install or upgrade stored entities to retain existing (pre-node 2.0) behavior. + Deploy(&'a Bytes), } impl<'a> ExecutionKind<'a> { /// Returns a new `Standard` variant of `ExecutionKind`. - pub fn new_standard(module_bytes: &'a Bytes, allow_casper_add_contract_version: bool) -> Self { - ExecutionKind::Standard { - module_bytes, - allow_casper_add_contract_version, - } + pub fn new_standard(module_bytes: &'a Bytes) -> Self { + ExecutionKind::Standard(module_bytes) } /// Returns a new `Installer` variant of `ExecutionKind`. @@ -58,26 +57,29 @@ impl<'a> ExecutionKind<'a> { ExecutionKind::Isolated(module_bytes) } + /// Returns a new `Deploy` variant of `ExecutionKind`. + pub fn new_deploy(module_bytes: &'a Bytes) -> Self { + ExecutionKind::Deploy(module_bytes) + } + /// Returns a new `Standard` variant of `ExecutionKind`, returning an error if the module bytes /// are empty. - pub fn new_for_payment(module_bytes: &'a Bytes) -> Result { + pub fn new_standard_for_payment(module_bytes: &'a Bytes) -> Result { if module_bytes.is_empty() { return Err(Error::EmptyCustomPaymentModuleBytes); } - Ok(ExecutionKind::Standard { - module_bytes, - allow_casper_add_contract_version: false, - }) + Ok(ExecutionKind::Standard(module_bytes)) } /// Returns a new `ExecutionKind` cloned from `self`, but converting any Wasm bytes variant to /// `Standard`, and returning an error if they are empty. pub fn convert_for_payment(&self) -> Result { match self { - ExecutionKind::Standard { module_bytes, .. } + ExecutionKind::Standard(module_bytes) | ExecutionKind::Installer(module_bytes) | ExecutionKind::Upgrader(module_bytes) - | ExecutionKind::Isolated(module_bytes) => Self::new_for_payment(module_bytes), + | ExecutionKind::Isolated(module_bytes) + | ExecutionKind::Deploy(module_bytes) => Self::new_standard_for_payment(module_bytes), ExecutionKind::Stored { .. } => Ok(self.clone()), } } @@ -85,7 +87,7 @@ impl<'a> ExecutionKind<'a> { /// Returns a new contract variant of `ExecutionKind`. pub fn new_stored( tracking_copy: &mut TrackingCopy, - target: TransactionInvocationTarget, + target: &TransactionInvocationTarget, entry_point: String, named_keys: &NamedKeys, protocol_version: ProtocolVersion, @@ -94,23 +96,22 @@ impl<'a> ExecutionKind<'a> { R: StateReader, { let entity_hash = match target { - TransactionInvocationTarget::InvocableEntity(addr) => AddressableEntityHash::new(addr), + TransactionInvocationTarget::InvocableEntity(addr) => AddressableEntityHash::new(*addr), TransactionInvocationTarget::InvocableEntityAlias(alias) => { let entity_key = named_keys - .get(&alias) - .cloned() - .ok_or_else(|| Error::Exec(ExecError::NamedKeyNotFound(alias)))?; + .get(alias) + .ok_or_else(|| Error::Exec(ExecError::NamedKeyNotFound(alias.clone())))?; match entity_key { - Key::Hash(hash) => AddressableEntityHash::new(hash), + Key::Hash(hash) => AddressableEntityHash::new(*hash), Key::AddressableEntity(entity_addr) => { AddressableEntityHash::new(entity_addr.value()) } - _ => return Err(Error::InvalidKeyVariant), + _ => return Err(Error::InvalidKeyVariant(*entity_key)), } } TransactionInvocationTarget::Package { addr, version } => { - let package_hash = PackageHash::from(addr); + let package_hash = PackageHash::from(*addr); let package = tracking_copy.get_package(package_hash)?; let maybe_version_key = @@ -140,13 +141,12 @@ impl<'a> ExecutionKind<'a> { } TransactionInvocationTarget::PackageAlias { alias, version } => { let package_key = named_keys - .get(&alias) - .cloned() + .get(alias) .ok_or_else(|| Error::Exec(ExecError::NamedKeyNotFound(alias.to_string())))?; let package_hash = match package_key { - Key::Hash(hash) | Key::Package(hash) => PackageHash::new(hash), - _ => return Err(Error::InvalidKeyVariant), + Key::Hash(hash) | Key::Package(hash) => PackageHash::new(*hash), + _ => return Err(Error::InvalidKeyVariant(*package_key)), }; let package = tracking_copy.get_package(package_hash)?; diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index 561ae1e911..03f836ad0a 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -171,7 +171,7 @@ impl ExecutionEngineV1 { let session_execution_kind = match &session { Session::Stored(invocation_target) => match ExecutionKind::new_stored( &mut *tracking_copy.borrow_mut(), - invocation_target.clone(), + invocation_target, session_entry_point, &entity_named_keys, protocol_version, @@ -184,7 +184,7 @@ impl ExecutionEngineV1 { Session::ModuleBytes { kind: TransactionSessionKind::Standard, module_bytes, - } => ExecutionKind::new_standard(module_bytes, false), + } => ExecutionKind::new_standard(module_bytes), Session::ModuleBytes { kind: TransactionSessionKind::Installer, module_bytes, @@ -200,9 +200,7 @@ impl ExecutionEngineV1 { module_bytes, .. } => ExecutionKind::new_isolated(module_bytes), - Session::DeployModuleBytes(module_bytes) => { - ExecutionKind::new_standard(module_bytes, true) - } + Session::DeployModuleBytes(module_bytes) => ExecutionKind::new_deploy(module_bytes), }; // Get account main purse balance key @@ -276,12 +274,12 @@ impl ExecutionEngineV1 { // payment_code_spec_6: system contract validity let Some(payment_purse_key) = handle_payment_named_keys.get(handle_payment::PAYMENT_PURSE_KEY).copied() else { - return Ok(ExecutionResult::precondition_failure(Error::Deploy)); + return Ok(ExecutionResult::precondition_failure(Error::FailedToGetPaymentPurse)); }; let payment_purse_uref = payment_purse_key .into_uref() - .ok_or(Error::InvalidKeyVariant)?; + .ok_or_else(|| Error::InvalidKeyVariant(payment_purse_key))?; // [`ExecutionResultBuilder`] handles merging of multiple execution results let mut execution_result_builder = execution_result::ExecutionResultBuilder::new(); @@ -332,7 +330,7 @@ impl ExecutionEngineV1 { Payment::Stored(invocation_target) => { match ExecutionKind::new_stored( &mut *tracking_copy.borrow_mut(), - invocation_target.clone(), + invocation_target, payment_entry_point, &entity_named_keys, protocol_version, @@ -344,7 +342,7 @@ impl ExecutionEngineV1 { } } Payment::ModuleBytes(module_bytes) => { - match ExecutionKind::new_for_payment(module_bytes) { + match ExecutionKind::new_standard_for_payment(module_bytes) { Ok(execution_kind) => Some(execution_kind), Err(error) => { return Ok(ExecutionResult::precondition_failure(error)); @@ -466,7 +464,11 @@ impl ExecutionEngineV1 { let payment_purse_key: Key = match handle_payment_named_keys.get(handle_payment::PAYMENT_PURSE_KEY) { Some(key) => *key, - None => return Ok(ExecutionResult::precondition_failure(Error::Deploy)), + None => { + return Ok(ExecutionResult::precondition_failure( + Error::FailedToGetPaymentPurse, + )) + } }; let purse_balance_key = match tracking_copy .borrow_mut() diff --git a/execution_engine/src/execution/executor.rs b/execution_engine/src/execution/executor.rs index 92f3efe6fe..bc6e7c80da 100644 --- a/execution_engine/src/execution/executor.rs +++ b/execution_engine/src/execution/executor.rs @@ -22,7 +22,7 @@ use crate::{ }, execution::ExecError, runtime::{Runtime, RuntimeStack}, - runtime_context::RuntimeContext, + runtime_context::{CallingAddContractVersion, RuntimeContext}, }; const ARG_AMOUNT: &str = "amount"; @@ -89,15 +89,14 @@ impl Executor { let entity_key = Key::addressable_entity_key(entity_kind.tag(), entity_hash); - let allow_casper_add_contract_version = match execution_kind { - ExecutionKind::Standard { - allow_casper_add_contract_version, - .. - } => allow_casper_add_contract_version, + let calling_add_contract_version = match execution_kind { ExecutionKind::Installer(_) | ExecutionKind::Upgrader(_) - | ExecutionKind::Stored { .. } => true, - ExecutionKind::Isolated(_) => false, + | ExecutionKind::Stored { .. } + | ExecutionKind::Deploy(_) => CallingAddContractVersion::Allowed, + ExecutionKind::Standard(_) | ExecutionKind::Isolated(_) => { + CallingAddContractVersion::Forbidden + } }; let context = self.create_runtime_context( @@ -118,16 +117,17 @@ impl Executor { gas_limit, spending_limit, EntryPointType::Session, - allow_casper_add_contract_version, + calling_add_contract_version, ); let mut runtime = Runtime::new(context); let result = match execution_kind { - ExecutionKind::Standard { module_bytes, .. } + ExecutionKind::Standard(module_bytes) | ExecutionKind::Installer(module_bytes) | ExecutionKind::Upgrader(module_bytes) - | ExecutionKind::Isolated(module_bytes) => { + | ExecutionKind::Isolated(module_bytes) + | ExecutionKind::Deploy(module_bytes) => { runtime.execute_module_bytes(module_bytes, stack) } ExecutionKind::Stored { @@ -239,7 +239,7 @@ impl Executor { let access_rights = contract.extract_access_rights(entity_hash, &named_keys); let entity_key = entity_addr.into(); - let allow_casper_add_contract_version = false; + let calling_add_contract_version = CallingAddContractVersion::Forbidden; let runtime_context = self.create_runtime_context( &mut named_keys, entity, @@ -258,7 +258,7 @@ impl Executor { gas_limit, remaining_spending_limit, EntryPointType::AddressableEntity, - allow_casper_add_contract_version, + calling_add_contract_version, ); let mut runtime = Runtime::new(runtime_context); @@ -321,7 +321,7 @@ impl Executor { gas_limit: Gas, remaining_spending_limit: U512, entry_point_type: EntryPointType, - allow_casper_add_contract_version: bool, + calling_add_contract_version: CallingAddContractVersion, ) -> RuntimeContext<'a, R> where R: StateReader, @@ -350,7 +350,7 @@ impl Executor { transfers, remaining_spending_limit, entry_point_type, - allow_casper_add_contract_version, + calling_add_contract_version, ) } diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index 25c49642a5..44e4bac28b 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -3529,10 +3529,9 @@ where #[cfg(feature = "test-support")] fn dump_runtime_stack_info(instance: casper_wasmi::ModuleRef, max_stack_height: u32) { let globals = instance.globals(); - let Some(current_runtime_call_stack_height) = globals.last() - else { - return; - }; + let Some(current_runtime_call_stack_height) = globals.last() else { + return; + }; if let RuntimeValue::I32(current_runtime_call_stack_height) = current_runtime_call_stack_height.get() diff --git a/execution_engine/src/runtime_context/mod.rs b/execution_engine/src/runtime_context/mod.rs index 82b1405645..48f30620d0 100644 --- a/execution_engine/src/runtime_context/mod.rs +++ b/execution_engine/src/runtime_context/mod.rs @@ -44,6 +44,15 @@ use crate::{engine_state::EngineConfig, execution::ExecError}; /// Number of bytes returned from the `random_bytes` function. pub const RANDOM_BYTES_COUNT: usize = 32; +/// Whether the execution is permitted to call FFI `casper_add_contract_version()` or not. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum CallingAddContractVersion { + /// Allowed. + Allowed, + /// Forbidden. + Forbidden, +} + /// Holds information specific to the deployed contract. pub struct RuntimeContext<'a, R> { tracking_copy: Rc>>, @@ -73,8 +82,7 @@ pub struct RuntimeContext<'a, R> { entity_kind: EntityKind, account_hash: AccountHash, emit_message_cost: U512, - // Whether the execution is permitted to call FFI `casper_add_contract_version()` or not. - allow_casper_add_contract_version: bool, + calling_add_contract_version: CallingAddContractVersion, } impl<'a, R> RuntimeContext<'a, R> @@ -106,7 +114,7 @@ where transfers: Vec, remaining_spending_limit: U512, entry_point_type: EntryPointType, - allow_casper_add_contract_version: bool, + calling_add_contract_version: CallingAddContractVersion, ) -> Self { let emit_message_cost = engine_config .wasm_config() @@ -136,7 +144,7 @@ where remaining_spending_limit, entity_kind, emit_message_cost, - allow_casper_add_contract_version, + calling_add_contract_version, } } @@ -192,7 +200,7 @@ where remaining_spending_limit, entity_kind, emit_message_cost: self.emit_message_cost, - allow_casper_add_contract_version: self.allow_casper_add_contract_version, + calling_add_contract_version: self.calling_add_contract_version, } } @@ -345,7 +353,7 @@ where /// Returns `true` if the execution is permitted to call `casper_add_contract_version()`. pub fn allow_casper_add_contract_version(&self) -> bool { - self.allow_casper_add_contract_version + self.calling_add_contract_version == CallingAddContractVersion::Allowed } /// Generates new deterministic hash for uses as an address. diff --git a/execution_engine/src/runtime_context/tests.rs b/execution_engine/src/runtime_context/tests.rs index 1d82e2fc5b..e6a7efb3be 100644 --- a/execution_engine/src/runtime_context/tests.rs +++ b/execution_engine/src/runtime_context/tests.rs @@ -25,7 +25,7 @@ use casper_types::{ }; use tempfile::TempDir; -use super::{ExecError, RuntimeContext}; +use super::{CallingAddContractVersion, ExecError, RuntimeContext}; use crate::engine_state::EngineConfig; const TXN_HASH_RAW: [u8; 32] = [1u8; 32]; @@ -163,7 +163,7 @@ fn new_runtime_context<'a>( Vec::default(), U512::MAX, EntryPointType::Session, - false, + CallingAddContractVersion::Forbidden, ); (runtime_context, tempdir) @@ -431,7 +431,7 @@ fn contract_key_addable_valid() { Vec::default(), U512::zero(), EntryPointType::Session, - false, + CallingAddContractVersion::Forbidden, ); assert!(runtime_context @@ -490,7 +490,7 @@ fn contract_key_addable_invalid() { Vec::default(), U512::zero(), EntryPointType::Session, - false, + CallingAddContractVersion::Forbidden, ); let result = runtime_context.metered_add_gs(contract_key, named_uref_tuple); diff --git a/execution_engine_testing/tests/src/test/contract_api/add_contract_version.rs b/execution_engine_testing/tests/src/test/contract_api/add_contract_version.rs index efc21fcf9f..893d5a6954 100644 --- a/execution_engine_testing/tests/src/test/contract_api/add_contract_version.rs +++ b/execution_engine_testing/tests/src/test/contract_api/add_contract_version.rs @@ -87,6 +87,6 @@ fn should_disallow_add_contract_version_via_transaction_v1_standard() { #[ignore] #[test] -fn should_allow_add_contract_version_via_transaction_v1_isolated() { +fn should_disallow_add_contract_version_via_transaction_v1_isolated() { try_add_contract_version(TransactionSessionKind::Isolated, false) } diff --git a/execution_engine_testing/tests/src/test/regression/ee_1129.rs b/execution_engine_testing/tests/src/test/regression/ee_1129.rs index d4f38d4c76..e01027e304 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1129.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1129.rs @@ -2,7 +2,7 @@ use casper_wasm::builder; use num_traits::Zero; use once_cell::sync::Lazy; -use casper_types::{GenesisAccount, GenesisValidator}; +use casper_types::{GenesisAccount, GenesisValidator, Key}; use casper_engine_test_support::{ utils, DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNTS, @@ -253,7 +253,7 @@ fn should_not_panic_when_calling_session_contract_by_uref() { .expect("should have error"); assert!( - matches!(error, Error::InvalidKeyVariant), + matches!(error, Error::InvalidKeyVariant(Key::URef(_))), "Unexpected error {:?}", error ); @@ -297,7 +297,7 @@ fn should_not_panic_when_calling_payment_contract_by_uref() { .expect("should have error"); assert!( - matches!(error, Error::InvalidKeyVariant), + matches!(error, Error::InvalidKeyVariant(Key::URef(_))), "Unexpected error {:?}", error ); @@ -348,7 +348,7 @@ fn should_not_panic_when_calling_contract_package_by_uref() { .expect("should have error"); assert!( - matches!(error, Error::InvalidKeyVariant), + matches!(error, Error::InvalidKeyVariant(Key::URef(_))), "Unexpected error {:?}", error ); @@ -396,7 +396,7 @@ fn should_not_panic_when_calling_payment_versioned_contract_by_uref() { .cloned() .expect("should have error"); assert!( - matches!(error, Error::InvalidKeyVariant), + matches!(error, Error::InvalidKeyVariant(Key::URef(_))), "Unexpected error {:?}", error ); diff --git a/types/src/byte_code.rs b/types/src/byte_code.rs index a09d1db6db..773102c28a 100644 --- a/types/src/byte_code.rs +++ b/types/src/byte_code.rs @@ -30,9 +30,6 @@ const BYTE_CODE_PREFIX: &str = "byte-code-"; const V1_WASM_PREFIX: &str = "v1-wasm-"; const EMPTY_PREFIX: &str = "empty-"; -/// A special contract wasm hash for contracts representing Accounts. -pub const ACCOUNT_BYTE_CODE_HASH: ByteCodeHash = ByteCodeHash::new([0; 32]); - /// Associated error type of `TryFrom<&[u8]>` for `ByteCodeHash`. #[derive(Debug)] pub struct TryFromSliceForContractHashError(()); diff --git a/types/src/lib.rs b/types/src/lib.rs index 72bc86b5a0..f189504417 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -108,7 +108,7 @@ pub use block::{ #[cfg(any(all(feature = "std", feature = "testing"), test))] pub use block::{TestBlockBuilder, TestBlockV1Builder}; pub use block_time::{BlockTime, BLOCKTIME_SERIALIZED_LENGTH}; -pub use byte_code::{ByteCode, ByteCodeAddr, ByteCodeHash, ByteCodeKind, ACCOUNT_BYTE_CODE_HASH}; +pub use byte_code::{ByteCode, ByteCodeAddr, ByteCodeHash, ByteCodeKind}; #[cfg(any(feature = "std", test))] pub use chainspec::{ AccountConfig, AccountsConfig, ActivationPoint, AdministratorAccount, AuctionCosts, From 56bd342ef632ebb3e7e6a03219d4ba91e32885b3 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Sun, 10 Mar 2024 00:57:48 -0800 Subject: [PATCH 12/70] extracting bits from runtime context / precursor cleanup --- execution_engine/src/engine_state/mod.rs | 9 +- execution_engine/src/execution/executor.rs | 29 +- .../src/runtime/auction_internal.rs | 4 +- execution_engine/src/runtime/mint_internal.rs | 2 +- execution_engine/src/runtime/mod.rs | 22 +- execution_engine/src/runtime_context/mod.rs | 265 ++++------- execution_engine/src/runtime_context/tests.rs | 136 +++--- .../src/test/contract_api/get_call_stack.rs | 20 +- node/src/reactor/main_reactor/tests.rs | 11 +- resources/test/sse_data_schema.json | 10 +- .../explorer/faucet-stored/src/main.rs | 6 +- .../host-function-metrics/src/lib.rs | 2 +- .../test/add-gas-subcall/src/main.rs | 2 +- .../test/contract-context/src/main.rs | 4 +- .../contracts/test/contract-funds/src/main.rs | 2 +- .../contract-messages-emitter/src/main.rs | 8 +- .../contract-messages-upgrader/src/main.rs | 6 +- .../test/counter-factory/src/main.rs | 8 +- .../test/deserialize-error/src/main.rs | 2 +- .../contracts/test/dictionary/src/lib.rs | 10 +- .../do-nothing-stored-upgrader/src/main.rs | 2 +- .../test/do-nothing-stored/src/main.rs | 2 +- .../test/ee-1071-regression/src/main.rs | 2 +- .../test/ee-1129-regression/src/main.rs | 2 +- .../test/ee-1217-regression/src/main.rs | 20 +- .../test/ee-401-regression/src/main.rs | 2 +- .../test/ee-441-rng-state/src/main.rs | 4 +- .../test/ee-572-regression-create/src/main.rs | 2 +- .../test/ee-599-regression/src/main.rs | 8 +- .../test/ee-771-regression/src/main.rs | 4 +- .../test/expensive-calculation/src/main.rs | 2 +- .../src/main.rs | 4 +- .../test/get-caller-subcall/src/main.rs | 2 +- .../test/gh-1470-regression/src/bin/main.rs | 4 +- .../test/gh-1688-regression/src/main.rs | 2 +- .../test/gh-2280-regression/src/main.rs | 2 +- .../test/gh-3097-regression/src/main.rs | 2 +- .../contracts/test/groups/src/main.rs | 20 +- .../test/host-function-costs/src/main.rs | 26 +- .../contracts/test/manage-groups/src/main.rs | 8 +- .../test/measure-gas-subcall/src/main.rs | 4 +- .../test/multisig-authorization/src/main.rs | 4 +- .../test/named-keys-stored/src/main.rs | 8 +- .../test/ordered-transforms/src/main.rs | 2 +- .../purse-holder-stored-upgrader/src/main.rs | 6 +- .../test/purse-holder-stored/src/main.rs | 4 +- .../test/regression-20210707/src/main.rs | 10 +- .../test/regression-20210831/src/main.rs | 20 +- .../test/regression-20220204/src/main.rs | 4 +- .../test/regression-20220211/src/main.rs | 20 +- .../test/regression_20211110/src/main.rs | 2 +- .../contracts/test/ret-uref/src/main.rs | 6 +- .../contracts/test/storage-costs/src/main.rs | 24 +- .../test/test-payment-stored/src/main.rs | 2 +- .../src/main.rs | 2 +- .../src/main.rs | 2 +- .../upgrade-threshold-upgrader/src/main.rs | 6 +- .../test/upgrade-threshold/src/main.rs | 4 +- .../tutorial/counter-installer/src/main.rs | 4 +- storage/src/tracking_copy/error.rs | 15 +- storage/src/tracking_copy/ext_entity.rs | 111 +++-- types/benches/bytesrepr_bench.rs | 2 +- types/src/addressable_entity.rs | 60 ++- types/src/block_time.rs | 6 +- types/src/contracts.rs | 4 +- types/src/gens.rs | 16 +- types/src/key.rs | 449 ++++++++++++------ types/src/lib.rs | 1 + types/src/package.rs | 4 +- types/src/system/auction/entry_points.rs | 22 +- .../src/system/handle_payment/entry_points.rs | 10 +- types/src/system/mint.rs | 2 + types/src/system/mint/balance_hold.rs | 267 +++++++++++ types/src/system/mint/entry_points.rs | 14 +- .../system/standard_payment/entry_points.rs | 2 +- utils/validation/src/generators.rs | 2 +- 76 files changed, 1082 insertions(+), 717 deletions(-) create mode 100644 types/src/system/mint/balance_hold.rs diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index 7424797da9..b3accdfffe 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -20,7 +20,6 @@ use casper_storage::{ }; use casper_types::{ - addressable_entity::EntityKind, system::{ handle_payment::{self}, HANDLE_PAYMENT, @@ -242,9 +241,7 @@ impl ExecutionEngineV1 { } }; - let entity_kind = entity.entity_kind(); - - let entity_addr = EntityAddr::new_with_tag(entity_kind, entity_hash.value()); + let entity_addr = entity.entity_addr(entity_hash); let entity_named_keys = match tracking_copy .borrow_mut() @@ -432,7 +429,6 @@ impl ExecutionEngineV1 { match executor.exec_standard_payment( payment_args, &entity, - entity_kind, authorization_keys.clone(), account_hash, blocktime, @@ -465,7 +461,6 @@ impl ExecutionEngineV1 { payment_args, entity_hash, &entity, - entity_kind, &mut payment_named_keys, payment_access_rights, authorization_keys.clone(), @@ -633,7 +628,6 @@ impl ExecutionEngineV1 { session_args, entity_hash, &entity, - entity_kind, &mut session_named_keys, session_access_rights, authorization_keys.clone(), @@ -785,7 +779,6 @@ impl ExecutionEngineV1 { DirectSystemContractCall::FinalizePayment, handle_payment_args, &system_addressable_entity, - EntityKind::Account(system_account_hash), authorization_keys, system_account_hash, blocktime, diff --git a/execution_engine/src/execution/executor.rs b/execution_engine/src/execution/executor.rs index d845832dbd..e853c7ef7d 100644 --- a/execution_engine/src/execution/executor.rs +++ b/execution_engine/src/execution/executor.rs @@ -8,12 +8,12 @@ use casper_storage::{ }; use casper_types::{ account::AccountHash, - addressable_entity::{EntityKind, NamedKeys}, + addressable_entity::NamedKeys, bytesrepr::FromBytes, system::{handle_payment, mint, HANDLE_PAYMENT, MINT}, AddressableEntity, AddressableEntityHash, ApiError, BlockTime, CLTyped, ContextAccessRights, - DeployHash, EntityAddr, EntryPointType, Gas, Key, Phase, ProtocolVersion, RuntimeArgs, - StoredValue, Tagged, URef, U512, + DeployHash, EntryPointType, Gas, Key, Phase, ProtocolVersion, RuntimeArgs, StoredValue, Tagged, + URef, U512, }; use crate::{ @@ -55,7 +55,6 @@ impl Executor { args: RuntimeArgs, entity_hash: AddressableEntityHash, entity: &AddressableEntity, - entity_kind: EntityKind, named_keys: &mut NamedKeys, access_rights: ContextAccessRights, authorization_keys: BTreeSet, @@ -83,7 +82,7 @@ impl Executor { Rc::new(RefCell::new(generator)) }; - let entity_key = Key::addressable_entity_key(entity_kind.tag(), entity_hash); + let entity_key = Key::addressable_entity_key(entity.entity_kind().tag(), entity_hash); let context = self.create_runtime_context( named_keys, @@ -91,7 +90,6 @@ impl Executor { entity_key, authorization_keys, access_rights, - entity_kind, account_hash, address_generator, tracking_copy, @@ -102,7 +100,7 @@ impl Executor { args.clone(), gas_limit, spending_limit, - EntryPointType::Session, + EntryPointType::Caller, ); let mut runtime = Runtime::new(context); @@ -147,7 +145,6 @@ impl Executor { direct_system_contract_call: DirectSystemContractCall, runtime_args: RuntimeArgs, entity: &AddressableEntity, - entity_kind: EntityKind, authorization_keys: BTreeSet, account_hash: AccountHash, blocktime: BlockTime, @@ -207,7 +204,8 @@ impl Executor { Err(error) => return (None, ExecutionResult::precondition_failure(error.into())), }; - let entity_addr = EntityAddr::new_with_tag(entity_kind, entity_hash.value()); + let entity_addr = entity.entity_addr(entity_hash); + let entity_key = entity_addr.into(); let mut named_keys = match tracking_copy.borrow_mut().get_named_keys(entity_addr) { Ok(named_key) => named_key, @@ -215,14 +213,12 @@ impl Executor { }; let access_rights = contract.extract_access_rights(entity_hash, &named_keys); - let entity_key = entity_addr.into(); let runtime_context = self.create_runtime_context( &mut named_keys, entity, entity_key, authorization_keys, access_rights, - entity_kind, account_hash, address_generator, tracking_copy, @@ -233,7 +229,7 @@ impl Executor { runtime_args.clone(), gas_limit, remaining_spending_limit, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let mut runtime = Runtime::new(runtime_context); @@ -284,7 +280,6 @@ impl Executor { entity_key: Key, authorization_keys: BTreeSet, access_rights: ContextAccessRights, - entity_kind: EntityKind, account_hash: AccountHash, address_generator: Rc>, tracking_copy: Rc>>, @@ -309,7 +304,6 @@ impl Executor { entity_key, authorization_keys, access_rights, - entity_kind, account_hash, address_generator, tracking_copy, @@ -333,7 +327,6 @@ impl Executor { &self, payment_args: RuntimeArgs, entity: &AddressableEntity, - entity_kind: EntityKind, authorization_keys: BTreeSet, account_hash: AccountHash, blocktime: BlockTime, @@ -358,7 +351,6 @@ impl Executor { let (maybe_purse, get_payment_result) = self.get_payment_purse( entity, - entity_kind, authorization_keys.clone(), account_hash, blocktime, @@ -402,7 +394,6 @@ impl Executor { let (transfer_result, payment_result) = self.invoke_mint_to_transfer( runtime_args, entity, - entity_kind, authorization_keys, account_hash, blocktime, @@ -436,7 +427,6 @@ impl Executor { pub(crate) fn get_payment_purse( &self, entity: &AddressableEntity, - entity_kind: EntityKind, authorization_keys: BTreeSet, account_hash: AccountHash, blocktime: BlockTime, @@ -454,7 +444,6 @@ impl Executor { DirectSystemContractCall::GetPaymentPurse, RuntimeArgs::new(), entity, - entity_kind, authorization_keys, account_hash, blocktime, @@ -473,7 +462,6 @@ impl Executor { &self, runtime_args: RuntimeArgs, entity: &AddressableEntity, - entity_kind: EntityKind, authorization_keys: BTreeSet, account_hash: AccountHash, blocktime: BlockTime, @@ -492,7 +480,6 @@ impl Executor { DirectSystemContractCall::Transfer, runtime_args, entity, - entity_kind, authorization_keys, account_hash, blocktime, diff --git a/execution_engine/src/runtime/auction_internal.rs b/execution_engine/src/runtime/auction_internal.rs index e91d8a3dad..a281f34086 100644 --- a/execution_engine/src/runtime/auction_internal.rs +++ b/execution_engine/src/runtime/auction_internal.rs @@ -213,7 +213,7 @@ where AccountHash::from_public_key(unbonding_purse.unbonder_public_key(), crypto::blake2b); let maybe_value = self .context - .read_gs_direct(&Key::Account(account_hash)) + .read_gs_unsafe(&Key::Account(account_hash)) .map_err(|exec_error| { error!("MintProvider::unbond: {:?}", exec_error); >::from(exec_error).unwrap_or(Error::Storage) @@ -230,7 +230,7 @@ where let maybe_value = self .context - .read_gs_direct(&contract_key) + .read_gs_unsafe(&contract_key) .map_err(|exec_error| { error!("MintProvider::unbond: {:?}", exec_error); >::from(exec_error).unwrap_or(Error::Storage) diff --git a/execution_engine/src/runtime/mint_internal.rs b/execution_engine/src/runtime/mint_internal.rs index 8607a6eed4..064a2c19ba 100644 --- a/execution_engine/src/runtime/mint_internal.rs +++ b/execution_engine/src/runtime/mint_internal.rs @@ -143,7 +143,7 @@ where fn read_balance(&mut self, uref: URef) -> Result, Error> { let maybe_value = self .context - .read_gs_direct(&Key::Balance(uref.addr())) + .read_gs_unsafe(&Key::Balance(uref.addr())) .map_err(|exec_error| >::from(exec_error).unwrap_or(Error::Storage))?; match maybe_value { Some(StoredValue::CLValue(value)) => { diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index 0a1bc2bd8b..6d140772e4 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -579,7 +579,7 @@ where let runtime_context = self.context.new_from_self( mint_addr.into(), - EntryPointType::AddressableEntity, + EntryPointType::Called, &mut named_keys, access_rights, runtime_args.to_owned(), @@ -713,7 +713,7 @@ where let runtime_context = self.context.new_from_self( handle_payment_key, - EntryPointType::AddressableEntity, + EntryPointType::Called, &mut named_keys, access_rights, runtime_args.to_owned(), @@ -812,7 +812,7 @@ where let runtime_context = self.context.new_from_self( auction_key, - EntryPointType::AddressableEntity, + EntryPointType::Called, &mut named_keys, access_rights, runtime_args.to_owned(), @@ -1125,25 +1125,23 @@ where let current = self.context.entry_point_type(); let next = entry_point.entry_point_type(); match (current, next) { - (EntryPointType::AddressableEntity, EntryPointType::Session) => { + (EntryPointType::Called, EntryPointType::Caller) => { // Session code can't be called from Contract code for security reasons. Err(ExecError::InvalidContext) } - (EntryPointType::Factory, EntryPointType::Session) => { + (EntryPointType::Factory, EntryPointType::Caller) => { // Session code can't be called from Installer code for security reasons. Err(ExecError::InvalidContext) } - (EntryPointType::Session, EntryPointType::Session) => { + (EntryPointType::Caller, EntryPointType::Caller) => { // Session code called from session reuses current base key match self.context.get_entity_key().into_entity_hash() { Some(entity_hash) => Ok(entity_hash), None => Err(ExecError::InvalidEntity(entity_hash)), } } - (EntryPointType::Session, EntryPointType::AddressableEntity) - | (EntryPointType::AddressableEntity, EntryPointType::AddressableEntity) => { - Ok(entity_hash) - } + (EntryPointType::Caller, EntryPointType::Called) + | (EntryPointType::Called, EntryPointType::Called) => Ok(entity_hash), _ => { // Any other combination (installer, normal, etc.) is a contract context. Ok(entity_hash) @@ -1378,7 +1376,7 @@ where all_urefs }; - let entity_addr = EntityAddr::new_with_tag(entity.entity_kind(), entity_hash.value()); + let entity_addr = entity.entity_addr(entity_hash); let entity_named_keys = self .context @@ -2757,7 +2755,7 @@ where } fn get_balance(&mut self, purse: URef) -> Result, ExecError> { - let maybe_value = self.context.read_gs_direct(&Key::Balance(purse.addr()))?; + let maybe_value = self.context.read_gs_unsafe(&Key::Balance(purse.addr()))?; match maybe_value { Some(StoredValue::CLValue(value)) => { let value = CLValue::into_t(value)?; diff --git a/execution_engine/src/runtime_context/mod.rs b/execution_engine/src/runtime_context/mod.rs index 08fd774abc..811e1db771 100644 --- a/execution_engine/src/runtime_context/mod.rs +++ b/execution_engine/src/runtime_context/mod.rs @@ -22,8 +22,8 @@ use casper_storage::{ use casper_types::{ account::{Account, AccountHash}, addressable_entity::{ - ActionType, AddKeyFailure, EntityKind, EntityKindTag, MessageTopicError, NamedKeyAddr, - NamedKeyValue, NamedKeys, RemoveKeyFailure, SetThresholdFailure, UpdateKeyFailure, Weight, + ActionType, AddKeyFailure, EntityKindTag, MessageTopicError, NamedKeyAddr, NamedKeyValue, + NamedKeys, RemoveKeyFailure, SetThresholdFailure, UpdateKeyFailure, Weight, }, bytesrepr::ToBytes, contract_messages::{ @@ -70,7 +70,6 @@ pub struct RuntimeContext<'a, R> { entity: &'a AddressableEntity, // Key pointing to the entity we are currently running entity_key: Key, - entity_kind: EntityKind, account_hash: AccountHash, emit_message_cost: U512, } @@ -89,7 +88,6 @@ where entity_key: Key, authorization_keys: BTreeSet, access_rights: ContextAccessRights, - entity_kind: EntityKind, account_hash: AccountHash, address_generator: Rc>, tracking_copy: Rc>>, @@ -131,7 +129,6 @@ where engine_config, transfers, remaining_spending_limit, - entity_kind, emit_message_cost, } } @@ -149,7 +146,6 @@ where let entity = self.entity; let authorization_keys = self.authorization_keys.clone(); let account_hash = self.account_hash; - let entity_kind = self.entity_kind; let address_generator = self.address_generator.clone(); let tracking_copy = self.state(); @@ -186,7 +182,6 @@ where engine_config, transfers, remaining_spending_limit, - entity_kind, emit_message_cost: self.emit_message_cost, } } @@ -221,30 +216,27 @@ where &self.engine_config } - /// Returns the package kind associated with the current context. - pub fn get_entity_kind(&self) -> EntityKind { - self.entity_kind - } - /// Returns whether the current context is of the system addressable entity. pub fn is_system_account(&self) -> bool { - if let Some(account_hash) = self.entity_kind.maybe_account_hash() { - return account_hash == PublicKey::System.to_account_hash(); + if let Key::AddressableEntity(entity_addr) = self.entity_key { + entity_addr.value() == PublicKey::System.to_account_hash().value() + } else { + false } - false } /// Helper function to avoid duplication in `remove_uref`. - fn remove_key_from_entity(&mut self, entity_key: Key, name: &str) -> Result<(), ExecError> { - let entity_addr = if let Key::AddressableEntity(addr) = entity_key { - addr - } else { - return Err(ExecError::UnexpectedKeyVariant(entity_key)); - }; - - let named_key_addr = NamedKeyAddr::new_from_string(entity_addr, name.to_string())?; - if let Some(StoredValue::NamedKey(_)) = self.read_gs(&Key::NamedKey(named_key_addr))? { - self.prune_gs_unsafe(Key::NamedKey(named_key_addr)); + fn remove_key_from_entity(&mut self, name: &str) -> Result<(), ExecError> { + let key = self.entity_key; + match key.as_entity_addr() { + None => return Err(ExecError::UnexpectedKeyVariant(key)), + Some(entity_addr) => { + let named_key = + NamedKeyAddr::new_from_string(entity_addr, name.to_string())?.into(); + if let Some(StoredValue::NamedKey(_)) = self.read_gs(&named_key)? { + self.prune_gs_unsafe(named_key); + } + } } Ok(()) } @@ -254,9 +246,8 @@ where /// also persistable map (one that is found in the /// TrackingCopy/GlobalState). pub fn remove_key(&mut self, name: &str) -> Result<(), ExecError> { - let entity_key = self.get_entity_key(); self.named_keys.remove(name); - self.remove_key_from_entity(entity_key, name) + self.remove_key_from_entity(name) } /// Returns the block time. @@ -472,7 +463,7 @@ where /// /// DO NOT EXPOSE THIS VIA THE FFI - This function bypasses security checks and should be used /// with caution. - pub fn read_gs_direct(&mut self, key: &Key) -> Result, ExecError> { + pub fn read_gs_unsafe(&mut self, key: &Key) -> Result, ExecError> { self.tracking_copy .borrow_mut() .read(key) @@ -674,27 +665,26 @@ where fn validate_value(&self, value: &StoredValue) -> Result<(), ExecError> { match value { StoredValue::CLValue(cl_value) => self.validate_cl_value(cl_value), - StoredValue::Account(_) => Ok(()), - StoredValue::ByteCode(_) => Ok(()), - StoredValue::Contract(_) => Ok(()), - StoredValue::AddressableEntity(_) => Ok(()), - // TODO: anything to validate here? - StoredValue::Package(_) => Ok(()), - StoredValue::Transfer(_) => Ok(()), - StoredValue::DeployInfo(_) => Ok(()), - StoredValue::EraInfo(_) => Ok(()), - StoredValue::Bid(_) => Ok(()), - StoredValue::BidKind(_) => Ok(()), - StoredValue::Withdraw(_) => Ok(()), - StoredValue::Unbonding(_) => Ok(()), - StoredValue::ContractPackage(_) => Ok(()), - StoredValue::ContractWasm(_) => Ok(()), - StoredValue::MessageTopic(_) => Ok(()), - StoredValue::Message(_) => Ok(()), StoredValue::NamedKey(named_key_value) => { self.validate_cl_value(named_key_value.get_key_as_cl_value())?; self.validate_cl_value(named_key_value.get_name_as_cl_value()) } + StoredValue::Account(_) + | StoredValue::ByteCode(_) + | StoredValue::Contract(_) + | StoredValue::AddressableEntity(_) + | StoredValue::Package(_) + | StoredValue::Transfer(_) + | StoredValue::DeployInfo(_) + | StoredValue::EraInfo(_) + | StoredValue::Bid(_) + | StoredValue::BidKind(_) + | StoredValue::Withdraw(_) + | StoredValue::Unbonding(_) + | StoredValue::ContractPackage(_) + | StoredValue::ContractWasm(_) + | StoredValue::MessageTopic(_) + | StoredValue::Message(_) => Ok(()), } } @@ -757,97 +747,34 @@ where /// Tests whether reading from the `key` is valid. pub fn is_readable(&self, key: &Key) -> bool { - match key { - Key::URef(uref) => uref.is_readable(), - Key::Balance(_) => false, - Key::Account(_) - | Key::Hash(_) - | Key::Transfer(_) - | Key::DeployInfo(_) - | Key::EraInfo(_) - | Key::Bid(_) - | Key::Withdraw(_) - | Key::Dictionary(_) - | Key::SystemEntityRegistry - | Key::EraSummary - | Key::Unbond(_) - | Key::ChainspecRegistry - | Key::ChecksumRegistry - | Key::BidAddr(_) - | Key::Package(_) - | Key::AddressableEntity(..) - | Key::ByteCode(..) - | Key::Message(_) - | Key::NamedKey(_) => true, + match self.entity_key.as_entity_addr() { + Some(entity_addr) => key.is_readable(&entity_addr), + None => { + error!(?self.entity_key, "entity_key is unexpected key variant (expected Key::AddressableEntity)"); + panic!("is_readable: entity_key is unexpected key variant"); + } } } /// Tests whether addition to `key` is valid. pub fn is_addable(&self, key: &Key) -> bool { - match key { - Key::AddressableEntity(entity_addr) => match self.get_entity_key().into_entity_hash() { - Some(entity_hash) => entity_hash == AddressableEntityHash::new(entity_addr.value()), - None => false, - }, - Key::URef(uref) => uref.is_addable(), - Key::NamedKey(named_key_addr) => { - if let Key::AddressableEntity(entity_addr) = self.get_entity_key() { - named_key_addr.entity_addr() == entity_addr - } else { - false - } + match self.entity_key.as_entity_addr() { + Some(entity_addr) => key.is_addable(&entity_addr), + None => { + error!(?self.entity_key, "entity_key is unexpected key variant (expected Key::AddressableEntity)"); + panic!("is_addable: entity_key is unexpected key variant"); } - Key::Hash(_) - | Key::Account(_) - | Key::Transfer(_) - | Key::DeployInfo(_) - | Key::EraInfo(_) - | Key::Balance(_) - | Key::Bid(_) - | Key::Withdraw(_) - | Key::Dictionary(_) - | Key::SystemEntityRegistry - | Key::EraSummary - | Key::Unbond(_) - | Key::ChainspecRegistry - | Key::ChecksumRegistry - | Key::BidAddr(_) - | Key::Package(_) - | Key::ByteCode(..) - | Key::Message(_) => false, } } /// Tests whether writing to `key` is valid. pub fn is_writeable(&self, key: &Key) -> bool { - match key { - Key::URef(uref) => uref.is_writeable(), - Key::NamedKey(named_key_addr) => { - if let Key::AddressableEntity(entity_addr) = self.get_entity_key() { - named_key_addr.entity_addr() == entity_addr - } else { - false - } + match self.entity_key.as_entity_addr() { + Some(entity_addr) => key.is_writeable(&entity_addr), + None => { + error!(?self.entity_key, "entity_key is unexpected key variant (expected Key::AddressableEntity)"); + panic!("is_writeable: entity_key is unexpected key variant"); } - Key::Account(_) - | Key::Hash(_) - | Key::Transfer(_) - | Key::DeployInfo(_) - | Key::EraInfo(_) - | Key::Balance(_) - | Key::Bid(_) - | Key::Withdraw(_) - | Key::Dictionary(_) - | Key::SystemEntityRegistry - | Key::EraSummary - | Key::Unbond(_) - | Key::ChainspecRegistry - | Key::ChecksumRegistry - | Key::BidAddr(_) - | Key::Package(_) - | Key::AddressableEntity(..) - | Key::ByteCode(..) - | Key::Message(_) => false, } } @@ -859,7 +786,7 @@ where pub(crate) fn charge_gas(&mut self, gas: Gas) -> Result<(), ExecError> { let prev = self.gas_counter(); let gas_limit = self.gas_limit(); - let is_system = self.entity_kind.is_system(); + let is_system = self.entity_key.is_system_key(); // gas charge overflow protection match prev.checked_add(gas.cost(is_system)) { @@ -1037,26 +964,23 @@ where account_hash: AccountHash, weight: Weight, ) -> Result<(), ExecError> { - let entity_key = match self.entry_point_type { - EntryPointType::AddressableEntity => self.entity_key, - EntryPointType::Session | EntryPointType::Factory => { - self.get_entity_address_for_account_hash(self.account_hash)? - } + let entity_key = self.entity_key; + let entity_addr = match entity_key.as_entity_addr() { + Some(entity_addr) => entity_addr, + None => return Err(ExecError::UnexpectedKeyVariant(entity_key)), }; - // Check permission to modify associated keys - if !self.is_valid_context(entity_key) { + if EntryPointType::Caller == self.entry_point_type + && entity_addr.tag() != EntityKindTag::Account + { // Exit early with error to avoid mutations return Err(AddKeyFailure::PermissionDenied.into()); } - // Converts an account's public key into a URef - let key = self.get_entity_key(); - - // Take an addressable entity out of the global state + // Get the current entity record let entity = { - let mut entity: AddressableEntity = self.read_gs_typed(&key)?; - + let mut entity: AddressableEntity = self.read_gs_typed(&entity_key)?; + // enforce max keys limit if entity.associated_keys().len() >= (self.engine_config.max_associated_keys() as usize) { return Err(ExecError::AddKeyFailure(AddKeyFailure::MaxKeysLimit)); @@ -1069,9 +993,10 @@ where entity }; - let entity_value = self.addressable_entity_to_validated_value(entity)?; - - self.metered_write_gs_unsafe(key, entity_value)?; + self.metered_write_gs_unsafe( + entity_key, + self.addressable_entity_to_validated_value(entity)?, + )?; Ok(()) } @@ -1081,9 +1006,15 @@ where &mut self, account_hash: AccountHash, ) -> Result<(), ExecError> { - let entity_key = self.get_entity_address_for_account_hash(self.account_hash)?; - // Check permission to modify associated keys - if !self.is_valid_context(entity_key) { + let entity_key = self.entity_key; + let entity_addr = match entity_key.as_entity_addr() { + Some(entity_addr) => entity_addr, + None => return Err(ExecError::UnexpectedKeyVariant(entity_key)), + }; + + if EntryPointType::Caller == self.entry_point_type + && entity_addr.tag() != EntityKindTag::Account + { // Exit early with error to avoid mutations return Err(RemoveKeyFailure::PermissionDenied.into()); } @@ -1118,9 +1049,15 @@ where account_hash: AccountHash, weight: Weight, ) -> Result<(), ExecError> { - let entity_key = self.get_entity_address_for_account_hash(self.account_hash)?; - // Check permission to modify associated keys - if !self.is_valid_context(entity_key) { + let entity_key = self.entity_key; + let entity_addr = match entity_key.as_entity_addr() { + Some(entity_addr) => entity_addr, + None => return Err(ExecError::UnexpectedKeyVariant(entity_key)), + }; + + if EntryPointType::Caller == self.entry_point_type + && entity_addr.tag() != EntityKindTag::Account + { // Exit early with error to avoid mutations return Err(UpdateKeyFailure::PermissionDenied.into()); } @@ -1163,22 +1100,23 @@ where action_type: ActionType, threshold: Weight, ) -> Result<(), ExecError> { - let entity_key = match self.entry_point_type { - EntryPointType::AddressableEntity => self.entity_key, - EntryPointType::Session | EntryPointType::Factory => { - self.get_entity_address_for_account_hash(self.account_hash)? + let entity_key = self.entity_key; + let entity_addr = match entity_key.as_entity_addr() { + Some(entity_addr) => entity_addr, + None => { + return Err(ExecError::UnexpectedKeyVariant(entity_key)); } }; - // Check permission to modify associated keys - if !self.is_valid_context(entity_key) { + + if EntryPointType::Caller == self.entry_point_type + && entity_addr.tag() != EntityKindTag::Account + { // Exit early with error to avoid mutations return Err(SetThresholdFailure::PermissionDeniedError.into()); } - let key = self.get_entity_key(); - // Take an addressable entity out of the global state - let mut entity: AddressableEntity = self.read_gs_typed(&key)?; + let mut entity: AddressableEntity = self.read_gs_typed(&entity_key)?; // Exit early in case of error without updating global state if self.is_authorized_by_admin() { @@ -1190,7 +1128,7 @@ where let entity_value = self.addressable_entity_to_validated_value(entity)?; - self.metered_write_gs_unsafe(key, entity_value)?; + self.metered_write_gs_unsafe(entity_key, entity_value)?; Ok(()) } @@ -1204,14 +1142,6 @@ where Ok(value) } - pub(crate) fn get_entity_address_for_account_hash( - &mut self, - account_hash: AccountHash, - ) -> Result { - let cl_value = self.read_gs_typed::(&Key::Account(account_hash))?; - CLValue::into_t::(cl_value).map_err(ExecError::CLValue) - } - pub(crate) fn read_addressable_entity_by_account_hash( &mut self, account_hash: AccountHash, @@ -1232,11 +1162,6 @@ where } } - /// Checks if the account context is valid. - fn is_valid_context(&self, entity_key: Key) -> bool { - self.get_entity_key() == entity_key - } - /// Gets main purse id pub fn get_main_purse(&mut self) -> Result { let main_purse = self.entity().main_purse(); diff --git a/execution_engine/src/runtime_context/tests.rs b/execution_engine/src/runtime_context/tests.rs index 180fa2fbb2..0fd4061a74 100644 --- a/execution_engine/src/runtime_context/tests.rs +++ b/execution_engine/src/runtime_context/tests.rs @@ -147,7 +147,6 @@ fn new_runtime_context<'a>( entity_address, BTreeSet::from_iter(vec![account_hash]), access_rights, - EntityKind::Account(account_hash), account_hash, Rc::new(RefCell::new(address_generator)), Rc::new(RefCell::new(tracking_copy)), @@ -161,7 +160,7 @@ fn new_runtime_context<'a>( Gas::default(), Vec::default(), U512::MAX, - EntryPointType::Session, + EntryPointType::Caller, ); (runtime_context, tempdir) @@ -243,10 +242,10 @@ fn use_uref_valid() { // Use uref as the key to perform an action on the global state. // This should succeed because the uref is valid. let value = StoredValue::CLValue(CLValue::from_t(43_i32).unwrap()); - let query_result = build_runtime_context_and_execute(named_keys, |mut rc| { + let result = build_runtime_context_and_execute(named_keys, |mut rc| { rc.metered_write_gs(uref_as_key, value) }); - query_result.expect("writing using valid uref should succeed"); + result.expect("writing using valid uref should succeed"); } #[test] @@ -257,30 +256,30 @@ fn use_uref_forged() { let named_keys = NamedKeys::new(); // named_keys.insert(String::new(), Key::from(uref)); let value = StoredValue::CLValue(CLValue::from_t(43_i32).unwrap()); - let query_result = + let result = build_runtime_context_and_execute(named_keys, |mut rc| rc.metered_write_gs(uref, value)); - assert_forged_reference(query_result); + assert_forged_reference(result); } #[test] fn account_key_not_writeable() { let mut rng = rand::thread_rng(); let acc_key = random_account_key(&mut rng); - let query_result = build_runtime_context_and_execute(NamedKeys::new(), |mut rc| { + let result = build_runtime_context_and_execute(NamedKeys::new(), |mut rc| { rc.metered_write_gs( acc_key, StoredValue::CLValue(CLValue::from_t(1_i32).unwrap()), ) }); - assert_invalid_access(query_result, AccessRights::WRITE); + assert_invalid_access(result, AccessRights::WRITE); } #[test] fn entity_key_readable_valid() { // Entity key is readable if it is a "base" key - current context of the // execution. - let query_result = build_runtime_context_and_execute(NamedKeys::new(), |mut rc| { + let result = build_runtime_context_and_execute(NamedKeys::new(), |mut rc| { let base_key = rc.get_entity_key(); let entity = rc.get_entity(); @@ -293,7 +292,7 @@ fn entity_key_readable_valid() { Ok(()) }); - assert!(query_result.is_ok()); + assert!(result.is_ok()); } #[test] @@ -304,7 +303,7 @@ fn account_key_addable_returns_type_mismatch() { let uref_as_key = create_uref_as_key(&mut rng, AccessRights::READ); let mut named_keys = NamedKeys::new(); named_keys.insert(String::new(), uref_as_key); - let query_result = build_runtime_context_and_execute(named_keys, |mut rc| { + let result = build_runtime_context_and_execute(named_keys, |mut rc| { let account_key: Key = rc.account_hash.into(); let uref_name = "NewURef".to_owned(); let named_key = StoredValue::CLValue(CLValue::from_t((uref_name, uref_as_key)).unwrap()); @@ -312,7 +311,7 @@ fn account_key_addable_returns_type_mismatch() { rc.metered_add_gs(account_key, named_key) }); - assert!(query_result.is_err()); + assert!(result.is_err()); } #[test] @@ -322,14 +321,14 @@ fn account_key_addable_invalid() { let mut rng = rand::thread_rng(); let other_acc_key = random_account_key(&mut rng); - let query_result = build_runtime_context_and_execute(NamedKeys::new(), |mut rc| { + let result = build_runtime_context_and_execute(NamedKeys::new(), |mut rc| { rc.metered_add_gs( other_acc_key, StoredValue::CLValue(CLValue::from_t(1_i32).unwrap()), ) }); - assert_invalid_access(query_result, AccessRights::ADD); + assert_invalid_access(result, AccessRights::ADD); } #[test] @@ -338,10 +337,10 @@ fn contract_key_readable_valid() { // execution. let mut rng = rand::thread_rng(); let contract_key = random_contract_key(&mut rng); - let query_result = + let result = build_runtime_context_and_execute(NamedKeys::new(), |mut rc| rc.read_gs(&contract_key)); - assert!(query_result.is_ok()); + assert!(result.is_ok()); } #[test] @@ -350,14 +349,14 @@ fn contract_key_not_writeable() { // execution. let mut rng = rand::thread_rng(); let contract_key = random_contract_key(&mut rng); - let query_result = build_runtime_context_and_execute(NamedKeys::new(), |mut rc| { + let result = build_runtime_context_and_execute(NamedKeys::new(), |mut rc| { rc.metered_write_gs( contract_key, StoredValue::CLValue(CLValue::from_t(1_i32).unwrap()), ) }); - assert_invalid_access(query_result, AccessRights::WRITE); + assert_invalid_access(result, AccessRights::WRITE); } #[test] @@ -414,7 +413,6 @@ fn contract_key_addable_valid() { contract_key, authorization_keys, access_rights, - EntityKind::SmartContract, account_hash, Rc::new(RefCell::new(address_generator)), Rc::clone(&tracking_copy), @@ -428,7 +426,7 @@ fn contract_key_addable_valid() { Gas::default(), Vec::default(), U512::zero(), - EntryPointType::Session, + EntryPointType::Caller, ); assert!(runtime_context @@ -472,7 +470,6 @@ fn contract_key_addable_invalid() { other_contract_key, authorization_keys, access_rights, - EntityKind::Account(account_hash), account_hash, Rc::new(RefCell::new(address_generator)), Rc::clone(&tracking_copy), @@ -486,7 +483,7 @@ fn contract_key_addable_invalid() { Gas::default(), Vec::default(), U512::zero(), - EntryPointType::Session, + EntryPointType::Caller, ); let result = runtime_context.metered_add_gs(contract_key, named_uref_tuple); @@ -502,9 +499,8 @@ fn uref_key_readable_valid() { let mut named_keys = NamedKeys::new(); named_keys.insert(String::new(), uref_key); - let query_result = - build_runtime_context_and_execute(named_keys, |mut rc| rc.read_gs(&uref_key)); - assert!(query_result.is_ok()); + let result = build_runtime_context_and_execute(named_keys, |mut rc| rc.read_gs(&uref_key)); + assert!(result.is_ok()); } #[test] @@ -515,9 +511,8 @@ fn uref_key_readable_invalid() { let mut named_keys = NamedKeys::new(); named_keys.insert(String::new(), uref_key); - let query_result = - build_runtime_context_and_execute(named_keys, |mut rc| rc.read_gs(&uref_key)); - assert_invalid_access(query_result, AccessRights::READ); + let result = build_runtime_context_and_execute(named_keys, |mut rc| rc.read_gs(&uref_key)); + assert_invalid_access(result, AccessRights::READ); } #[test] @@ -528,13 +523,13 @@ fn uref_key_writeable_valid() { let mut named_keys = NamedKeys::new(); named_keys.insert(String::new(), uref_key); - let query_result = build_runtime_context_and_execute(named_keys, |mut rc| { + let result = build_runtime_context_and_execute(named_keys, |mut rc| { rc.metered_write_gs( uref_key, StoredValue::CLValue(CLValue::from_t(1_i32).unwrap()), ) }); - assert!(query_result.is_ok()); + assert!(result.is_ok()); } #[test] @@ -545,13 +540,13 @@ fn uref_key_writeable_invalid() { let mut named_keys = NamedKeys::new(); named_keys.insert(String::new(), uref_key); - let query_result = build_runtime_context_and_execute(named_keys, |mut rc| { + let result = build_runtime_context_and_execute(named_keys, |mut rc| { rc.metered_write_gs( uref_key, StoredValue::CLValue(CLValue::from_t(1_i32).unwrap()), ) }); - assert_invalid_access(query_result, AccessRights::WRITE); + assert_invalid_access(result, AccessRights::WRITE); } #[test] @@ -562,12 +557,12 @@ fn uref_key_addable_valid() { let mut named_keys = NamedKeys::new(); named_keys.insert(String::new(), uref_key); - let query_result = build_runtime_context_and_execute(named_keys, |mut rc| { + let result = build_runtime_context_and_execute(named_keys, |mut rc| { rc.metered_write_gs(uref_key, CLValue::from_t(10_i32).unwrap()) .expect("Writing to the GlobalState should work."); rc.metered_add_gs(uref_key, CLValue::from_t(1_i32).unwrap()) }); - assert!(query_result.is_ok()); + assert!(result.is_ok()); } #[test] @@ -578,49 +573,37 @@ fn uref_key_addable_invalid() { let mut named_keys = NamedKeys::new(); named_keys.insert(String::new(), uref_key); - let query_result = build_runtime_context_and_execute(named_keys, |mut rc| { + let result = build_runtime_context_and_execute(named_keys, |mut rc| { rc.metered_add_gs( uref_key, StoredValue::CLValue(CLValue::from_t(1_i32).unwrap()), ) }); - assert_invalid_access(query_result, AccessRights::ADD); -} - -#[test] -fn hash_key_readable() { - // values under hash's are universally readable - let query = |runtime_context: RuntimeContext| { - let mut rng = rand::thread_rng(); - let key = random_hash(&mut rng); - runtime_context.validate_readable(&key) - }; - let query_result = build_runtime_context_and_execute(NamedKeys::new(), query); - assert!(query_result.is_ok()) + assert_invalid_access(result, AccessRights::ADD); } #[test] -fn hash_key_writeable() { +fn hash_key_is_not_writeable() { // values under hash's are immutable - let query = |runtime_context: RuntimeContext| { + let functor = |runtime_context: RuntimeContext| { let mut rng = rand::thread_rng(); let key = random_hash(&mut rng); runtime_context.validate_writeable(&key) }; - let query_result = build_runtime_context_and_execute(NamedKeys::new(), query); - assert!(query_result.is_err()) + let result = build_runtime_context_and_execute(NamedKeys::new(), functor); + assert!(result.is_err()) } #[test] -fn hash_key_addable_invalid() { +fn hash_key_is_not_addable() { // values under hashes are immutable - let query = |runtime_context: RuntimeContext| { + let functor = |runtime_context: RuntimeContext| { let mut rng = rand::thread_rng(); let key = random_hash(&mut rng); runtime_context.validate_addable(&key) }; - let query_result = build_runtime_context_and_execute(NamedKeys::new(), query); - assert!(query_result.is_err()) + let result = build_runtime_context_and_execute(NamedKeys::new(), functor); + assert!(result.is_err()) } #[test] @@ -628,7 +611,7 @@ fn manage_associated_keys() { // Testing a valid case only - successfully added a key, and successfully removed, // making sure `account_dirty` mutated let named_keys = NamedKeys::new(); - let query = |mut runtime_context: RuntimeContext| { + let functor = |mut runtime_context: RuntimeContext| { let account_hash = AccountHash::new([42; 32]); let weight = Weight::new(155); @@ -688,7 +671,7 @@ fn manage_associated_keys() { Ok(()) }; - let _ = build_runtime_context_and_execute(named_keys, query); + let _ = build_runtime_context_and_execute(named_keys, functor); } #[test] @@ -696,7 +679,7 @@ fn action_thresholds_management() { // Testing a valid case only - successfully added a key, and successfully removed, // making sure `account_dirty` mutated let named_keys = NamedKeys::new(); - let query = |mut runtime_context: RuntimeContext| { + let functor = |mut runtime_context: RuntimeContext| { let entity_hash_by_account_hash = CLValue::from_t(Key::Hash([2; 32])).expect("must convert to cl_value"); @@ -738,7 +721,7 @@ fn action_thresholds_management() { Ok(()) }; - let _ = build_runtime_context_and_execute(named_keys, query); + let _ = build_runtime_context_and_execute(named_keys, functor); } #[test] @@ -746,9 +729,10 @@ fn should_verify_ownership_before_adding_key() { // Testing a valid case only - successfully added a key, and successfully removed, // making sure `account_dirty` mutated let named_keys = NamedKeys::new(); - let query = |mut runtime_context: RuntimeContext| { + let functor = |mut runtime_context: RuntimeContext| { // Overwrites a `base_key` to a different one before doing any operation as // account `[0; 32]` + // TODO: this test should be updated to use v2.0.0 / AddressableEntity model let entity_hash_by_account_hash = CLValue::from_t(Key::Hash([2; 32])).expect("must convert to cl_value"); @@ -770,13 +754,17 @@ fn should_verify_ownership_before_adding_key() { .expect_err("This operation should return error"); match err { + ExecError::UnexpectedKeyVariant(_) => { + // This is the v2.0.0 error as this test is currently using Key::Hash + // instead of Key::AddressableEntity + } ExecError::AddKeyFailure(AddKeyFailure::PermissionDenied) => {} e => panic!("Invalid error variant: {:?}", e), } Ok(()) }; - let _ = build_runtime_context_and_execute(named_keys, query); + let _ = build_runtime_context_and_execute(named_keys, functor); } #[test] @@ -784,9 +772,10 @@ fn should_verify_ownership_before_removing_a_key() { // Testing a valid case only - successfully added a key, and successfully removed, // making sure `account_dirty` mutated let named_keys = NamedKeys::new(); - let query = |mut runtime_context: RuntimeContext| { + let functor = |mut runtime_context: RuntimeContext| { // Overwrites a `base_key` to a different one before doing any operation as // account `[0; 32]` + // TODO: this test should be updated to use v2.0.0 / AddressableEntity model runtime_context.entity_key = Key::Hash([1; 32]); let err = runtime_context @@ -794,13 +783,17 @@ fn should_verify_ownership_before_removing_a_key() { .expect_err("This operation should return error"); match err { + ExecError::UnexpectedKeyVariant(_) => { + // this is the v2.0 error because this test is currently using + // Key::Hash instead of Key::AddressableEntity + } ExecError::RemoveKeyFailure(RemoveKeyFailure::PermissionDenied) => {} ref e => panic!("Invalid error variant: {:?}", e), } Ok(()) }; - let _ = build_runtime_context_and_execute(named_keys, query); + let _ = build_runtime_context_and_execute(named_keys, functor); } #[test] @@ -808,9 +801,10 @@ fn should_verify_ownership_before_setting_action_threshold() { // Testing a valid case only - successfully added a key, and successfully removed, // making sure `account_dirty` mutated let named_keys = NamedKeys::new(); - let query = |mut runtime_context: RuntimeContext| { + let functor = |mut runtime_context: RuntimeContext| { // Overwrites a `base_key` to a different one before doing any operation as // account `[0; 32]` + // TODO: this test should be updated to v2.0.0 / AddressableEntityHash model runtime_context.entity_key = Key::Hash([1; 32]); let err = runtime_context @@ -818,19 +812,23 @@ fn should_verify_ownership_before_setting_action_threshold() { .expect_err("This operation should return error"); match err { + ExecError::UnexpectedKeyVariant(_) => { + // this is what is returned under protocol version 2.0 because Key::Hash(_) is + // deprecated. + } ExecError::SetThresholdFailure(SetThresholdFailure::PermissionDeniedError) => {} ref e => panic!("Invalid error variant: {:?}", e), } Ok(()) }; - let _ = build_runtime_context_and_execute(named_keys, query); + let _ = build_runtime_context_and_execute(named_keys, functor); } #[test] fn can_roundtrip_key_value_pairs() { let named_keys = NamedKeys::new(); - let query = |mut runtime_context: RuntimeContext| { + let functor = |mut runtime_context: RuntimeContext| { let deploy_hash = [1u8; 32]; let mut uref_address_generator = AddressGenerator::new(&deploy_hash, Phase::Session); let test_uref = create_uref_as_key(&mut uref_address_generator, AccessRights::default()) @@ -849,8 +847,8 @@ fn can_roundtrip_key_value_pairs() { Ok(result == Some(test_value)) }; - let query_result = build_runtime_context_and_execute(named_keys, query).expect("should be ok"); - assert!(query_result) + let result = build_runtime_context_and_execute(named_keys, functor).expect("should be ok"); + assert!(result) } #[test] diff --git a/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs b/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs index 7cb82a9c2f..297db3b2f1 100644 --- a/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs +++ b/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs @@ -35,7 +35,7 @@ fn stored_session(contract_hash: AddressableEntityHash) -> Call { Call { contract_address: ContractAddress::ContractHash(contract_hash), target_method: CONTRACT_FORWARDER_ENTRYPOINT_SESSION.to_string(), - entry_point_type: EntryPointType::Session, + entry_point_type: EntryPointType::Caller, } } @@ -43,7 +43,7 @@ fn stored_versioned_session(contract_package_hash: PackageHash) -> Call { Call { contract_address: ContractAddress::ContractPackageHash(contract_package_hash), target_method: CONTRACT_FORWARDER_ENTRYPOINT_SESSION.to_string(), - entry_point_type: EntryPointType::Session, + entry_point_type: EntryPointType::Caller, } } @@ -51,7 +51,7 @@ fn stored_contract(contract_hash: AddressableEntityHash) -> Call { Call { contract_address: ContractAddress::ContractHash(contract_hash), target_method: CONTRACT_FORWARDER_ENTRYPOINT_CONTRACT.to_string(), - entry_point_type: EntryPointType::AddressableEntity, + entry_point_type: EntryPointType::Called, } } @@ -59,7 +59,7 @@ fn stored_versioned_contract(contract_package_hash: PackageHash) -> Call { Call { contract_address: ContractAddress::ContractPackageHash(contract_package_hash), target_method: CONTRACT_FORWARDER_ENTRYPOINT_CONTRACT.to_string(), - entry_point_type: EntryPointType::AddressableEntity, + entry_point_type: EntryPointType::Called, } } @@ -212,12 +212,12 @@ fn assert_each_context_has_correct_call_stack_info( let stored_call_stack_key = format!("call_stack-{}", i); // we need to know where to look for the call stack information let call_stack = match call.entry_point_type { - EntryPointType::AddressableEntity | EntryPointType::Factory => builder + EntryPointType::Called | EntryPointType::Factory => builder .get_call_stack_from_contract_context( &stored_call_stack_key, current_contract_package_hash, ), - EntryPointType::Session => { + EntryPointType::Caller => { builder.get_call_stack_from_session_context(&stored_call_stack_key) } }; @@ -272,12 +272,12 @@ fn assert_each_context_has_correct_call_stack_info_module_bytes( let stored_call_stack_key = format!("call_stack-{}", i); // we need to know where to look for the call stack information let call_stack = match call.entry_point_type { - EntryPointType::AddressableEntity | EntryPointType::Factory => builder + EntryPointType::Called | EntryPointType::Factory => builder .get_call_stack_from_contract_context( &stored_call_stack_key, current_contract_package_hash.value(), ), - EntryPointType::Session => { + EntryPointType::Caller => { builder.get_call_stack_from_session_context(&stored_call_stack_key) } }; @@ -308,7 +308,7 @@ fn assert_call_stack_matches_calls(call_stack: Vec, calls: &[Call]) { package_hash: contract_package_hash, .. }, - ) if *entry_point_type == EntryPointType::AddressableEntity + ) if *entry_point_type == EntryPointType::Called && *contract_package_hash == *current_contract_package_hash => {} // Unversioned Call with EntryPointType::Contract @@ -322,7 +322,7 @@ fn assert_call_stack_matches_calls(call_stack: Vec, calls: &[Call]) { entity_hash: contract_hash, .. }, - ) if *entry_point_type == EntryPointType::AddressableEntity + ) if *entry_point_type == EntryPointType::Called && *contract_hash == *current_contract_hash => {} _ => panic!( diff --git a/node/src/reactor/main_reactor/tests.rs b/node/src/reactor/main_reactor/tests.rs index 4b366d8c9d..d93b9cfe56 100644 --- a/node/src/reactor/main_reactor/tests.rs +++ b/node/src/reactor/main_reactor/tests.rs @@ -577,7 +577,6 @@ impl TestFixture { .storage .read_highest_block() .expect("should have block"); - let bids_request = BidsRequest::new(*highest_block.state_root_hash()); let bids_result = runner .main_reactor() @@ -1726,18 +1725,18 @@ async fn run_redelegate_bid_network() { ); deploy.sign(&alice_secret_key); - let txn = Transaction::Deploy(deploy); - let txn_hash = txn.hash(); + let transaction = Transaction::Deploy(deploy); + let transaction_hash = transaction.hash(); // Inject the transaction and run the network until executed. - fixture.inject_transaction(txn).await; + fixture.inject_transaction(transaction).await; fixture - .run_until_executed_transaction(&txn_hash, TEN_SECS) + .run_until_executed_transaction(&transaction_hash, TEN_SECS) .await; // Ensure execution succeeded and that there is a Prune transform for the bid's key. fixture - .successful_execution_transforms(&txn_hash) + .successful_execution_transforms(&transaction_hash) .iter() .find(|transform| match transform.kind() { TransformKind::Prune(prune_key) => prune_key == &bid_key, diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index 5fe9ba4c78..788c1007af 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -4014,21 +4014,21 @@ "description": "Context of method execution\n\nMost significant bit represents version i.e. - 0b0 -> 0.x/1.x (session & contracts) - 0b1 -> 2.x and later (introduced installer, utility entry points)", "oneOf": [ { - "description": "Runs as session code (caller) Deprecated, retained to allow read back of legacy stored session.", + "description": "Runs using the calling entity's context. In v1.x this was used for both \"session\" code run using the originating Account's context, and also for \"StoredSession\" code that ran in the caller's context. While this made systemic sense due to the way the runtime context nesting works, this dual usage was very confusing to most human beings.\n\nIn v2.x the renamed Caller variant is exclusively used for wasm run using the initiating account entity's context. Previously installed 1.x stored session code should continue to work as the binary value matches but we no longer allow such logic to be upgraded, nor do we allow new stored session to be installed.", "type": "string", "enum": [ - "Session" + "Caller" ] }, { - "description": "Runs within called entity's context (called)", + "description": "Runs using the called entity's context.", "type": "string", "enum": [ - "AddressableEntity" + "Called" ] }, { - "description": "This entry point is intended to extract a subset of bytecode. Runs within called entity's context (called)", + "description": "Extract a subset of bytecode and installs it as a new smart contract. Runs using the called entity's context.", "type": "string", "enum": [ "Factory" diff --git a/smart_contracts/contracts/explorer/faucet-stored/src/main.rs b/smart_contracts/contracts/explorer/faucet-stored/src/main.rs index 835a6cb6ff..ba33a0c867 100644 --- a/smart_contracts/contracts/explorer/faucet-stored/src/main.rs +++ b/smart_contracts/contracts/explorer/faucet-stored/src/main.rs @@ -114,7 +114,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let set_variables = EntryPoint::new( @@ -135,7 +135,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let authorize_to = EntryPoint::new( @@ -146,7 +146,7 @@ pub extern "C" fn call() { )], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(faucet); diff --git a/smart_contracts/contracts/profiling/host-function-metrics/src/lib.rs b/smart_contracts/contracts/profiling/host-function-metrics/src/lib.rs index 0d7bce2a18..edafa474b0 100644 --- a/smart_contracts/contracts/profiling/host-function-metrics/src/lib.rs +++ b/smart_contracts/contracts/profiling/host-function-metrics/src/lib.rs @@ -228,7 +228,7 @@ fn store_function( ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/add-gas-subcall/src/main.rs b/smart_contracts/contracts/test/add-gas-subcall/src/main.rs index b66757318a..070cfa079f 100644 --- a/smart_contracts/contracts/test/add-gas-subcall/src/main.rs +++ b/smart_contracts/contracts/test/add-gas-subcall/src/main.rs @@ -55,7 +55,7 @@ fn store() -> (AddressableEntityHash, EntityVersion) { vec![Parameter::new(ARG_GAS_AMOUNT, CLType::I32)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/contract-context/src/main.rs b/smart_contracts/contracts/test/contract-context/src/main.rs index 63f82547a9..fb3b70718b 100644 --- a/smart_contracts/contracts/test/contract-context/src/main.rs +++ b/smart_contracts/contracts/test/contract-context/src/main.rs @@ -97,7 +97,7 @@ fn create_entrypoints_1() -> EntryPoints { Vec::new(), CLType::I32, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(contract_code_test); @@ -106,7 +106,7 @@ fn create_entrypoints_1() -> EntryPoints { Vec::new(), CLType::I32, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(session_code_caller_as_contract); diff --git a/smart_contracts/contracts/test/contract-funds/src/main.rs b/smart_contracts/contracts/test/contract-funds/src/main.rs index ae59493d5a..70c28afe37 100644 --- a/smart_contracts/contracts/test/contract-funds/src/main.rs +++ b/smart_contracts/contracts/test/contract-funds/src/main.rs @@ -45,7 +45,7 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_TARGET, AccountHash::cl_type())], URef::cl_type(), EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(faucet_entrypoint); diff --git a/smart_contracts/contracts/test/contract-messages-emitter/src/main.rs b/smart_contracts/contracts/test/contract-messages-emitter/src/main.rs index b1191decd7..9d010d1a79 100644 --- a/smart_contracts/contracts/test/contract-messages-emitter/src/main.rs +++ b/smart_contracts/contracts/test/contract-messages-emitter/src/main.rs @@ -91,28 +91,28 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); emitter_entry_points.add_entry_point(EntryPoint::new( ENTRY_POINT_EMIT_MESSAGE, vec![Parameter::new(ARG_MESSAGE_SUFFIX_NAME, String::cl_type())], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); emitter_entry_points.add_entry_point(EntryPoint::new( ENTRY_POINT_ADD_TOPIC, vec![Parameter::new(ARG_TOPIC_NAME, String::cl_type())], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); emitter_entry_points.add_entry_point(EntryPoint::new( ENTRY_POINT_EMIT_MULTIPLE_MESSAGES, vec![Parameter::new(ARG_NUM_MESSAGES_TO_EMIT, u32::cl_type())], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); if register_topic_with_init { diff --git a/smart_contracts/contracts/test/contract-messages-upgrader/src/main.rs b/smart_contracts/contracts/test/contract-messages-upgrader/src/main.rs index 273e893660..4b884466fb 100644 --- a/smart_contracts/contracts/test/contract-messages-upgrader/src/main.rs +++ b/smart_contracts/contracts/test/contract-messages-upgrader/src/main.rs @@ -105,21 +105,21 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); emitter_entry_points.add_entry_point(EntryPoint::new( ENTRY_POINT_EMIT_MESSAGE, vec![Parameter::new(ARG_MESSAGE_SUFFIX_NAME, String::cl_type())], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); emitter_entry_points.add_entry_point(EntryPoint::new( ENTRY_POINT_EMIT_MESSAGE_FROM_EACH_VERSION, vec![Parameter::new(ARG_MESSAGE_SUFFIX_NAME, String::cl_type())], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); let message_emitter_package_hash: PackageHash = runtime::get_key(PACKAGE_HASH_KEY_NAME) diff --git a/smart_contracts/contracts/test/counter-factory/src/main.rs b/smart_contracts/contracts/test/counter-factory/src/main.rs index 665b6e1987..fab271c793 100644 --- a/smart_contracts/contracts/test/counter-factory/src/main.rs +++ b/smart_contracts/contracts/test/counter-factory/src/main.rs @@ -85,7 +85,7 @@ fn installer(name: String, initial_value: U512) { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); let entry_point: EntryPoint = EntryPoint::new( @@ -93,7 +93,7 @@ fn installer(name: String, initial_value: U512) { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -138,7 +138,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Template, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); let entry_point: EntryPoint = EntryPoint::new( @@ -146,7 +146,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Template, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/deserialize-error/src/main.rs b/smart_contracts/contracts/test/deserialize-error/src/main.rs index c0b16dd85b..5836be1174 100644 --- a/smart_contracts/contracts/test/deserialize-error/src/main.rs +++ b/smart_contracts/contracts/test/deserialize-error/src/main.rs @@ -81,7 +81,7 @@ pub extern "C" fn call() { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/dictionary/src/lib.rs b/smart_contracts/contracts/test/dictionary/src/lib.rs index be79645de7..79e0cfa84d 100644 --- a/smart_contracts/contracts/test/dictionary/src/lib.rs +++ b/smart_contracts/contracts/test/dictionary/src/lib.rs @@ -183,35 +183,35 @@ pub fn delegate() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); entry_points.add_entry_point(EntryPoint::new( SHARE_RO_ENTRYPOINT, Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); entry_points.add_entry_point(EntryPoint::new( SHARE_W_ENTRYPOINT, Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); entry_points.add_entry_point(EntryPoint::new( INVALID_PUT_DICTIONARY_ITEM_KEY_ENTRYPOINT, Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); entry_points.add_entry_point(EntryPoint::new( INVALID_GET_DICTIONARY_ITEM_KEY_ENTRYPOINT, Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); let named_keys = { let uref = { diff --git a/smart_contracts/contracts/test/do-nothing-stored-upgrader/src/main.rs b/smart_contracts/contracts/test/do-nothing-stored-upgrader/src/main.rs index 97d04fa005..e5d18a1a34 100644 --- a/smart_contracts/contracts/test/do-nothing-stored-upgrader/src/main.rs +++ b/smart_contracts/contracts/test/do-nothing-stored-upgrader/src/main.rs @@ -42,7 +42,7 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_PURSE_NAME, String::cl_type())], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(delegate); diff --git a/smart_contracts/contracts/test/do-nothing-stored/src/main.rs b/smart_contracts/contracts/test/do-nothing-stored/src/main.rs index 33e65f19d0..401982ae38 100644 --- a/smart_contracts/contracts/test/do-nothing-stored/src/main.rs +++ b/smart_contracts/contracts/test/do-nothing-stored/src/main.rs @@ -27,7 +27,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); entry_points diff --git a/smart_contracts/contracts/test/ee-1071-regression/src/main.rs b/smart_contracts/contracts/test/ee-1071-regression/src/main.rs index c37dbe1838..90ff40021a 100644 --- a/smart_contracts/contracts/test/ee-1071-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-1071-regression/src/main.rs @@ -26,7 +26,7 @@ pub extern "C" fn call() { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/ee-1129-regression/src/main.rs b/smart_contracts/contracts/test/ee-1129-regression/src/main.rs index 57bade8faf..a8340814a1 100644 --- a/smart_contracts/contracts/test/ee-1129-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-1129-regression/src/main.rs @@ -33,7 +33,7 @@ pub extern "C" fn call() { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/ee-1217-regression/src/main.rs b/smart_contracts/contracts/test/ee-1217-regression/src/main.rs index e73848d1e4..68746a8bd0 100644 --- a/smart_contracts/contracts/test/ee-1217-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-1217-regression/src/main.rs @@ -141,70 +141,70 @@ pub extern "C" fn call() { vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let add_bid_contract_entry_point = EntryPoint::new( METHOD_ADD_BID_CONTRACT_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let withdraw_bid_session_entry_point = EntryPoint::new( METHOD_WITHDRAW_BID_SESSION_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let withdraw_bid_contract_entry_point = EntryPoint::new( METHOD_WITHDRAW_BID_CONTRACT_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let delegate_session_entry_point = EntryPoint::new( METHOD_DELEGATE_SESSION_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let delegate_contract_entry_point = EntryPoint::new( METHOD_DELEGATE_CONTRACT_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let undelegate_session_entry_point = EntryPoint::new( METHOD_UNDELEGATE_SESSION_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let undelegate_contract_entry_point = EntryPoint::new( METHOD_UNDELEGATE_CONTRACT_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let activate_bid_session_entry_point = EntryPoint::new( METHOD_ACTIVATE_BID_SESSION_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let activate_bid_contract_entry_point = EntryPoint::new( METHOD_ACTIVATE_BID_CONTRACT_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(add_bid_session_entry_point); entry_points.add_entry_point(add_bid_contract_entry_point); diff --git a/smart_contracts/contracts/test/ee-401-regression/src/main.rs b/smart_contracts/contracts/test/ee-401-regression/src/main.rs index 4183f37072..b1b6bcff70 100644 --- a/smart_contracts/contracts/test/ee-401-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-401-regression/src/main.rs @@ -35,7 +35,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::URef, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/ee-441-rng-state/src/main.rs b/smart_contracts/contracts/test/ee-441-rng-state/src/main.rs index 864ed084e3..e328ce8505 100644 --- a/smart_contracts/contracts/test/ee-441-rng-state/src/main.rs +++ b/smart_contracts/contracts/test/ee-441-rng-state/src/main.rs @@ -44,7 +44,7 @@ pub extern "C" fn call() { Parameters::default(), CLType::String, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(do_nothing_entry_point); @@ -54,7 +54,7 @@ pub extern "C" fn call() { Parameters::default(), CLType::URef, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(do_something_entry_point); diff --git a/smart_contracts/contracts/test/ee-572-regression-create/src/main.rs b/smart_contracts/contracts/test/ee-572-regression-create/src/main.rs index b4c6726fda..92ee1dbc00 100644 --- a/smart_contracts/contracts/test/ee-572-regression-create/src/main.rs +++ b/smart_contracts/contracts/test/ee-572-regression-create/src/main.rs @@ -34,7 +34,7 @@ pub extern "C" fn call() { Parameters::default(), CLType::URef, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/ee-599-regression/src/main.rs b/smart_contracts/contracts/test/ee-599-regression/src/main.rs index d232b6b120..31e4a54773 100644 --- a/smart_contracts/contracts/test/ee-599-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-599-regression/src/main.rs @@ -132,7 +132,7 @@ fn delegate() -> Result<(), ApiError> { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point_1); @@ -142,7 +142,7 @@ fn delegate() -> Result<(), ApiError> { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point_2); @@ -152,7 +152,7 @@ fn delegate() -> Result<(), ApiError> { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point_3); @@ -162,7 +162,7 @@ fn delegate() -> Result<(), ApiError> { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point_4); diff --git a/smart_contracts/contracts/test/ee-771-regression/src/main.rs b/smart_contracts/contracts/test/ee-771-regression/src/main.rs index 12414d68a5..21328e8658 100644 --- a/smart_contracts/contracts/test/ee-771-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-771-regression/src/main.rs @@ -39,7 +39,7 @@ pub extern "C" fn contract_ext() { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -61,7 +61,7 @@ fn store(named_keys: NamedKeys) -> (AddressableEntityHash, EntityVersion) { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/expensive-calculation/src/main.rs b/smart_contracts/contracts/test/expensive-calculation/src/main.rs index ed69b3da6e..3f8607975c 100644 --- a/smart_contracts/contracts/test/expensive-calculation/src/main.rs +++ b/smart_contracts/contracts/test/expensive-calculation/src/main.rs @@ -34,7 +34,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); entry_points diff --git a/smart_contracts/contracts/test/get-call-stack-recursive-subcall/src/main.rs b/smart_contracts/contracts/test/get-call-stack-recursive-subcall/src/main.rs index 6dac6d58d1..a7ec5dd402 100644 --- a/smart_contracts/contracts/test/get-call-stack-recursive-subcall/src/main.rs +++ b/smart_contracts/contracts/test/get-call-stack-recursive-subcall/src/main.rs @@ -37,7 +37,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let forwarder_session_entry_point = EntryPoint::new( METHOD_FORWARDER_SESSION_NAME.to_string(), @@ -47,7 +47,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::Caller, ); entry_points.add_entry_point(forwarder_contract_entry_point); entry_points.add_entry_point(forwarder_session_entry_point); diff --git a/smart_contracts/contracts/test/get-caller-subcall/src/main.rs b/smart_contracts/contracts/test/get-caller-subcall/src/main.rs index fa7de3a352..e559585af0 100644 --- a/smart_contracts/contracts/test/get-caller-subcall/src/main.rs +++ b/smart_contracts/contracts/test/get-caller-subcall/src/main.rs @@ -42,7 +42,7 @@ pub extern "C" fn call() { Vec::new(), CLType::ByteArray(32), EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); entry_points diff --git a/smart_contracts/contracts/test/gh-1470-regression/src/bin/main.rs b/smart_contracts/contracts/test/gh-1470-regression/src/bin/main.rs index f7ab7ca8e3..80a8ce2570 100644 --- a/smart_contracts/contracts/test/gh-1470-regression/src/bin/main.rs +++ b/smart_contracts/contracts/test/gh-1470-regression/src/bin/main.rs @@ -61,7 +61,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Groups(vec![Group::new(GROUP_LABEL)]), - EntryPointType::AddressableEntity, + EntryPointType::Called, )); entry_points.add_entry_point(EntryPoint::new( @@ -73,7 +73,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Groups(vec![Group::new(GROUP_LABEL)]), - EntryPointType::AddressableEntity, + EntryPointType::Called, )); let named_keys = NamedKeys::new(); diff --git a/smart_contracts/contracts/test/gh-1688-regression/src/main.rs b/smart_contracts/contracts/test/gh-1688-regression/src/main.rs index d8d5db275b..f9b7ca0faa 100644 --- a/smart_contracts/contracts/test/gh-1688-regression/src/main.rs +++ b/smart_contracts/contracts/test/gh-1688-regression/src/main.rs @@ -30,7 +30,7 @@ fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); let (contract_hash, _version) = storage::new_contract( diff --git a/smart_contracts/contracts/test/gh-2280-regression/src/main.rs b/smart_contracts/contracts/test/gh-2280-regression/src/main.rs index 64b24d0d19..ca01cafd3a 100644 --- a/smart_contracts/contracts/test/gh-2280-regression/src/main.rs +++ b/smart_contracts/contracts/test/gh-2280-regression/src/main.rs @@ -48,7 +48,7 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_TARGET, AccountHash::cl_type())], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(faucet_entrypoint); diff --git a/smart_contracts/contracts/test/gh-3097-regression/src/main.rs b/smart_contracts/contracts/test/gh-3097-regression/src/main.rs index c217ed700f..a8cf62cdc5 100644 --- a/smart_contracts/contracts/test/gh-3097-regression/src/main.rs +++ b/smart_contracts/contracts/test/gh-3097-regression/src/main.rs @@ -33,7 +33,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(do_something); diff --git a/smart_contracts/contracts/test/groups/src/main.rs b/smart_contracts/contracts/test/groups/src/main.rs index e609399a8f..7bd28f4fa3 100644 --- a/smart_contracts/contracts/test/groups/src/main.rs +++ b/smart_contracts/contracts/test/groups/src/main.rs @@ -132,7 +132,7 @@ fn create_entry_points_1() -> EntryPoints { Vec::new(), CLType::I32, EntryPointAccess::groups(&["Group 1"]), - EntryPointType::Session, + EntryPointType::Caller, ); entry_points.add_entry_point(restricted_session); @@ -141,7 +141,7 @@ fn create_entry_points_1() -> EntryPoints { Vec::new(), CLType::I32, EntryPointAccess::groups(&["Group 1"]), - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(restricted_contract); @@ -150,7 +150,7 @@ fn create_entry_points_1() -> EntryPoints { vec![Parameter::new(ARG_PACKAGE_HASH, CLType::Key)], CLType::I32, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::Caller, ); entry_points.add_entry_point(restricted_session_caller); @@ -159,7 +159,7 @@ fn create_entry_points_1() -> EntryPoints { Vec::new(), CLType::I32, EntryPointAccess::groups(&["Group 1"]), - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(restricted_contract); @@ -172,7 +172,7 @@ fn create_entry_points_1() -> EntryPoints { EntryPointAccess::Public, // NOTE: Public contract authorizes any contract call, because this contract has groups // uref in its named keys - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(unrestricted_contract_caller); @@ -185,7 +185,7 @@ fn create_entry_points_1() -> EntryPoints { EntryPointAccess::Public, // NOTE: Public contract authorizes any contract call, because this contract has groups // uref in its named keys - EntryPointType::Session, + EntryPointType::Caller, ); entry_points.add_entry_point(unrestricted_contract_caller_as_session); @@ -198,7 +198,7 @@ fn create_entry_points_1() -> EntryPoints { EntryPointAccess::groups(&[]), // NOTE: Public contract authorizes any contract call, because this contract has groups // uref in its named keys - EntryPointType::Session, + EntryPointType::Caller, ); entry_points.add_entry_point(uncallable_session); @@ -211,7 +211,7 @@ fn create_entry_points_1() -> EntryPoints { EntryPointAccess::groups(&[]), // NOTE: Public contract authorizes any contract call, because this contract has groups // uref in its named keys - EntryPointType::Session, + EntryPointType::Caller, ); entry_points.add_entry_point(uncallable_contract); @@ -226,7 +226,7 @@ fn create_entry_points_1() -> EntryPoints { EntryPointAccess::Public, // NOTE: Public contract authorizes any contract call, because this contract has groups // uref in its named keys - EntryPointType::Session, + EntryPointType::Caller, ); entry_points.add_entry_point(call_restricted_entry_points); @@ -238,7 +238,7 @@ fn create_entry_points_1() -> EntryPoints { )], CLType::Unit, EntryPointAccess::groups(&["Group 1"]), - EntryPointType::Session, + EntryPointType::Caller, ); entry_points.add_entry_point(restricted_standard_payment); diff --git a/smart_contracts/contracts/test/host-function-costs/src/main.rs b/smart_contracts/contracts/test/host-function-costs/src/main.rs index 08ab3c97cd..e1930a2c7c 100644 --- a/smart_contracts/contracts/test/host-function-costs/src/main.rs +++ b/smart_contracts/contracts/test/host-function-costs/src/main.rs @@ -281,7 +281,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -290,7 +290,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -299,7 +299,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); let entry_point = EntryPoint::new( @@ -307,7 +307,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -316,7 +316,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); let entry_point = EntryPoint::new( @@ -324,7 +324,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -333,7 +333,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); let entry_point = EntryPoint::new( @@ -341,7 +341,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -350,7 +350,7 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_BYTES, >::cl_type())], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -359,7 +359,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -368,7 +368,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -377,7 +377,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -386,7 +386,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/manage-groups/src/main.rs b/smart_contracts/contracts/test/manage-groups/src/main.rs index 5d38556636..50f93921a8 100644 --- a/smart_contracts/contracts/test/manage-groups/src/main.rs +++ b/smart_contracts/contracts/test/manage-groups/src/main.rs @@ -178,7 +178,7 @@ fn create_entry_points_1() -> EntryPoints { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::Caller, ); entry_points.add_entry_point(restricted_session); @@ -187,7 +187,7 @@ fn create_entry_points_1() -> EntryPoints { vec![Parameter::new(GROUP_NAME_ARG, CLType::String)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::Caller, ); entry_points.add_entry_point(remove_group); @@ -200,7 +200,7 @@ fn create_entry_points_1() -> EntryPoints { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::Caller, ); entry_points.add_entry_point(extend_group_urefs); @@ -213,7 +213,7 @@ fn create_entry_points_1() -> EntryPoints { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::Caller, ); entry_points.add_entry_point(remove_group_urefs); entry_points diff --git a/smart_contracts/contracts/test/measure-gas-subcall/src/main.rs b/smart_contracts/contracts/test/measure-gas-subcall/src/main.rs index c49a21eb71..e44dbb2617 100644 --- a/smart_contracts/contracts/test/measure-gas-subcall/src/main.rs +++ b/smart_contracts/contracts/test/measure-gas-subcall/src/main.rs @@ -44,7 +44,7 @@ fn store() -> (AddressableEntityHash, EntityVersion) { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point_1); @@ -54,7 +54,7 @@ fn store() -> (AddressableEntityHash, EntityVersion) { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point_2); diff --git a/smart_contracts/contracts/test/multisig-authorization/src/main.rs b/smart_contracts/contracts/test/multisig-authorization/src/main.rs index 456ec24e39..a085778d50 100644 --- a/smart_contracts/contracts/test/multisig-authorization/src/main.rs +++ b/smart_contracts/contracts/test/multisig-authorization/src/main.rs @@ -77,7 +77,7 @@ pub extern "C" fn call() { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let entrypoint_b = EntryPoint::new( @@ -85,7 +85,7 @@ pub extern "C" fn call() { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entrypoint_a); diff --git a/smart_contracts/contracts/test/named-keys-stored/src/main.rs b/smart_contracts/contracts/test/named-keys-stored/src/main.rs index 348f7deba4..d54e7d8313 100644 --- a/smart_contracts/contracts/test/named-keys-stored/src/main.rs +++ b/smart_contracts/contracts/test/named-keys-stored/src/main.rs @@ -142,7 +142,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(contract_entrypoint); let session_entrypoint = EntryPoint::new( @@ -150,7 +150,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(session_entrypoint); let contract_to_contract_entrypoint = EntryPoint::new( @@ -158,7 +158,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(contract_to_contract_entrypoint); let contract_to_contract_entrypoint = EntryPoint::new( @@ -166,7 +166,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(contract_to_contract_entrypoint); entry_points diff --git a/smart_contracts/contracts/test/ordered-transforms/src/main.rs b/smart_contracts/contracts/test/ordered-transforms/src/main.rs index f7fa05e75d..7b565b10c4 100644 --- a/smart_contracts/contracts/test/ordered-transforms/src/main.rs +++ b/smart_contracts/contracts/test/ordered-transforms/src/main.rs @@ -25,7 +25,7 @@ pub extern "C" fn call() { )], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); let n: u32 = runtime::get_named_arg("n"); diff --git a/smart_contracts/contracts/test/purse-holder-stored-upgrader/src/main.rs b/smart_contracts/contracts/test/purse-holder-stored-upgrader/src/main.rs index 4306526a85..7febdcae82 100644 --- a/smart_contracts/contracts/test/purse-holder-stored-upgrader/src/main.rs +++ b/smart_contracts/contracts/test/purse-holder-stored-upgrader/src/main.rs @@ -63,7 +63,7 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_PURSE_NAME, CLType::String)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(add); let version = EntryPoint::new( @@ -71,7 +71,7 @@ pub extern "C" fn call() { vec![], CLType::String, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(version); @@ -80,7 +80,7 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_PURSE_NAME, CLType::String)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(remove); entry_points diff --git a/smart_contracts/contracts/test/purse-holder-stored/src/main.rs b/smart_contracts/contracts/test/purse-holder-stored/src/main.rs index df60cff72a..6a2cf6f6e0 100644 --- a/smart_contracts/contracts/test/purse-holder-stored/src/main.rs +++ b/smart_contracts/contracts/test/purse-holder-stored/src/main.rs @@ -52,7 +52,7 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_PURSE, CLType::String)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(add); let version = EntryPoint::new( @@ -60,7 +60,7 @@ pub extern "C" fn call() { vec![], CLType::String, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(version); entry_points diff --git a/smart_contracts/contracts/test/regression-20210707/src/main.rs b/smart_contracts/contracts/test/regression-20210707/src/main.rs index 33356e03f3..820ebe1082 100644 --- a/smart_contracts/contracts/test/regression-20210707/src/main.rs +++ b/smart_contracts/contracts/test/regression-20210707/src/main.rs @@ -149,7 +149,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let send_to_purse = EntryPoint::new( METHOD_SEND_TO_PURSE, @@ -160,7 +160,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let hardcoded_src = EntryPoint::new( METHOD_HARDCODED_PURSE_SRC, @@ -170,7 +170,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let stored_payment = EntryPoint::new( METHOD_STORED_PAYMENT, @@ -180,14 +180,14 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let hardcoded_payment = EntryPoint::new( METHOD_HARDCODED_PAYMENT, vec![Parameter::new(ARG_AMOUNT, CLType::U512)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(send_to_account); diff --git a/smart_contracts/contracts/test/regression-20210831/src/main.rs b/smart_contracts/contracts/test/regression-20210831/src/main.rs index 9d3209575b..539048756b 100644 --- a/smart_contracts/contracts/test/regression-20210831/src/main.rs +++ b/smart_contracts/contracts/test/regression-20210831/src/main.rs @@ -182,7 +182,7 @@ pub extern "C" fn call() { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(add_bid_proxy_call_1); @@ -195,7 +195,7 @@ pub extern "C" fn call() { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(add_bid_proxy_call); @@ -207,7 +207,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let withdraw_proxy_call = EntryPoint::new( @@ -218,7 +218,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let delegate_proxy_call = EntryPoint::new( @@ -230,7 +230,7 @@ pub extern "C" fn call() { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let delegate_proxy_call_1 = EntryPoint::new( @@ -242,7 +242,7 @@ pub extern "C" fn call() { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let undelegate_proxy_call = EntryPoint::new( @@ -254,7 +254,7 @@ pub extern "C" fn call() { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let undelegate_proxy_call_1 = EntryPoint::new( @@ -266,7 +266,7 @@ pub extern "C" fn call() { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let activate_bid_proxy_call = EntryPoint::new( @@ -277,7 +277,7 @@ pub extern "C" fn call() { )], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); let activate_bid_proxy_call_1 = EntryPoint::new( METHOD_ACTIVATE_BID_CALL_1, @@ -287,7 +287,7 @@ pub extern "C" fn call() { )], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(withdraw_proxy_call); diff --git a/smart_contracts/contracts/test/regression-20220204/src/main.rs b/smart_contracts/contracts/test/regression-20220204/src/main.rs index d541c5cde1..e3e3fb547d 100644 --- a/smart_contracts/contracts/test/regression-20220204/src/main.rs +++ b/smart_contracts/contracts/test/regression-20220204/src/main.rs @@ -34,7 +34,7 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_PURSE, URef::cl_type())], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); type NonTrivialArg = BTreeMap; @@ -44,7 +44,7 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_PURSE, NonTrivialArg::cl_type())], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); let named_keys = { diff --git a/smart_contracts/contracts/test/regression-20220211/src/main.rs b/smart_contracts/contracts/test/regression-20220211/src/main.rs index 6ca1cf5950..4aacb2c37f 100644 --- a/smart_contracts/contracts/test/regression-20220211/src/main.rs +++ b/smart_contracts/contracts/test/regression-20220211/src/main.rs @@ -30,7 +30,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); entry_points.add_entry_point(EntryPoint::new( @@ -38,63 +38,63 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); entry_points.add_entry_point(EntryPoint::new( PUT_KEY_AS_SESSION, Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); entry_points.add_entry_point(EntryPoint::new( PUT_KEY_AS_CONTRACT, Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); entry_points.add_entry_point(EntryPoint::new( READ_AS_SESSION, Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); entry_points.add_entry_point(EntryPoint::new( READ_AS_CONTRACT, Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); entry_points.add_entry_point(EntryPoint::new( WRITE_AS_SESSION, Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); entry_points.add_entry_point(EntryPoint::new( WRITE_AS_CONTRACT, Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); entry_points.add_entry_point(EntryPoint::new( ADD_AS_SESSION, Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); entry_points.add_entry_point(EntryPoint::new( ADD_AS_CONTRACT, Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); let (contract_hash, _contract_version) = storage::new_locked_contract(entry_points, None, None, None, None); diff --git a/smart_contracts/contracts/test/regression_20211110/src/main.rs b/smart_contracts/contracts/test/regression_20211110/src/main.rs index 8e16815e05..5f1d793f4a 100644 --- a/smart_contracts/contracts/test/regression_20211110/src/main.rs +++ b/smart_contracts/contracts/test/regression_20211110/src/main.rs @@ -22,7 +22,7 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_TARGET, AddressableEntityHash::cl_type())], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); let (contract_hash, _contract_version) = diff --git a/smart_contracts/contracts/test/ret-uref/src/main.rs b/smart_contracts/contracts/test/ret-uref/src/main.rs index 2b6bc38392..09b9e8d8e3 100644 --- a/smart_contracts/contracts/test/ret-uref/src/main.rs +++ b/smart_contracts/contracts/test/ret-uref/src/main.rs @@ -54,7 +54,7 @@ pub extern "C" fn call() { vec![Parameter::new(ACCESS_UREF, CLType::URef)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(put_uref_entrypoint); let get_uref_entrypoint = EntryPoint::new( @@ -62,7 +62,7 @@ pub extern "C" fn call() { vec![], CLType::URef, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(get_uref_entrypoint); let insert_uref_entrypoint = EntryPoint::new( @@ -70,7 +70,7 @@ pub extern "C" fn call() { vec![Parameter::new("contract_hash", CLType::ByteArray(32))], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::Caller, ); entry_points.add_entry_point(insert_uref_entrypoint); entry_points diff --git a/smart_contracts/contracts/test/storage-costs/src/main.rs b/smart_contracts/contracts/test/storage-costs/src/main.rs index d713cc7c4a..e665c6f874 100644 --- a/smart_contracts/contracts/test/storage-costs/src/main.rs +++ b/smart_contracts/contracts/test/storage-costs/src/main.rs @@ -143,7 +143,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); let entry_point = EntryPoint::new( @@ -151,7 +151,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); let entry_point = EntryPoint::new( @@ -159,7 +159,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); let entry_point = EntryPoint::new( @@ -167,7 +167,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -176,7 +176,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -185,7 +185,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -194,7 +194,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -203,7 +203,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -212,7 +212,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -221,7 +221,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -230,7 +230,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -239,7 +239,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/test-payment-stored/src/main.rs b/smart_contracts/contracts/test/test-payment-stored/src/main.rs index be81984d8e..24eddf3bd7 100644 --- a/smart_contracts/contracts/test/test-payment-stored/src/main.rs +++ b/smart_contracts/contracts/test/test-payment-stored/src/main.rs @@ -53,7 +53,7 @@ pub extern "C" fn call() { vec![Parameter::new(standard_payment::ARG_AMOUNT, CLType::U512)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); entry_points diff --git a/smart_contracts/contracts/test/transfer-purse-to-account-stored/src/main.rs b/smart_contracts/contracts/test/transfer-purse-to-account-stored/src/main.rs index fe562fe2f6..b46127963b 100644 --- a/smart_contracts/contracts/test/transfer-purse-to-account-stored/src/main.rs +++ b/smart_contracts/contracts/test/transfer-purse-to-account-stored/src/main.rs @@ -38,7 +38,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::Caller, ); entry_points.add_entry_point(entry_point); entry_points diff --git a/smart_contracts/contracts/test/transfer-purse-to-accounts-stored/src/main.rs b/smart_contracts/contracts/test/transfer-purse-to-accounts-stored/src/main.rs index 3f1b884d3a..dcbbc0c3d1 100644 --- a/smart_contracts/contracts/test/transfer-purse-to-accounts-stored/src/main.rs +++ b/smart_contracts/contracts/test/transfer-purse-to-accounts-stored/src/main.rs @@ -56,7 +56,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); tmp.add_entry_point(entry_point); tmp diff --git a/smart_contracts/contracts/test/upgrade-threshold-upgrader/src/main.rs b/smart_contracts/contracts/test/upgrade-threshold-upgrader/src/main.rs index edf56742eb..35e165dfdc 100644 --- a/smart_contracts/contracts/test/upgrade-threshold-upgrader/src/main.rs +++ b/smart_contracts/contracts/test/upgrade-threshold-upgrader/src/main.rs @@ -57,7 +57,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entrypoints.add_entry_point(add_associated_key_entry_point); let manage_action_threshold_entrypoint = EntryPoint::new( @@ -65,7 +65,7 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_NEW_UPGRADE_THRESHOLD, CLType::U8)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entrypoints.add_entry_point(manage_action_threshold_entrypoint); let remove_associated_key_entry_point = EntryPoint::new( @@ -76,7 +76,7 @@ pub extern "C" fn call() { )], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entrypoints.add_entry_point(remove_associated_key_entry_point); entrypoints diff --git a/smart_contracts/contracts/test/upgrade-threshold/src/main.rs b/smart_contracts/contracts/test/upgrade-threshold/src/main.rs index e73d3f5f91..8270ac0de3 100644 --- a/smart_contracts/contracts/test/upgrade-threshold/src/main.rs +++ b/smart_contracts/contracts/test/upgrade-threshold/src/main.rs @@ -51,7 +51,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entrypoints.add_entry_point(add_associated_key_entry_point); let manage_action_threshold_entrypoint = EntryPoint::new( @@ -59,7 +59,7 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_NEW_UPGRADE_THRESHOLD, CLType::U8)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entrypoints.add_entry_point(manage_action_threshold_entrypoint); entrypoints diff --git a/smart_contracts/contracts/tutorial/counter-installer/src/main.rs b/smart_contracts/contracts/tutorial/counter-installer/src/main.rs index 4448bd8504..8c4dc9b364 100644 --- a/smart_contracts/contracts/tutorial/counter-installer/src/main.rs +++ b/smart_contracts/contracts/tutorial/counter-installer/src/main.rs @@ -65,14 +65,14 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); counter_entry_points.add_entry_point(EntryPoint::new( COUNTER_GET, Vec::new(), CLType::I32, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, )); let (stored_contract_hash, contract_version) = storage::new_contract( diff --git a/storage/src/tracking_copy/error.rs b/storage/src/tracking_copy/error.rs index 7cc3c16445..faf8557c24 100644 --- a/storage/src/tracking_copy/error.rs +++ b/storage/src/tracking_copy/error.rs @@ -2,8 +2,7 @@ use thiserror::Error; use casper_types::{ addressable_entity::{AddKeyFailure, RemoveKeyFailure, SetThresholdFailure, UpdateKeyFailure}, - bytesrepr, system, AccessRights, ApiError, CLType, CLValueError, Key, StoredValueTypeMismatch, - URef, + bytesrepr, system, ApiError, CLType, CLValueError, Key, StoredValueTypeMismatch, }; /// Possible tracking copy errors. @@ -28,18 +27,6 @@ pub enum Error { /// Type mismatch error. #[error("{}", _0)] TypeMismatch(StoredValueTypeMismatch), - /// Invalid access. - #[error("Invalid access rights: {}", required)] - InvalidAccess { - /// Required access rights of the operation. - required: AccessRights, - }, - /// Forged reference error. - #[error("Forged reference: {}", _0)] - ForgedReference(URef), - /// Unable to find a [`URef`]. - #[error("URef not found: {}", _0)] - URefNotFound(URef), /// Execution exceeded the gas limit. #[error("Out of gas error")] GasLimit, diff --git a/storage/src/tracking_copy/ext_entity.rs b/storage/src/tracking_copy/ext_entity.rs index c3e3151025..8cca74437d 100644 --- a/storage/src/tracking_copy/ext_entity.rs +++ b/storage/src/tracking_copy/ext_entity.rs @@ -339,45 +339,22 @@ where ) -> Result<(), Self::Error> { let account_hash = account.account_hash(); - let mut generator = - AddressGenerator::new(account.main_purse().addr().as_ref(), Phase::System); - - let byte_code_hash = ByteCodeHash::default(); - let entity_hash = AddressableEntityHash::new(generator.new_hash_address()); - let package_hash = PackageHash::new(generator.new_hash_address()); - - let entry_points = EntryPoints::new(); - - let associated_keys = AssociatedKeys::from(account.associated_keys().clone()); - let action_thresholds = { - let account_threshold = account.action_thresholds().clone(); - ActionThresholds::new( - Weight::new(account_threshold.deployment.value()), - Weight::new(1u8), - Weight::new(account_threshold.key_management.value()), - ) - .map_err(Self::Error::SetThresholdFailure)? - }; - + // carry forward the account hash to allow reverse lookup + let entity_hash = AddressableEntityHash::new(account_hash.value()); let entity_addr = EntityAddr::new_account_entity_addr(entity_hash.value()); - self.migrate_named_keys(entity_addr, account.named_keys().clone())?; + // migrate named keys -- if this fails there is no reason to proceed further. + let named_keys = account.named_keys().clone(); + self.migrate_named_keys(entity_addr, named_keys)?; - let entity = AddressableEntity::new( - package_hash, - byte_code_hash, - entry_points, - protocol_version, - account.main_purse(), - associated_keys, - action_thresholds, - MessageTopics::default(), - EntityKind::Account(account_hash), - ); + // write package first + let package_hash = { + let mut generator = + AddressGenerator::new(account.main_purse().addr().as_ref(), Phase::System); - let access_key = generator.new_uref(AccessRights::READ_ADD_WRITE); + let package_hash = PackageHash::new(generator.new_hash_address()); + let access_key = generator.new_uref(AccessRights::READ_ADD_WRITE); - let package = { let mut package = Package::new( access_key, EntityVersions::default(), @@ -386,22 +363,54 @@ where PackageStatus::Locked, ); package.insert_entity_version(protocol_version.value().major, entity_hash); - package + self.write(package_hash.into(), package.into()); + package_hash }; - let entity_key: Key = entity.entity_key(entity_hash); + // write entity after package + { + // currently, addressable entities of account kind are not permitted to have bytecode + // however, we intend to revisit this and potentially allow it in a future release + // as a replacement for stored session. + let byte_code_hash = ByteCodeHash::default(); + let entry_points = EntryPoints::new(); + + let action_thresholds = { + let account_threshold = account.action_thresholds().clone(); + ActionThresholds::new( + Weight::new(account_threshold.deployment.value()), + Weight::new(1u8), + Weight::new(account_threshold.key_management.value()), + ) + .map_err(Self::Error::SetThresholdFailure)? + }; - self.write(entity_key, entity.into()); - self.write(package_hash.into(), package.into()); - let contract_by_account = match CLValue::from_t(entity_key) { - Ok(cl_value) => cl_value, - Err(err) => return Err(Self::Error::CLValue(err)), - }; + let associated_keys = AssociatedKeys::from(account.associated_keys().clone()); + + let entity = AddressableEntity::new( + package_hash, + byte_code_hash, + entry_points, + protocol_version, + account.main_purse(), + associated_keys, + action_thresholds, + MessageTopics::default(), + EntityKind::Account(account_hash), + ); + let entity_key = entity.entity_key(entity_hash); + let contract_by_account = match CLValue::from_t(entity_key) { + Ok(cl_value) => cl_value, + Err(err) => return Err(Self::Error::CLValue(err)), + }; + + self.write(entity_key, entity.into()); + self.write( + Key::Account(account_hash), + StoredValue::CLValue(contract_by_account), + ); + } - self.write( - Key::Account(account_hash), - StoredValue::CLValue(contract_by_account), - ); Ok(()) } @@ -426,8 +435,7 @@ where } }; let auction = self.get_addressable_entity_by_hash(auction_hash)?; - let auction_addr = - EntityAddr::new_with_tag(auction.entity_kind(), auction_hash.value()); + let auction_addr = auction.entity_addr(auction_hash); let auction_named_keys = self.get_named_keys(auction_addr)?; let auction_access_rights = auction.extract_access_rights(auction_hash, &auction_named_keys); @@ -444,7 +452,7 @@ where } }; let mint = self.get_addressable_entity_by_hash(mint_hash)?; - let mint_addr = EntityAddr::new_with_tag(mint.entity_kind(), mint_hash.value()); + let mint_addr = mint.entity_addr(mint_hash); let mint_named_keys = self.get_named_keys(mint_addr)?; let mint_access_rights = mint.extract_access_rights(mint_hash, &mint_named_keys); (mint_named_keys, mint_access_rights) @@ -461,8 +469,7 @@ where } }; let payment = self.get_addressable_entity_by_hash(payment_hash)?; - let payment_addr = - EntityAddr::new_with_tag(payment.entity_kind(), payment_hash.value()); + let payment_addr = payment.entity_addr(payment_hash); let payment_named_keys = self.get_named_keys(payment_addr)?; let payment_access_rights = payment.extract_access_rights(payment_hash, &mint_named_keys); @@ -499,7 +506,7 @@ where authorization_keys, administrative_accounts, )?; - let entity_addr = EntityAddr::new_with_tag(entity.entity_kind(), entity_hash.value()); + let entity_addr = entity.entity_addr(entity_hash); let named_keys = self.get_named_keys(entity_addr)?; let access_rights = entity .extract_access_rights(AddressableEntityHash::new(entity_addr.value()), &named_keys); diff --git a/types/benches/bytesrepr_bench.rs b/types/benches/bytesrepr_bench.rs index ae4ba66f8f..8099763e27 100644 --- a/types/benches/bytesrepr_bench.rs +++ b/types/benches/bytesrepr_bench.rs @@ -473,7 +473,7 @@ fn sample_contract(entry_points_len: u8) -> AddressableEntity { args, casper_types::CLType::U512, EntryPointAccess::groups(&["Group 2"]), - EntryPointType::AddressableEntity, + EntryPointType::Called, ); tmp.add_entry_point(entry_point); }); diff --git a/types/src/addressable_entity.rs b/types/src/addressable_entity.rs index 33374dda0c..cf71c1a1ed 100644 --- a/types/src/addressable_entity.rs +++ b/types/src/addressable_entity.rs @@ -262,6 +262,11 @@ impl AddressableEntityHash { AddressableEntityHash(value) } + /// Get the entity addr for this entity hash from the corresponding entity. + pub fn entity_addr(&self, entity: AddressableEntity) -> EntityAddr { + entity.entity_addr(*self) + } + /// Returns the raw bytes of the contract hash as an array. pub fn value(&self) -> HashAddr { self.0 @@ -654,7 +659,7 @@ impl EntryPoints { pub fn contains_stored_session(&self) -> bool { self.0 .values() - .any(|entry_point| entry_point.entry_point_type == EntryPointType::Session) + .any(|entry_point| entry_point.entry_point_type == EntryPointType::Caller) } } @@ -960,6 +965,12 @@ impl EntityAddr { } } + /// Is this a system entity address? + pub fn is_system(&self) -> bool { + self.tag() == EntityKindTag::System + || self.value() == PublicKey::System.to_account_hash().value() + } + /// Returns the 32 bytes of the [`EntityAddr`]. pub fn value(&self) -> HashAddr { match self { @@ -1160,6 +1171,15 @@ impl NamedKeyAddr { } } +impl Default for NamedKeyAddr { + fn default() -> Self { + NamedKeyAddr { + base_addr: EntityAddr::System(HashAddr::default()), + string_bytes: Default::default(), + } + } +} + impl ToBytes for NamedKeyAddr { fn to_bytes(&self) -> Result, bytesrepr::Error> { let mut buffer = bytesrepr::allocate_buffer(self)?; @@ -1482,6 +1502,16 @@ impl AddressableEntity { } } + /// Get the entity addr for this entity from the corresponding hash. + pub fn entity_addr(&self, entity_hash: AddressableEntityHash) -> EntityAddr { + let hash_addr = entity_hash.value(); + match self.entity_kind { + EntityKind::System(_) => EntityAddr::new_system_entity_addr(hash_addr), + EntityKind::Account(_) => EntityAddr::new_account_entity_addr(hash_addr), + EntityKind::SmartContract => EntityAddr::new_contract_entity_addr(hash_addr), + } + } + /// Hash for accessing contract package pub fn package_hash(&self) -> PackageHash { self.package_hash @@ -1918,13 +1948,21 @@ impl From for AddressableEntity { #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] pub enum EntryPointType { - /// Runs as session code (caller) - /// Deprecated, retained to allow read back of legacy stored session. - Session = 0b00000000, - /// Runs within called entity's context (called) - AddressableEntity = 0b00000001, - /// This entry point is intended to extract a subset of bytecode. - /// Runs within called entity's context (called) + /// Runs using the calling entity's context. + /// In v1.x this was used for both "session" code run using the originating + /// Account's context, and also for "StoredSession" code that ran in the + /// caller's context. While this made systemic sense due to the way the runtime + /// context nesting works, this dual usage was very confusing to most human beings. + /// + /// In v2.x the renamed Caller variant is exclusively used for wasm run using the initiating + /// account entity's context. Previously installed 1.x stored session code should + /// continue to work as the binary value matches but we no longer allow such logic + /// to be upgraded, nor do we allow new stored session to be installed. + Caller = 0b00000000, + /// Runs using the called entity's context. + Called = 0b00000001, + /// Extract a subset of bytecode and installs it as a new smart contract. + /// Runs using the called entity's context. Factory = 0b10000000, } @@ -1946,8 +1984,8 @@ impl EntryPointType { /// Returns true if entry point type is invalid for the context. pub fn is_invalid_context(&self) -> bool { match self { - EntryPointType::Session => true, - EntryPointType::AddressableEntity | EntryPointType::Factory => false, + EntryPointType::Caller => true, + EntryPointType::Called | EntryPointType::Factory => false, } } } @@ -2073,7 +2111,7 @@ impl Default for EntryPoint { args: Vec::new(), ret: CLType::Unit, access: EntryPointAccess::Public, - entry_point_type: EntryPointType::Session, + entry_point_type: EntryPointType::Caller, } } } diff --git a/types/src/block_time.rs b/types/src/block_time.rs index 935afa6e2b..397a46bb27 100644 --- a/types/src/block_time.rs +++ b/types/src/block_time.rs @@ -14,12 +14,14 @@ pub const BLOCKTIME_SERIALIZED_LENGTH: usize = U64_SERIALIZED_LENGTH; /// A newtype wrapping a [`u64`] which represents the block time. #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] -#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Serialize, Deserialize)] +#[derive( + Clone, Copy, Default, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Serialize, Deserialize, +)] pub struct BlockTime(u64); impl BlockTime { /// Constructs a `BlockTime`. - pub fn new(value: u64) -> Self { + pub const fn new(value: u64) -> Self { BlockTime(value) } diff --git a/types/src/contracts.rs b/types/src/contracts.rs index 576bf64300..1370d28662 100644 --- a/types/src/contracts.rs +++ b/types/src/contracts.rs @@ -1094,7 +1094,7 @@ mod tests { vec![], CLType::U32, EntryPointAccess::groups(&["Group 2"]), - EntryPointType::Session, + EntryPointType::Caller, ); ret.insert(entrypoint.name().to_owned(), entrypoint); let entrypoint = EntryPoint::new( @@ -1102,7 +1102,7 @@ mod tests { vec![Parameter::new("Foo", CLType::U32)], CLType::U32, EntryPointAccess::groups(&["Group 1"]), - EntryPointType::Session, + EntryPointType::Caller, ); ret.insert(entrypoint.name().to_owned(), entrypoint); ret diff --git a/types/src/gens.rs b/types/src/gens.rs index 5d38bf82ad..189b5637d5 100644 --- a/types/src/gens.rs +++ b/types/src/gens.rs @@ -47,7 +47,10 @@ use crate::{ ContractVersions, }, deploy_info::gens::{deploy_hash_arb, transfer_addr_arb}, - system::auction::{Bid, BidAddr, BidKind, ValidatorBid}, + system::{ + auction::{Bid, BidAddr, BidKind, ValidatorBid}, + mint::BalanceHoldAddr, + }, }; pub use crate::{deploy_info::gens::deploy_info_arb, transfer::gens::transfer_arb}; @@ -115,6 +118,7 @@ pub fn key_arb() -> impl Strategy { bid_addr_delegator_arb().prop_map(Key::BidAddr), account_hash_arb().prop_map(Key::Withdraw), u8_slice_32().prop_map(Key::Dictionary), + balance_hold_addr_arb().prop_map(Key::BalanceHold), Just(Key::EraSummary), ] } @@ -143,6 +147,12 @@ pub fn bid_addr_delegator_arb() -> impl Strategy { (x, y).prop_map(BidAddr::new_delegator_addr) } +pub fn balance_hold_addr_arb() -> impl Strategy { + let x = uref_arb().prop_map(|uref| uref.addr()); + let y = any::(); + (x, y).prop_map(|(x, y)| BalanceHoldAddr::new_gas(x, BlockTime::new(y))) +} + pub fn weight_arb() -> impl Strategy { any::().prop_map(Weight::new) } @@ -318,8 +328,8 @@ pub fn entry_point_access_arb() -> impl Strategy { pub fn entry_point_type_arb() -> impl Strategy { prop_oneof![ - Just(EntryPointType::Session), - Just(EntryPointType::AddressableEntity), + Just(EntryPointType::Caller), + Just(EntryPointType::Called), Just(EntryPointType::Factory), ] } diff --git a/types/src/key.rs b/types/src/key.rs index 209515731b..9c2510cd6c 100644 --- a/types/src/key.rs +++ b/types/src/key.rs @@ -31,6 +31,7 @@ use rand::{ #[cfg(feature = "json-schema")] use schemars::JsonSchema; use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer}; +use tracing::warn; use crate::{ account::{AccountHash, ACCOUNT_HASH_LENGTH}, @@ -46,7 +47,10 @@ use crate::{ contract_wasm::ContractWasmHash, contracts::{ContractHash, ContractPackageHash}, package::PackageHash, - system::auction::{BidAddr, BidAddrTag}, + system::{ + auction::{BidAddr, BidAddrTag}, + mint::BalanceHoldAddr, + }, uref::{self, URef, URefAddr, UREF_SERIALIZED_LENGTH}, ByteCodeAddr, DeployHash, Digest, EraId, Tagged, TransferAddr, TransferFromStrError, TRANSFER_ADDR_LENGTH, UREF_ADDR_LENGTH, @@ -56,6 +60,7 @@ const HASH_PREFIX: &str = "hash-"; const DEPLOY_INFO_PREFIX: &str = "deploy-"; const ERA_INFO_PREFIX: &str = "era-"; const BALANCE_PREFIX: &str = "balance-"; +const BALANCE_HOLD_PREFIX: &str = "balance-hold-"; const BID_PREFIX: &str = "bid-"; const WITHDRAW_PREFIX: &str = "withdraw-"; const DICTIONARY_PREFIX: &str = "dictionary-"; @@ -119,6 +124,141 @@ pub type PackageAddr = [u8; ADDR_LENGTH]; /// An alias for [`Key`]s dictionary variant. pub type DictionaryAddr = [u8; KEY_DICTIONARY_LENGTH]; +/// Errors produced when converting a `String` into a `Key`. +#[derive(Debug)] +#[non_exhaustive] +pub enum FromStrError { + /// Account parse error. + Account(addressable_entity::FromStrError), + /// Hash parse error. + Hash(String), + /// URef parse error. + URef(uref::FromStrError), + /// Transfer parse error. + Transfer(TransferFromStrError), + /// DeployInfo parse error. + DeployInfo(String), + /// EraInfo parse error. + EraInfo(String), + /// Balance parse error. + Balance(String), + /// Bid parse error. + Bid(String), + /// Withdraw parse error. + Withdraw(String), + /// Dictionary parse error. + Dictionary(String), + /// System contract registry parse error. + SystemContractRegistry(String), + /// Era summary parse error. + EraSummary(String), + /// Unbond parse error. + Unbond(String), + /// Chainspec registry error. + ChainspecRegistry(String), + /// Checksum registry error. + ChecksumRegistry(String), + /// Bid parse error. + BidAddr(String), + /// Package parse error. + Package(String), + /// Entity parse error. + AddressableEntity(String), + /// Byte code parse error. + ByteCode(String), + /// Message parse error. + Message(contract_messages::FromStrError), + /// Named key parse error. + NamedKey(String), + /// Balance hold parse error. + BalanceHold(String), + /// Unknown prefix. + UnknownPrefix, +} + +impl From for FromStrError { + fn from(error: addressable_entity::FromStrError) -> Self { + FromStrError::Account(error) + } +} + +impl From for FromStrError { + fn from(error: TransferFromStrError) -> Self { + FromStrError::Transfer(error) + } +} + +impl From for FromStrError { + fn from(error: uref::FromStrError) -> Self { + FromStrError::URef(error) + } +} + +impl From for FromStrError { + fn from(error: contract_messages::FromStrError) -> Self { + FromStrError::Message(error) + } +} + +impl Display for FromStrError { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + FromStrError::Account(error) => write!(f, "account-key from string error: {}", error), + FromStrError::Hash(error) => write!(f, "hash-key from string error: {}", error), + FromStrError::URef(error) => write!(f, "uref-key from string error: {}", error), + FromStrError::Transfer(error) => write!(f, "transfer-key from string error: {}", error), + FromStrError::DeployInfo(error) => { + write!(f, "deploy-info-key from string error: {}", error) + } + FromStrError::EraInfo(error) => write!(f, "era-info-key from string error: {}", error), + FromStrError::Balance(error) => write!(f, "balance-key from string error: {}", error), + FromStrError::Bid(error) => write!(f, "bid-key from string error: {}", error), + FromStrError::Withdraw(error) => write!(f, "withdraw-key from string error: {}", error), + FromStrError::Dictionary(error) => { + write!(f, "dictionary-key from string error: {}", error) + } + FromStrError::SystemContractRegistry(error) => { + write!( + f, + "system-contract-registry-key from string error: {}", + error + ) + } + FromStrError::EraSummary(error) => { + write!(f, "era-summary-key from string error: {}", error) + } + FromStrError::Unbond(error) => { + write!(f, "unbond-key from string error: {}", error) + } + FromStrError::ChainspecRegistry(error) => { + write!(f, "chainspec-registry-key from string error: {}", error) + } + FromStrError::ChecksumRegistry(error) => { + write!(f, "checksum-registry-key from string error: {}", error) + } + FromStrError::BidAddr(error) => write!(f, "bid-addr-key from string error: {}", error), + FromStrError::Package(error) => write!(f, "package-key from string error: {}", error), + FromStrError::AddressableEntity(error) => { + write!(f, "addressable-entity-key from string error: {}", error) + } + FromStrError::ByteCode(error) => { + write!(f, "byte-code-key from string error: {}", error) + } + FromStrError::Message(error) => { + write!(f, "message-key from string error: {}", error) + } + FromStrError::NamedKey(error) => { + write!(f, "named-key from string error: {}", error) + } + FromStrError::BalanceHold(error) => { + write!(f, "balance-hold from string error: {}", error) + } + + FromStrError::UnknownPrefix => write!(f, "unknown prefix for key"), + } + } +} + #[allow(missing_docs)] #[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] #[repr(u8)] @@ -144,6 +284,7 @@ pub enum KeyTag { ByteCode = 18, Message = 19, NamedKey = 20, + BalanceHold = 21, } impl KeyTag { @@ -171,6 +312,7 @@ impl KeyTag { 18 => KeyTag::ByteCode, 19 => KeyTag::Message, 20 => KeyTag::NamedKey, + 21 => KeyTag::BalanceHold, _ => panic!(), } } @@ -200,6 +342,7 @@ impl Display for KeyTag { KeyTag::ByteCode => write!(f, "ByteCode"), KeyTag::Message => write!(f, "Message"), KeyTag::NamedKey => write!(f, "NamedKey"), + KeyTag::BalanceHold => write!(f, "BalanceHold"), } } } @@ -246,6 +389,7 @@ impl FromBytes for KeyTag { tag if tag == KeyTag::ByteCode as u8 => KeyTag::ByteCode, tag if tag == KeyTag::Message as u8 => KeyTag::Message, tag if tag == KeyTag::NamedKey as u8 => KeyTag::NamedKey, + tag if tag == KeyTag::BalanceHold as u8 => KeyTag::BalanceHold, _ => return Err(Error::Formatting), }; Ok((tag, rem)) @@ -302,153 +446,8 @@ pub enum Key { Message(MessageAddr), /// A `Key` under which a single named key entry is stored. NamedKey(NamedKeyAddr), -} - -#[cfg(feature = "json-schema")] -impl JsonSchema for Key { - fn schema_name() -> String { - String::from("Key") - } - - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema = gen.subschema_for::(); - let mut schema_object = schema.into_object(); - schema_object.metadata().description = Some( - "The key as a formatted string, under which data (e.g. `CLValue`s, smart contracts, \ - user accounts) are stored in global state." - .to_string(), - ); - schema_object.into() - } -} - -/// Errors produced when converting a `String` into a `Key`. -#[derive(Debug)] -#[non_exhaustive] -pub enum FromStrError { - /// Account parse error. - Account(addressable_entity::FromStrError), - /// Hash parse error. - Hash(String), - /// URef parse error. - URef(uref::FromStrError), - /// Transfer parse error. - Transfer(TransferFromStrError), - /// DeployInfo parse error. - DeployInfo(String), - /// EraInfo parse error. - EraInfo(String), - /// Balance parse error. - Balance(String), - /// Bid parse error. - Bid(String), - /// Withdraw parse error. - Withdraw(String), - /// Dictionary parse error. - Dictionary(String), - /// System contract registry parse error. - SystemContractRegistry(String), - /// Era summary parse error. - EraSummary(String), - /// Unbond parse error. - Unbond(String), - /// Chainspec registry error. - ChainspecRegistry(String), - /// Checksum registry error. - ChecksumRegistry(String), - /// Bid parse error. - BidAddr(String), - /// Package parse error. - Package(String), - /// Entity parse error. - AddressableEntity(String), - /// Byte code parse error. - ByteCode(String), - /// Message parse error. - Message(contract_messages::FromStrError), - /// Named key parse error. - NamedKey(String), - /// Unknown prefix. - UnknownPrefix, -} - -impl From for FromStrError { - fn from(error: addressable_entity::FromStrError) -> Self { - FromStrError::Account(error) - } -} - -impl From for FromStrError { - fn from(error: TransferFromStrError) -> Self { - FromStrError::Transfer(error) - } -} - -impl From for FromStrError { - fn from(error: uref::FromStrError) -> Self { - FromStrError::URef(error) - } -} - -impl From for FromStrError { - fn from(error: contract_messages::FromStrError) -> Self { - FromStrError::Message(error) - } -} - -impl Display for FromStrError { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match self { - FromStrError::Account(error) => write!(f, "account-key from string error: {}", error), - FromStrError::Hash(error) => write!(f, "hash-key from string error: {}", error), - FromStrError::URef(error) => write!(f, "uref-key from string error: {}", error), - FromStrError::Transfer(error) => write!(f, "transfer-key from string error: {}", error), - FromStrError::DeployInfo(error) => { - write!(f, "deploy-info-key from string error: {}", error) - } - FromStrError::EraInfo(error) => write!(f, "era-info-key from string error: {}", error), - FromStrError::Balance(error) => write!(f, "balance-key from string error: {}", error), - FromStrError::Bid(error) => write!(f, "bid-key from string error: {}", error), - FromStrError::Withdraw(error) => write!(f, "withdraw-key from string error: {}", error), - FromStrError::Dictionary(error) => { - write!(f, "dictionary-key from string error: {}", error) - } - FromStrError::SystemContractRegistry(error) => { - write!( - f, - "system-contract-registry-key from string error: {}", - error - ) - } - FromStrError::EraSummary(error) => { - write!(f, "era-summary-key from string error: {}", error) - } - FromStrError::Unbond(error) => { - write!(f, "unbond-key from string error: {}", error) - } - FromStrError::ChainspecRegistry(error) => { - write!(f, "chainspec-registry-key from string error: {}", error) - } - FromStrError::ChecksumRegistry(error) => { - write!(f, "checksum-registry-key from string error: {}", error) - } - FromStrError::BidAddr(error) => write!(f, "bid-addr-key from string error: {}", error), - FromStrError::Package(error) => write!(f, "package-key from string error: {}", error), - FromStrError::AddressableEntity(error) => { - write!(f, "addressable-entity-key from string error: {}", error) - } - FromStrError::ByteCode(error) => { - write!(f, "byte-code-key from string error: {}", error) - } - FromStrError::Message(error) => { - write!(f, "message-key from string error: {}", error) - } - FromStrError::NamedKey(error) => { - write!(f, "named-key from string error: {}", error) - } - FromStrError::UnknownPrefix => write!(f, "unknown prefix for key"), - } - } + /// A `Key` under which a hold on a purse balance is stored. + BalanceHold(BalanceHoldAddr), } impl Key { @@ -477,6 +476,7 @@ impl Key { Key::ByteCode(..) => String::from("Key::ByteCode"), Key::Message(_) => String::from("Key::Message"), Key::NamedKey(_) => String::from("Key::NamedKey"), + Key::BalanceHold(_) => String::from("Key::BalanceHold"), } } @@ -576,6 +576,9 @@ impl Key { Key::NamedKey(named_key) => { format!("{}", named_key) } + Key::BalanceHold(balance_hold_addr) => { + format!("{}{}", BALANCE_HOLD_PREFIX, balance_hold_addr) + } } } @@ -1042,6 +1045,118 @@ impl Key { false } } + + /// Is the record under this key readable by the entity corresponding to the imputed address? + pub fn is_readable(&self, entity_addr: &EntityAddr) -> bool { + if entity_addr.is_system() { + // the system can read everything + return true; + } + let ret = match self { + Key::BidAddr(_) => { + // all bids are public information + true + } + Key::URef(uref) => { + // uref's require explicit permissions + uref.is_readable() + } + Key::SystemEntityRegistry | Key::Package(_) => { + // the system entities and all packages are public info + true + } + Key::AddressableEntity(addr_entity_addr) => { + // smart contracts and system contracts are public + // and an entity can read its own entity record + addr_entity_addr.tag() != EntityKindTag::Account || entity_addr == addr_entity_addr + } + Key::Account(account_hash) | Key::Unbond(account_hash) => { + // and an account holder can read their own account record + entity_addr.tag() == EntityKindTag::Account + && entity_addr.value() == account_hash.value() + } + Key::NamedKey(named_key_addr) => { + // an entity can read its own named keys + &named_key_addr.entity_addr() == entity_addr + } + _ => false, + }; + if !ret { + let reading_entity_key = Key::AddressableEntity(*entity_addr); + warn!(?reading_entity_key, attempted_key=?self, "attempt to read without permission") + } + ret + } + + /// Is the record under this key addable by the entity corresponding to the imputed address? + pub fn is_addable(&self, entity_addr: &EntityAddr) -> bool { + // unlike readable / writeable which are universally supported, + // only some data types support commutative add / extension + let ret = match self { + Key::URef(uref) => uref.is_addable(), + Key::AddressableEntity(addr_entity_addr) => { + // an entity can extend itself (only associated keys, currently) + entity_addr == addr_entity_addr + } + Key::NamedKey(named_key_addr) => { + // an entity can extend its own named keys + &named_key_addr.entity_addr() == entity_addr + } + _ => { + // other data types do not support commutative addition / extension + let adding_entity_key = Key::AddressableEntity(*entity_addr); + warn!(?adding_entity_key, attempted_key=?self, "attempt to add on an unsupported data type"); + return false; // we want the above more explicit warn message, not both messages. + } + }; + if !ret { + let adding_entity_key = Key::AddressableEntity(*entity_addr); + warn!(?adding_entity_key, attempted_key=?self, "attempt to add without permission"); + } + ret + } + + /// Is the record under this key writeable by the entity corresponding to the imputed address? + pub fn is_writeable(&self, entity_addr: &EntityAddr) -> bool { + if entity_addr.is_system() { + // the system can write everything + return true; + } + let ret = match self { + Key::URef(uref) => uref.is_writeable(), + Key::NamedKey(named_key_addr) => { + // an entity can write to its own named keys + &named_key_addr.entity_addr() == entity_addr + } + _ => { + // only the system can write other kinds of records + false + } + }; + if !ret { + let writing_entity_key = Key::AddressableEntity(*entity_addr); + warn!(?writing_entity_key, attempted_key=?self, "attempt to write without permission") + } + ret + } +} + +#[cfg(feature = "json-schema")] +impl JsonSchema for Key { + fn schema_name() -> String { + String::from("Key") + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema = gen.subschema_for::(); + let mut schema_object = schema.into_object(); + schema_object.metadata().description = Some( + "The key as a formatted string, under which data (e.g. `CLValue`s, smart contracts, \ + user accounts) are stored in global state." + .to_string(), + ); + schema_object.into() + } } impl Display for Key { @@ -1107,6 +1222,9 @@ impl Display for Key { Key::NamedKey(named_key_addr) => { write!(f, "Key::NamedKey({})", named_key_addr) } + Key::BalanceHold(balance_hold_addr) => { + write!(f, "Key::BalanceHold({})", balance_hold_addr) + } } } } @@ -1141,6 +1259,7 @@ impl Tagged for Key { Key::ByteCode(..) => KeyTag::ByteCode, Key::Message(_) => KeyTag::Message, Key::NamedKey(_) => KeyTag::NamedKey, + Key::BalanceHold(_) => KeyTag::BalanceHold, } } } @@ -1255,6 +1374,9 @@ impl ToBytes for Key { KEY_ID_SERIALIZED_LENGTH + message_addr.serialized_length() } Key::NamedKey(named_key) => U8_SERIALIZED_LENGTH + named_key.serialized_length(), + Key::BalanceHold(balance_hold_addr) => { + U8_SERIALIZED_LENGTH + balance_hold_addr.serialized_length() + } } } @@ -1289,6 +1411,7 @@ impl ToBytes for Key { Key::ByteCode(byte_code_addr) => byte_code_addr.write_bytes(writer), Key::Message(message_addr) => message_addr.write_bytes(writer), Key::NamedKey(named_key_addr) => named_key_addr.write_bytes(writer), + Key::BalanceHold(balance_hold_addr) => balance_hold_addr.write_bytes(writer), } } } @@ -1381,6 +1504,10 @@ impl FromBytes for Key { let (named_key_addr, rem) = NamedKeyAddr::from_bytes(remainder)?; Ok((Key::NamedKey(named_key_addr), rem)) } + KeyTag::BalanceHold => { + let (balance_hold_addr, rem) = BalanceHoldAddr::from_bytes(remainder)?; + Ok((Key::BalanceHold(balance_hold_addr), rem)) + } } } } @@ -1411,6 +1538,7 @@ fn please_add_to_distribution_impl(key: Key) { Key::ByteCode(..) => unimplemented!(), Key::Message(_) => unimplemented!(), Key::NamedKey(_) => unimplemented!(), + Key::BalanceHold(_) => unimplemented!(), } } @@ -1438,6 +1566,7 @@ impl Distribution for Standard { 17 => Key::AddressableEntity(rng.gen()), 18 => Key::ByteCode(rng.gen()), 19 => Key::Message(rng.gen()), + 20 => Key::BalanceHold(rng.gen()), _ => unreachable!(), } } @@ -1470,6 +1599,7 @@ mod serde_helpers { ByteCode(&'a ByteCodeAddr), Message(&'a MessageAddr), NamedKey(&'a NamedKeyAddr), + BalanceHold(&'a BalanceHoldAddr), } #[derive(Deserialize)] @@ -1496,6 +1626,7 @@ mod serde_helpers { ByteCode(ByteCodeAddr), Message(MessageAddr), NamedKey(NamedKeyAddr), + BalanceHold(BalanceHoldAddr), } impl<'a> From<&'a Key> for BinarySerHelper<'a> { @@ -1524,6 +1655,9 @@ mod serde_helpers { } Key::ByteCode(byte_code_addr) => BinarySerHelper::ByteCode(byte_code_addr), Key::NamedKey(named_key) => BinarySerHelper::NamedKey(named_key), + Key::BalanceHold(balance_hold_addr) => { + BinarySerHelper::BalanceHold(balance_hold_addr) + } } } } @@ -1554,6 +1688,9 @@ mod serde_helpers { } BinaryDeserHelper::ByteCode(byte_code_addr) => Key::ByteCode(byte_code_addr), BinaryDeserHelper::NamedKey(named_key_addr) => Key::NamedKey(named_key_addr), + BinaryDeserHelper::BalanceHold(balance_hold_addr) => { + Key::BalanceHold(balance_hold_addr) + } } } } @@ -1591,7 +1728,7 @@ mod tests { bytesrepr::{Error, FromBytes}, transfer::TRANSFER_ADDR_FORMATTED_STRING_PREFIX, uref::UREF_FORMATTED_STRING_PREFIX, - AccessRights, URef, + AccessRights, BlockTime, URef, }; const ENTITY_PREFIX: &str = "addressable-entity-"; @@ -1640,6 +1777,8 @@ mod tests { EntityAddr::new_contract_entity_addr([42; 32]), [43; 32], )); + const BALANCE_HOLD: Key = + Key::BalanceHold(BalanceHoldAddr::new_gas([42; 32], BlockTime::new(100))); const KEYS: &[Key] = &[ ACCOUNT_KEY, HASH_KEY, @@ -1668,6 +1807,7 @@ mod tests { MESSAGE_TOPIC_KEY, MESSAGE_KEY, NAMED_KEY, + BALANCE_HOLD, ]; const HEX_STRING: &str = "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"; const TOPIC_NAME_HEX_STRING: &str = @@ -2125,6 +2265,15 @@ mod tests { Key::from_formatted_str(no_prefix).unwrap_err().to_string(), "unknown prefix for key" ); + + let balance_hold_err = Key::from_formatted_str(BALANCE_HOLD_PREFIX) + .unwrap_err() + .to_string(); + assert!( + balance_hold_err.starts_with("balance-hold from string error: "), + "{}", + bid_addr_err + ); } #[test] @@ -2205,5 +2354,7 @@ mod tests { nines.into(), 1, ))); + round_trip(&Key::NamedKey(NamedKeyAddr::default())); + round_trip(&Key::BalanceHold(BalanceHoldAddr::default())); } } diff --git a/types/src/lib.rs b/types/src/lib.rs index 96717b35a1..f90844e85b 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -20,6 +20,7 @@ #[cfg_attr(not(test), macro_use)] extern crate alloc; + extern crate core; mod access_rights; diff --git a/types/src/package.rs b/types/src/package.rs index 9da3492e9b..792fab2e47 100644 --- a/types/src/package.rs +++ b/types/src/package.rs @@ -947,7 +947,7 @@ mod tests { vec![], CLType::U32, EntryPointAccess::groups(&["Group 2"]), - EntryPointType::Session, + EntryPointType::Caller, ); ret.insert(entrypoint.name().to_owned(), entrypoint); let entrypoint = EntryPoint::new( @@ -955,7 +955,7 @@ mod tests { vec![Parameter::new("Foo", CLType::U32)], CLType::U32, EntryPointAccess::groups(&["Group 1"]), - EntryPointType::Session, + EntryPointType::Caller, ); ret.insert(entrypoint.name().to_owned(), entrypoint); ret diff --git a/types/src/system/auction/entry_points.rs b/types/src/system/auction/entry_points.rs index 252550e548..41e421af96 100644 --- a/types/src/system/auction/entry_points.rs +++ b/types/src/system/auction/entry_points.rs @@ -21,7 +21,7 @@ pub fn auction_entry_points() -> EntryPoints { vec![], Option::::cl_type(), EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -34,7 +34,7 @@ pub fn auction_entry_points() -> EntryPoints { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -46,7 +46,7 @@ pub fn auction_entry_points() -> EntryPoints { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -59,7 +59,7 @@ pub fn auction_entry_points() -> EntryPoints { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -72,7 +72,7 @@ pub fn auction_entry_points() -> EntryPoints { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -86,7 +86,7 @@ pub fn auction_entry_points() -> EntryPoints { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -95,7 +95,7 @@ pub fn auction_entry_points() -> EntryPoints { vec![Parameter::new(ARG_ERA_END_TIMESTAMP_MILLIS, u64::cl_type())], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -104,7 +104,7 @@ pub fn auction_entry_points() -> EntryPoints { vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -116,7 +116,7 @@ pub fn auction_entry_points() -> EntryPoints { )], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -125,7 +125,7 @@ pub fn auction_entry_points() -> EntryPoints { vec![], CLType::U64, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -134,7 +134,7 @@ pub fn auction_entry_points() -> EntryPoints { vec![Parameter::new(ARG_VALIDATOR_PUBLIC_KEY, CLType::PublicKey)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); diff --git a/types/src/system/handle_payment/entry_points.rs b/types/src/system/handle_payment/entry_points.rs index f07b09f58d..daf8926f9e 100644 --- a/types/src/system/handle_payment/entry_points.rs +++ b/types/src/system/handle_payment/entry_points.rs @@ -19,7 +19,7 @@ pub fn handle_payment_entry_points() -> EntryPoints { vec![], CLType::URef, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(get_payment_purse); @@ -28,7 +28,7 @@ pub fn handle_payment_entry_points() -> EntryPoints { vec![Parameter::new(ARG_PURSE, CLType::URef)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(set_refund_purse); @@ -37,7 +37,7 @@ pub fn handle_payment_entry_points() -> EntryPoints { vec![], CLType::Option(Box::new(CLType::URef)), EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(get_refund_purse); @@ -49,7 +49,7 @@ pub fn handle_payment_entry_points() -> EntryPoints { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(finalize_payment); @@ -58,7 +58,7 @@ pub fn handle_payment_entry_points() -> EntryPoints { vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(distribute_accumulated_fees); diff --git a/types/src/system/mint.rs b/types/src/system/mint.rs index 4a7e58a170..3b37be8957 100644 --- a/types/src/system/mint.rs +++ b/types/src/system/mint.rs @@ -1,8 +1,10 @@ //! Contains implementation of a Mint contract functionality. +mod balance_hold; mod constants; mod entry_points; mod error; +pub use balance_hold::{BalanceHoldAddr, BalanceHoldAddrTag}; pub use constants::*; pub use entry_points::mint_entry_points; pub use error::Error; diff --git a/types/src/system/mint/balance_hold.rs b/types/src/system/mint/balance_hold.rs new file mode 100644 index 0000000000..4764b91685 --- /dev/null +++ b/types/src/system/mint/balance_hold.rs @@ -0,0 +1,267 @@ +use core::fmt::{Debug, Display, Formatter}; + +use alloc::vec::Vec; +#[cfg(any(feature = "std", test))] +use std::convert::TryFrom; + +#[cfg(feature = "datasize")] +use datasize::DataSize; +#[cfg(any(feature = "testing", test))] +use rand::distributions::{Distribution, Standard}; +#[cfg(any(feature = "testing", test))] +use rand::Rng; +#[cfg(feature = "json-schema")] +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use crate::{ + bytesrepr, + bytesrepr::{FromBytes, ToBytes}, + system::auction::Error, + BlockTime, Key, KeyTag, Timestamp, URefAddr, UREF_ADDR_LENGTH, +}; + +const BALANCE_HOLD_ADDR_TAG_LENGTH: u8 = 1; + +const GAS_TAG: u8 = 0; + +/// Serialization tag for BalanceHold variants. +#[derive( + Debug, Default, PartialOrd, Ord, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize, +)] +#[repr(u8)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +pub enum BalanceHoldAddrTag { + #[default] + /// Tag for gas variant. + Gas = GAS_TAG, +} + +impl BalanceHoldAddrTag { + /// The length in bytes of a [`BalanceHoldAddrTag`]. + pub const BALANCE_HOLD_ADDR_TAG_LENGTH: usize = 1; + + /// Attempts to map `BalanceHoldAddrTag` from a u8. + pub fn try_from_u8(value: u8) -> Option { + // TryFrom requires std, so doing this instead. + if value == GAS_TAG { + return Some(BalanceHoldAddrTag::Gas); + } + None + } +} + +impl Display for BalanceHoldAddrTag { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + let tag = match self { + BalanceHoldAddrTag::Gas => GAS_TAG, + }; + write!(f, "{}", base16::encode_lower(&[tag])) + } +} + +/// Balance hold address. +#[derive(PartialOrd, Ord, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +pub enum BalanceHoldAddr { + /// Gas hold variant. + Gas { + /// The address of the purse this hold is on. + purse_addr: URefAddr, + /// The block time this hold was placed. + block_time: BlockTime, + }, + // future balance hold variants might allow punitive lockup or settlement periods, etc +} + +impl BalanceHoldAddr { + /// The length in bytes of a [`BalanceHoldAddr`] for a gas hold address. + pub const GAS_HOLD_ADDR_LENGTH: usize = + UREF_ADDR_LENGTH + BalanceHoldAddrTag::BALANCE_HOLD_ADDR_TAG_LENGTH; + + /// Creates a Gas variant instance of [`BalanceHoldAddr`]. + #[cfg(any(feature = "testing", test))] + pub(crate) const fn new_gas(purse_addr: URefAddr, block_time: BlockTime) -> BalanceHoldAddr { + BalanceHoldAddr::Gas { + purse_addr, + block_time, + } + } + + /// How long is be the serialized value for this instance. + pub fn serialized_length(&self) -> usize { + match self { + BalanceHoldAddr::Gas { + purse_addr, + block_time, + } => { + BALANCE_HOLD_ADDR_TAG_LENGTH as usize + + ToBytes::serialized_length(purse_addr) + + ToBytes::serialized_length(block_time) + } + } + } + + /// Returns the tag of this instance. + pub fn tag(&self) -> BalanceHoldAddrTag { + match self { + BalanceHoldAddr::Gas { .. } => BalanceHoldAddrTag::Gas, + } + } + + /// Returns the `[URefAddr]` for the purse associated with this hold. + pub fn purse_addr(&self) -> URefAddr { + match self { + BalanceHoldAddr::Gas { purse_addr, .. } => *purse_addr, + } + } + + /// Returns the common prefix of all holds on the cited purse. + pub fn balance_hold_prefix(&self) -> Result, Error> { + let purse_addr_bytes = self.purse_addr().to_bytes()?; + let size = 1 + purse_addr_bytes.len(); + let mut ret = Vec::with_capacity(size); + ret.push(KeyTag::BalanceHold as u8); + ret.extend(purse_addr_bytes); + Ok(ret) + } +} + +impl ToBytes for BalanceHoldAddr { + fn to_bytes(&self) -> Result, bytesrepr::Error> { + let mut buffer = bytesrepr::allocate_buffer(self)?; + buffer.push(self.tag() as u8); + match self { + BalanceHoldAddr::Gas { + purse_addr, + block_time, + } => { + buffer.append(&mut purse_addr.to_bytes()?); + buffer.append(&mut block_time.to_bytes()?) + } + } + Ok(buffer) + } + + fn serialized_length(&self) -> usize { + self.serialized_length() + } +} + +impl FromBytes for BalanceHoldAddr { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (tag, remainder): (u8, &[u8]) = FromBytes::from_bytes(bytes)?; + match tag { + tag if tag == BalanceHoldAddrTag::Gas as u8 => { + let (purse_addr, rem) = URefAddr::from_bytes(remainder)?; + let (block_time, rem) = BlockTime::from_bytes(rem)?; + Ok(( + BalanceHoldAddr::Gas { + purse_addr, + block_time, + }, + rem, + )) + } + _ => Err(bytesrepr::Error::Formatting), + } + } +} + +impl Default for BalanceHoldAddr { + fn default() -> Self { + BalanceHoldAddr::Gas { + purse_addr: URefAddr::default(), + block_time: BlockTime::default(), + } + } +} + +impl From for Key { + fn from(balance_hold_addr: BalanceHoldAddr) -> Self { + Key::BalanceHold(balance_hold_addr) + } +} + +#[cfg(any(feature = "std", test))] +impl TryFrom for BalanceHoldAddr { + type Error = (); + + fn try_from(value: Key) -> Result { + if let Key::BalanceHold(balance_hold_addr) = value { + Ok(balance_hold_addr) + } else { + Err(()) + } + } +} + +impl Display for BalanceHoldAddr { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + let tag = self.tag(); + match self { + BalanceHoldAddr::Gas { + purse_addr, + block_time, + } => { + write!( + f, + "{}-{}-{}", + tag, + base16::encode_lower(&purse_addr), + Timestamp::from(block_time.value()) + ) + } + } + } +} + +impl Debug for BalanceHoldAddr { + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + match self { + BalanceHoldAddr::Gas { + purse_addr, + block_time, + } => write!( + f, + "BidAddr::Gas({}, {})", + base16::encode_lower(&purse_addr), + Timestamp::from(block_time.value()) + ), + } + } +} + +#[cfg(any(feature = "testing", test))] +impl Distribution for Standard { + fn sample(&self, rng: &mut R) -> BalanceHoldAddr { + BalanceHoldAddr::new_gas(rng.gen(), BlockTime::new(rng.gen())) + } +} + +#[cfg(test)] +mod tests { + use crate::{bytesrepr, system::mint::BalanceHoldAddr, BlockTime, Timestamp}; + + #[test] + fn serialization_roundtrip() { + let addr = BalanceHoldAddr::new_gas([1; 32], BlockTime::new(Timestamp::now().millis())); + bytesrepr::test_serialization_roundtrip(&addr); + } +} + +#[cfg(test)] +mod prop_test_gas { + use proptest::prelude::*; + + use crate::{bytesrepr, gens}; + + proptest! { + #[test] + fn test_variant_gas(addr in gens::balance_hold_addr_arb()) { + bytesrepr::test_serialization_roundtrip(&addr); + } + } +} diff --git a/types/src/system/mint/entry_points.rs b/types/src/system/mint/entry_points.rs index 6002b3383b..bc22fcec78 100644 --- a/types/src/system/mint/entry_points.rs +++ b/types/src/system/mint/entry_points.rs @@ -22,7 +22,7 @@ pub fn mint_entry_points() -> EntryPoints { err: Box::new(CLType::U8), }, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -34,7 +34,7 @@ pub fn mint_entry_points() -> EntryPoints { err: Box::new(CLType::U8), }, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -43,7 +43,7 @@ pub fn mint_entry_points() -> EntryPoints { Parameters::new(), CLType::URef, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -52,7 +52,7 @@ pub fn mint_entry_points() -> EntryPoints { vec![Parameter::new(ARG_PURSE, CLType::URef)], CLType::Option(Box::new(CLType::U512)), EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -70,7 +70,7 @@ pub fn mint_entry_points() -> EntryPoints { err: Box::new(CLType::U8), }, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -79,7 +79,7 @@ pub fn mint_entry_points() -> EntryPoints { Parameters::new(), CLType::U512, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); @@ -94,7 +94,7 @@ pub fn mint_entry_points() -> EntryPoints { err: Box::new(CLType::U8), }, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(entry_point); diff --git a/types/src/system/standard_payment/entry_points.rs b/types/src/system/standard_payment/entry_points.rs index 3eeaed52d6..fee12664a7 100644 --- a/types/src/system/standard_payment/entry_points.rs +++ b/types/src/system/standard_payment/entry_points.rs @@ -17,7 +17,7 @@ pub fn standard_payment_entry_points() -> EntryPoints { err: Box::new(CLType::U32), }, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::Caller, ); entry_points.add_entry_point(entry_point); diff --git a/utils/validation/src/generators.rs b/utils/validation/src/generators.rs index a1c33ebf8e..0fc5971332 100644 --- a/utils/validation/src/generators.rs +++ b/utils/validation/src/generators.rs @@ -351,7 +351,7 @@ pub fn make_abi_test_fixtures() -> Result { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::AddressableEntity, + EntryPointType::Called, ); entry_points.add_entry_point(public_contract_entry_point); From 19cdf76969346ffaa4bc58ad2ae38ee16157349f Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Tue, 12 Mar 2024 14:26:08 -0700 Subject: [PATCH 13/70] payment infrastructure wire up --- Cargo.lock | 61 ++++- .../src/engine_state/engine_config.rs | 20 +- execution_engine/src/engine_state/mod.rs | 26 +- execution_engine/src/execution/executor.rs | 4 + .../src/runtime/auction_internal.rs | 11 +- .../src/runtime/handle_payment_internal.rs | 8 +- execution_engine/src/runtime/mint_internal.rs | 20 +- execution_engine/src/runtime/mod.rs | 64 +++-- execution_engine/src/runtime/stack.rs | 6 +- execution_engine/src/runtime_context/mod.rs | 26 +- execution_engine/src/runtime_context/tests.rs | 9 +- .../test_support/src/wasm_test_builder.rs | 32 ++- .../tests/benches/auction_bench.rs | 18 +- .../src/test/contract_api/get_call_stack.rs | 14 +- .../tests/src/test/get_balance.rs | 7 +- node/Cargo.toml | 2 +- .../components/contract_runtime/operations.rs | 170 +++++++----- node/src/components/transaction_acceptor.rs | 13 +- .../components/transaction_acceptor/tests.rs | 14 +- node/src/components/upgrade_watcher.rs | 26 +- .../utils/chain_specification/parse_toml.rs | 7 +- resources/local/chainspec.toml.in | 2 + resources/production/chainspec.toml | 2 + resources/test/sse_data_schema.json | 4 +- storage/src/data_access_layer.rs | 4 + storage/src/data_access_layer/balance.rs | 135 +++++++++- storage/src/data_access_layer/balance_hold.rs | 253 ++++++++++++++++++ storage/src/data_access_layer/bidding.rs | 8 +- storage/src/global_state/state/mod.rs | 220 +++++++++++---- storage/src/system/auction.rs | 4 + storage/src/system/auction/auction_native.rs | 12 +- storage/src/system/auction/detail.rs | 10 +- storage/src/system/auction/providers.rs | 7 +- storage/src/system/handle_payment/internal.rs | 9 +- .../system/handle_payment/mint_provider.rs | 6 +- storage/src/system/mint.rs | 21 +- storage/src/system/mint/mint_native.rs | 10 +- storage/src/system/mint/storage_provider.rs | 6 +- storage/src/system/runtime_native.rs | 10 + storage/src/system/transfer.rs | 46 +++- storage/src/tracking_copy/ext.rs | 184 ++++++++++--- types/src/chainspec/core_config.rs | 16 +- types/src/chainspec/protocol_config.rs | 13 +- types/src/contract_messages/messages.rs | 20 +- types/src/key.rs | 10 + types/src/system/caller.rs | 53 ++-- types/src/system/mint/balance_hold.rs | 16 ++ types/src/system/mint/constants.rs | 2 + .../transaction/transaction_entry_point.rs | 14 + 49 files changed, 1303 insertions(+), 352 deletions(-) create mode 100644 storage/src/data_access_layer/balance_hold.rs diff --git a/Cargo.lock b/Cargo.lock index 5207b77f53..6f22caee7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -495,7 +495,7 @@ dependencies = [ "rand", "serde", "tempfile", - "toml", + "toml 0.5.11", "version-sync", ] @@ -678,7 +678,7 @@ dependencies = [ "tokio-serde", "tokio-stream", "tokio-util 0.6.10", - "toml", + "toml 0.7.8", "tower", "tracing", "tracing-futures", @@ -3017,7 +3017,7 @@ dependencies = [ "lmdb-rkv", "rand", "serde", - "toml", + "toml 0.5.11", ] [[package]] @@ -5208,6 +5208,15 @@ dependencies = [ "syn 2.0.28", ] +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + [[package]] name = "serde_test" version = "1.0.176" @@ -5827,6 +5836,41 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "indexmap 2.0.0", + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.0.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.4.13" @@ -6291,7 +6335,7 @@ dependencies = [ "regex", "semver", "syn 1.0.109", - "toml", + "toml 0.5.11", "url", ] @@ -6665,6 +6709,15 @@ version = "0.48.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d419259aba16b663966e29e6d7c6ecfa0bb8425818bb96f6f1f3c3eb71a6e7b9" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/execution_engine/src/engine_state/engine_config.rs b/execution_engine/src/engine_state/engine_config.rs index 8462392d73..f5ebcf5966 100644 --- a/execution_engine/src/engine_state/engine_config.rs +++ b/execution_engine/src/engine_state/engine_config.rs @@ -7,8 +7,8 @@ use num_rational::Ratio; use num_traits::One; use casper_types::{ - account::AccountHash, FeeHandling, PublicKey, RefundHandling, SystemConfig, WasmConfig, - DEFAULT_REFUND_HANDLING, + account::AccountHash, FeeHandling, PublicKey, RefundHandling, SystemConfig, TimeDiff, + WasmConfig, DEFAULT_REFUND_HANDLING, }; /// Default value for a maximum query depth configuration option. @@ -45,6 +45,8 @@ pub const DEFAULT_ALLOW_UNRESTRICTED_TRANSFERS: bool = true; pub const DEFAULT_FEE_HANDLING: FeeHandling = FeeHandling::PayToProposer; /// Default compute rewards. pub const DEFAULT_COMPUTE_REWARDS: bool = true; +/// Default period for balance holds to decay (currently 24 hours). +pub const DEFAULT_BALANCE_HOLD_INTERVAL: TimeDiff = TimeDiff::from_seconds(24 * 60 * 60); /// The runtime configuration of the execution engine #[derive(Debug, Clone)] @@ -79,6 +81,8 @@ pub struct EngineConfig { pub(crate) fee_handling: FeeHandling, /// Compute auction rewards. pub(crate) compute_rewards: bool, + /// The period over which balance holds decay. + pub(crate) balance_hold_interval: TimeDiff, } impl Default for EngineConfig { @@ -98,6 +102,7 @@ impl Default for EngineConfig { refund_handling: DEFAULT_REFUND_HANDLING, fee_handling: DEFAULT_FEE_HANDLING, compute_rewards: DEFAULT_COMPUTE_REWARDS, + balance_hold_interval: DEFAULT_BALANCE_HOLD_INTERVAL, } } } @@ -200,6 +205,7 @@ pub struct EngineConfigBuilder { refund_handling: Option, fee_handling: Option, compute_rewards: Option, + balance_hold_interval: Option, } impl EngineConfigBuilder { @@ -323,6 +329,12 @@ impl EngineConfigBuilder { self } + /// Sets balance hold interval config option. + pub fn balance_hold_interval(mut self, balance_hold_interval: TimeDiff) -> Self { + self.balance_hold_interval = Some(balance_hold_interval); + self + } + /// Builds a new [`EngineConfig`] object. pub fn build(self) -> EngineConfig { let max_associated_keys = self @@ -362,6 +374,9 @@ impl EngineConfigBuilder { .max_delegators_per_validator .unwrap_or(DEFAULT_MAX_DELEGATORS_PER_VALIDATOR); let compute_rewards = self.compute_rewards.unwrap_or(DEFAULT_COMPUTE_REWARDS); + let balance_hold_interval = self + .balance_hold_interval + .unwrap_or(DEFAULT_BALANCE_HOLD_INTERVAL); EngineConfig { max_associated_keys, @@ -378,6 +393,7 @@ impl EngineConfigBuilder { vesting_schedule_period_millis, max_delegators_per_validator, compute_rewards, + balance_hold_interval, } } } diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index b3accdfffe..e51f32187c 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -16,12 +16,13 @@ use casper_storage::{ data_access_layer::TransferRequest, global_state::state::StateProvider, system::runtime_native::TransferConfig, - tracking_copy::{FeesPurseHandling, TrackingCopyEntityExt, TrackingCopyExt}, + tracking_copy::{FeesPurseHandling, TrackingCopyEntityExt, TrackingCopyError, TrackingCopyExt}, }; use casper_types::{ system::{ handle_payment::{self}, + mint::ARG_HOLDS_EPOCH, HANDLE_PAYMENT, }, BlockTime, DeployInfo, Digest, EntityAddr, ExecutableDeployItem, FeeHandling, Gas, Key, Motes, @@ -154,6 +155,7 @@ impl ExecutionEngineV1 { let compute_rewards = self.config.compute_rewards; let max_delegators_per_validator = self.config.max_delegators_per_validator(); let minimum_delegation_amount = self.config.minimum_delegation_amount(); + let balance_hold_interval = self.config.balance_hold_interval.millis(); let native_runtime_config = casper_storage::system::runtime_native::Config::new( transfer_config, @@ -164,13 +166,21 @@ impl ExecutionEngineV1 { compute_rewards, max_delegators_per_validator, minimum_delegation_amount, + balance_hold_interval, ); let wasmless_transfer_gas = Gas::new(U512::from( self.config().system_config().wasmless_transfer_cost(), )); - let transaction_hash = TransactionHash::Deploy(deploy_hash); - + let holds_epoch = Some( + blocktime + .value() + .saturating_sub(self.config.balance_hold_interval.millis()), + ); + let mut runtime_args = deploy_item.session.args().clone(); + if let Err(cve) = runtime_args.insert(ARG_HOLDS_EPOCH, holds_epoch) { + return Err(Error::TrackingCopy(TrackingCopyError::CLValue(cve))); + } let transfer_req = TransferRequest::with_runtime_args( native_runtime_config, prestate_hash, @@ -179,7 +189,7 @@ impl ExecutionEngineV1 { transaction_hash, deploy_item.address, deploy_item.authorization_keys, - deploy_item.session.args().clone(), + runtime_args, wasmless_transfer_gas.value(), ); let transfer_result = state_provider.transfer(transfer_req); @@ -292,11 +302,15 @@ impl ExecutionEngineV1 { } }; + let holds_epoch = blocktime + .value() + .saturating_sub(self.config.balance_hold_interval.millis()); + // Get account main purse balance to enforce precondition and in case of forced // transfer validation_spec_5: account main purse minimum balance let account_main_purse_balance: Motes = match tracking_copy .borrow_mut() - .get_purse_balance(entity_main_purse_key) + .get_available_balance(entity_main_purse_key, Some(holds_epoch)) { Ok(balance) => balance, Err(error) => return Ok(ExecutionResult::precondition_failure(error.into())), @@ -545,7 +559,7 @@ impl ExecutionEngineV1 { let payment_purse_balance: Motes = { match tracking_copy .borrow_mut() - .get_purse_balance(purse_balance_key) + .get_available_balance(purse_balance_key, Some(holds_epoch)) { Ok(balance) => balance, Err(error) => { diff --git a/execution_engine/src/execution/executor.rs b/execution_engine/src/execution/executor.rs index e853c7ef7d..ce33e21a46 100644 --- a/execution_engine/src/execution/executor.rs +++ b/execution_engine/src/execution/executor.rs @@ -370,6 +370,9 @@ impl Executor { None => return Err(EngineStateError::reverter(ApiError::HandlePayment(12))), }; + let holds_epoch = blocktime + .value() + .saturating_sub(self.config.balance_hold_interval.millis()); let runtime_args = { let transfer_args = TransferArgs::new( None, @@ -377,6 +380,7 @@ impl Executor { payment_purse, payment_amount, None, + Some(holds_epoch), ); match RuntimeArgs::try_from(transfer_args) { diff --git a/execution_engine/src/runtime/auction_internal.rs b/execution_engine/src/runtime/auction_internal.rs index a281f34086..ea34b25dfd 100644 --- a/execution_engine/src/runtime/auction_internal.rs +++ b/execution_engine/src/runtime/auction_internal.rs @@ -244,6 +244,7 @@ where contract.main_purse(), *unbonding_purse.amount(), None, + None, ) .map_err(|_| Error::Transfer)? .map_err(|_| Error::Transfer)?; @@ -264,6 +265,7 @@ where target: URef, amount: U512, id: Option, + holds_epoch: Option, ) -> Result, Error> { if !(self.context.entity().main_purse().addr() == source.addr() || self.context.get_caller() == PublicKey::System.to_account_hash()) @@ -277,6 +279,7 @@ where args.insert(mint::ARG_TARGET, target)?; args.insert(mint::ARG_AMOUNT, amount)?; args.insert(mint::ARG_ID, id)?; + args.insert(mint::ARG_HOLDS_EPOCH, holds_epoch)?; Ok(()) }) .map_err(|_| Error::CLValue)?; @@ -340,8 +343,12 @@ where }) } - fn get_balance(&mut self, purse: URef) -> Result, Error> { - Runtime::get_balance(self, purse) + fn available_balance( + &mut self, + purse: URef, + holds_epoch: Option, + ) -> Result, Error> { + Runtime::available_balance(self, purse, holds_epoch) .map_err(|exec_error| >::from(exec_error).unwrap_or(Error::GetBalance)) } diff --git a/execution_engine/src/runtime/handle_payment_internal.rs b/execution_engine/src/runtime/handle_payment_internal.rs index 13637c6a94..006d3bfe83 100644 --- a/execution_engine/src/runtime/handle_payment_internal.rs +++ b/execution_engine/src/runtime/handle_payment_internal.rs @@ -64,8 +64,12 @@ where } } - fn balance(&mut self, purse: URef) -> Result, Error> { - self.get_balance(purse) + fn available_balance( + &mut self, + purse: URef, + holds_epoch: Option, + ) -> Result, Error> { + Runtime::available_balance(self, purse, holds_epoch) .map_err(|exec_error| >::from(exec_error).unwrap_or(Error::GetBalance)) } diff --git a/execution_engine/src/runtime/mint_internal.rs b/execution_engine/src/runtime/mint_internal.rs index 064a2c19ba..8709f79318 100644 --- a/execution_engine/src/runtime/mint_internal.rs +++ b/execution_engine/src/runtime/mint_internal.rs @@ -140,19 +140,13 @@ where .map_err(|exec_error| >::from(exec_error).unwrap_or(Error::Storage)) } - fn read_balance(&mut self, uref: URef) -> Result, Error> { - let maybe_value = self - .context - .read_gs_unsafe(&Key::Balance(uref.addr())) - .map_err(|exec_error| >::from(exec_error).unwrap_or(Error::Storage))?; - match maybe_value { - Some(StoredValue::CLValue(value)) => { - let value = CLValue::into_t(value).map_err(|_| Error::CLValue)?; - Ok(Some(value)) - } - Some(_cl_value) => Err(Error::CLValue), - None => Ok(None), - } + fn available_balance( + &mut self, + purse: URef, + holds_epoch: Option, + ) -> Result, Error> { + Runtime::available_balance(self, purse, holds_epoch) + .map_err(|exec_error| >::from(exec_error).unwrap_or(Error::Storage)) } fn write_balance(&mut self, uref: URef, balance: U512) -> Result<(), Error> { diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index 6d140772e4..f92d8785f6 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -398,7 +398,7 @@ where return true; } - if let Some(Caller::Session { account_hash }) = self.get_immediate_caller() { + if let Some(Caller::Initiator { account_hash }) = self.get_immediate_caller() { return account_hash == provided_account_hash; } false @@ -556,6 +556,14 @@ where } } + /// Returns holds epoch. + fn holds_epoch(&self) -> u64 { + self.context + .get_blocktime() + .value() + .saturating_sub(self.context.engine_config().balance_hold_interval.millis()) + } + /// Calls host mint contract. fn call_host_mint( &mut self, @@ -622,8 +630,10 @@ where mint_runtime.charge_system_contract_call(mint_costs.balance)?; let uref: URef = Self::get_named_argument(runtime_args, mint::ARG_PURSE)?; - let maybe_balance: Option = - mint_runtime.balance(uref).map_err(Self::reverter)?; + + let maybe_balance: Option = mint_runtime + .balance(uref, Some(self.holds_epoch())) + .map_err(Self::reverter)?; CLValue::from_t(maybe_balance).map_err(Self::reverter) })(), // Type: `fn transfer(maybe_to: Option, source: URef, target: URef, amount: @@ -637,8 +647,14 @@ where let target: URef = Self::get_named_argument(runtime_args, mint::ARG_TARGET)?; let amount: U512 = Self::get_named_argument(runtime_args, mint::ARG_AMOUNT)?; let id: Option = Self::get_named_argument(runtime_args, mint::ARG_ID)?; - let result: Result<(), mint::Error> = - mint_runtime.transfer(maybe_to, source, target, amount, id); + let result: Result<(), mint::Error> = mint_runtime.transfer( + maybe_to, + source, + target, + amount, + id, + Some(self.holds_epoch()), + ); CLValue::from_t(result).map_err(Self::reverter) })(), @@ -842,9 +858,10 @@ where let delegation_rate = Self::get_named_argument(runtime_args, auction::ARG_DELEGATION_RATE)?; let amount = Self::get_named_argument(runtime_args, auction::ARG_AMOUNT)?; + let holds_epoch = Some(self.holds_epoch()); let result = runtime - .add_bid(account_hash, delegation_rate, amount) + .add_bid(account_hash, delegation_rate, amount, holds_epoch) .map_err(Self::reverter)?; CLValue::from_t(result).map_err(Self::reverter) @@ -873,7 +890,7 @@ where self.context.engine_config().max_delegators_per_validator(); let minimum_delegation_amount = self.context.engine_config().minimum_delegation_amount(); - + let holds_epoch = Some(self.holds_epoch()); let result = runtime .delegate( delegator, @@ -881,6 +898,7 @@ where amount, max_delegators_per_validator, minimum_delegation_amount, + holds_epoch, ) .map_err(Self::reverter)?; @@ -1393,7 +1411,7 @@ where let stack = { let mut stack = self.try_get_stack()?.clone(); - stack.push(Caller::stored_contract(entity.package_hash(), entity_hash))?; + stack.push(Caller::entity(entity.package_hash(), entity_hash))?; stack }; @@ -2503,9 +2521,14 @@ where return Err(ExecError::DisabledUnrestrictedTransfers); } + let holds_epoch = self.holds_epoch(); // A precondition check that verifies that the transfer can be done // as the source purse has enough funds to cover the transfer. - if amount > self.get_balance(source)?.unwrap_or_default() { + if amount + > self + .available_balance(source, Some(holds_epoch))? + .unwrap_or_default() + { return Ok(Err(mint::Error::InsufficientFunds.into())); } @@ -2754,15 +2777,14 @@ where } } - fn get_balance(&mut self, purse: URef) -> Result, ExecError> { - let maybe_value = self.context.read_gs_unsafe(&Key::Balance(purse.addr()))?; - match maybe_value { - Some(StoredValue::CLValue(value)) => { - let value = CLValue::into_t(value)?; - Ok(Some(value)) - } - Some(_) => Err(ExecError::UnexpectedStoredValueVariant), - None => Ok(None), + fn available_balance( + &mut self, + purse: URef, + holds_epoch: Option, + ) -> Result, ExecError> { + match self.context.available_balance(&purse, holds_epoch) { + Ok(motes) => Ok(Some(motes.value())), + Err(err) => Err(err), } } @@ -2785,7 +2807,7 @@ where } }; - let balance = match self.get_balance(purse)? { + let balance = match self.available_balance(purse, Some(self.holds_epoch()))? { Some(balance) => balance, None => return Ok(Err(ApiError::InvalidPurse)), }; @@ -3329,11 +3351,11 @@ where }; match immediate_caller { - Caller::Session { account_hash } => { + Caller::Initiator { account_hash } => { // This case can happen during genesis where we're setting up purses for accounts. Ok(account_hash == &PublicKey::System.to_account_hash()) } - Caller::AddressableEntity { + Caller::Entity { entity_hash: contract_hash, .. } => Ok(self.context.is_system_addressable_entity(contract_hash)?), diff --git a/execution_engine/src/runtime/stack.rs b/execution_engine/src/runtime/stack.rs index 153f12a4a8..18fc1deac9 100644 --- a/execution_engine/src/runtime/stack.rs +++ b/execution_engine/src/runtime/stack.rs @@ -46,7 +46,7 @@ impl RuntimeStack { pub(crate) fn new_system_call_stack(max_height: usize) -> Self { RuntimeStack::new_with_frame( max_height, - Caller::session(PublicKey::System.to_account_hash()), + Caller::initiator(PublicKey::System.to_account_hash()), ) } @@ -101,7 +101,7 @@ impl RuntimeStack { /// Returns a stack with exactly one session element with the associated account hash. pub fn from_account_hash(account_hash: AccountHash, max_height: usize) -> Self { RuntimeStack { - frames: vec![Caller::session(account_hash)], + frames: vec![Caller::initiator(account_hash)], max_height, } } @@ -119,7 +119,7 @@ mod test { let mut bytes = [0_u8; ACCOUNT_HASH_LENGTH]; let n: u32 = n.try_into().unwrap(); bytes[0..4].copy_from_slice(&n.to_le_bytes()); - Caller::session(AccountHash::new(bytes)) + Caller::initiator(AccountHash::new(bytes)) } #[allow(clippy::redundant_clone)] diff --git a/execution_engine/src/runtime_context/mod.rs b/execution_engine/src/runtime_context/mod.rs index 811e1db771..c5502ae7a5 100644 --- a/execution_engine/src/runtime_context/mod.rs +++ b/execution_engine/src/runtime_context/mod.rs @@ -34,7 +34,7 @@ use casper_types::{ system::auction::EraInfo, AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, CLType, CLValue, CLValueDictionary, ContextAccessRights, DeployHash, EntityAddr, EntryPointType, Gas, - GrantedAccess, Key, KeyTag, Package, PackageHash, Phase, ProtocolVersion, PublicKey, + GrantedAccess, Key, KeyTag, Motes, Package, PackageHash, Phase, ProtocolVersion, PublicKey, RuntimeArgs, StoredValue, StoredValueTypeMismatch, SystemEntityRegistry, Transfer, TransferAddr, URef, URefAddr, DICTIONARY_ITEM_KEY_MAX_LENGTH, KEY_HASH_LENGTH, U512, }; @@ -415,31 +415,25 @@ where /// Reads the balance of a purse [`URef`]. /// /// Currently address of a purse [`URef`] is also a hash in the [`Key::Hash`] space. - #[cfg(test)] - pub(crate) fn read_purse_uref( + pub(crate) fn available_balance( &mut self, purse_uref: &URef, - ) -> Result, ExecError> { - match self - .tracking_copy + holds_epoch: Option, + ) -> Result { + let key = Key::URef(*purse_uref); + self.tracking_copy .borrow_mut() - .read(&Key::Hash(purse_uref.addr())) - .map_err(ExecError::TrackingCopy)? - { - Some(stored_value) => Ok(Some( - stored_value.try_into().map_err(ExecError::TypeMismatch)?, - )), - None => Ok(None), - } + .get_available_balance(key, holds_epoch) + .map_err(ExecError::TrackingCopy) } #[cfg(test)] - pub(crate) fn write_purse_uref( + pub(crate) fn write_balance( &mut self, purse_uref: URef, cl_value: CLValue, ) -> Result<(), ExecError> { - self.metered_write_gs_unsafe(Key::Hash(purse_uref.addr()), cl_value) + self.metered_write_gs_unsafe(Key::Balance(purse_uref.addr()), cl_value) } /// Read a stored value under a [`Key`]. diff --git a/execution_engine/src/runtime_context/tests.rs b/execution_engine/src/runtime_context/tests.rs index 0fd4061a74..5253345cf7 100644 --- a/execution_engine/src/runtime_context/tests.rs +++ b/execution_engine/src/runtime_context/tests.rs @@ -835,17 +835,18 @@ fn can_roundtrip_key_value_pairs() { .as_uref() .cloned() .expect("must have created URef from the key"); - let test_value = CLValue::from_t("test_value".to_string()).unwrap(); + let expected = CLValue::from_t(U512::zero()).unwrap(); runtime_context - .write_purse_uref(test_uref.to_owned(), test_value.clone()) + .write_balance(test_uref.to_owned(), expected.clone()) .expect("should write_ls"); let result = runtime_context - .read_purse_uref(&test_uref) + .available_balance(&test_uref, None) .expect("should read_ls"); - Ok(result == Some(test_value)) + let actual = CLValue::from_t(result.value()).unwrap(); + Ok(actual == expected) }; let result = build_runtime_context_and_execute(named_keys, functor).expect("should be ok"); assert!(result) diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index e42f4f10e6..300d6e041b 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -20,9 +20,9 @@ use casper_execution_engine::engine_state::{ }; use casper_storage::{ data_access_layer::{ - BalanceRequest, BalanceResult, BidsRequest, BlockRewardsRequest, BlockRewardsResult, - BlockStore, DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, FeeRequest, - FeeResult, FlushRequest, FlushResult, GenesisRequest, GenesisResult, + balance::BalanceHandling, BalanceRequest, BalanceResult, BidsRequest, BlockRewardsRequest, + BlockRewardsResult, BlockStore, DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, + FeeRequest, FeeResult, FlushRequest, FlushResult, GenesisRequest, GenesisResult, ProtocolUpgradeRequest, ProtocolUpgradeResult, PruneRequest, PruneResult, QueryRequest, QueryResult, StepRequest, StepResult, SystemEntityRegistryPayload, SystemEntityRegistryRequest, SystemEntityRegistryResult, SystemEntityRegistrySelector, @@ -856,6 +856,7 @@ where let compute_rewards = self.chainspec.core_config.compute_rewards; let max_delegators_per_validator = self.chainspec.core_config.max_delegators_per_validator; let minimum_delegation_amount = self.chainspec.core_config.minimum_delegation_amount; + let balance_hold_interval = self.chainspec.core_config.balance_hold_interval.millis(); NativeRuntimeConfig::new( transfer_config, fee_handling, @@ -865,6 +866,7 @@ where compute_rewards, max_delegators_per_validator, minimum_delegation_amount, + balance_hold_interval, ) } @@ -1138,9 +1140,17 @@ where &self, protocol_version: ProtocolVersion, purse: URef, + block_time: u64, ) -> BalanceResult { + let hold_interval = self.chainspec.core_config.balance_hold_interval.millis(); + let balance_handling = BalanceHandling::Available { + block_time, + hold_interval, + }; + let state_root_hash: Digest = self.post_state_hash.expect("should have post_state_hash"); - let request = BalanceRequest::from_purse(state_root_hash, protocol_version, purse); + let request = + BalanceRequest::from_purse(state_root_hash, protocol_version, purse, balance_handling); self.data_access_layer.balance(request) } @@ -1149,10 +1159,20 @@ where &self, protocol_version: ProtocolVersion, public_key: PublicKey, + block_time: u64, ) -> BalanceResult { let state_root_hash: Digest = self.post_state_hash.expect("should have post_state_hash"); - let request = - BalanceRequest::from_public_key(state_root_hash, protocol_version, public_key); + let hold_interval = self.chainspec.core_config.balance_hold_interval.millis(); + let balance_handling = BalanceHandling::Available { + block_time, + hold_interval, + }; + let request = BalanceRequest::from_public_key( + state_root_hash, + protocol_version, + public_key, + balance_handling, + ); self.data_access_layer.balance(request) } diff --git a/execution_engine_testing/tests/benches/auction_bench.rs b/execution_engine_testing/tests/benches/auction_bench.rs index 693d1a0ab0..14199143fe 100644 --- a/execution_engine_testing/tests/benches/auction_bench.rs +++ b/execution_engine_testing/tests/benches/auction_bench.rs @@ -149,26 +149,26 @@ fn setup_bench_run_auction( let contract_hash = builder.get_auction_contract_hash(); let mut next_validator_iter = validator_keys.iter().cycle(); for delegator_public_key in delegator_keys { - let balance = builder - .get_public_key_balance_result(protocol_version, delegator_public_key.clone()) - .motes() - .cloned() - .unwrap(); - - assert_eq!(U512::from(DELEGATOR_INITIAL_BALANCE), balance); - let delegation_amount = U512::from(DELEGATION_AMOUNT); let delegator_account_hash = delegator_public_key.to_account_hash(); let next_validator_key = next_validator_iter .next() .expect("should produce values forever"); let delegate = create_delegate_request( - delegator_public_key, + delegator_public_key.clone(), next_validator_key.clone(), delegation_amount, delegator_account_hash, contract_hash, ); + let block_time = delegate.block_time; + let balance = builder + .get_public_key_balance_result(protocol_version, delegator_public_key, block_time) + .motes() + .cloned() + .unwrap(); + + assert_eq!(U512::from(DELEGATOR_INITIAL_BALANCE), balance); builder.exec(delegate); builder.expect_success(); builder.commit(); diff --git a/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs b/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs index 297db3b2f1..e8b89c4a5b 100644 --- a/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs +++ b/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs @@ -233,7 +233,7 @@ fn assert_each_context_has_correct_call_stack_info( assert_eq!( head, - [Caller::Session { + [Caller::Initiator { account_hash: *DEFAULT_ACCOUNT_ADDR, }], ); @@ -263,7 +263,7 @@ fn assert_each_context_has_correct_call_stack_info_module_bytes( let (head, _) = call_stack.split_at(usize::one()); assert_eq!( head, - [Caller::Session { + [Caller::Initiator { account_hash: *DEFAULT_ACCOUNT_ADDR, }], ); @@ -284,7 +284,7 @@ fn assert_each_context_has_correct_call_stack_info_module_bytes( let (head, rest) = call_stack.split_at(usize::one()); assert_eq!( head, - [Caller::Session { + [Caller::Initiator { account_hash: *DEFAULT_ACCOUNT_ADDR, }], ); @@ -296,7 +296,7 @@ fn assert_call_stack_matches_calls(call_stack: Vec, calls: &[Call]) { for (index, expected_call_stack_element) in call_stack.iter().enumerate() { let maybe_call = calls.get(index); match (maybe_call, expected_call_stack_element) { - // Versioned Call with EntryPointType::Contract + // Versioned Call with EntryPointType::Called ( Some(Call { entry_point_type, @@ -304,21 +304,21 @@ fn assert_call_stack_matches_calls(call_stack: Vec, calls: &[Call]) { ContractAddress::ContractPackageHash(current_contract_package_hash), .. }), - Caller::AddressableEntity { + Caller::Entity { package_hash: contract_package_hash, .. }, ) if *entry_point_type == EntryPointType::Called && *contract_package_hash == *current_contract_package_hash => {} - // Unversioned Call with EntryPointType::Contract + // Unversioned Call with EntryPointType::Called ( Some(Call { entry_point_type, contract_address: ContractAddress::ContractHash(current_contract_hash), .. }), - Caller::AddressableEntity { + Caller::Entity { entity_hash: contract_hash, .. }, diff --git a/execution_engine_testing/tests/src/test/get_balance.rs b/execution_engine_testing/tests/src/test/get_balance.rs index 29e87c3bfd..a648b2fa74 100644 --- a/execution_engine_testing/tests/src/test/get_balance.rs +++ b/execution_engine_testing/tests/src/test/get_balance.rs @@ -39,6 +39,7 @@ fn get_balance_should_work() { ) .build(); + let block_time = transfer_request.block_time; builder.exec(transfer_request).commit().expect_success(); let alice_account = builder @@ -47,7 +48,8 @@ fn get_balance_should_work() { let alice_main_purse = alice_account.main_purse(); - let alice_balance_result = builder.get_purse_balance_result(protocol_version, alice_main_purse); + let alice_balance_result = + builder.get_purse_balance_result(protocol_version, alice_main_purse, block_time); let alice_balance = alice_balance_result .motes() @@ -130,6 +132,7 @@ fn get_balance_using_public_key_should_work() { ) .build(); + let block_time = transfer_request.block_time; builder.exec(transfer_request).commit().expect_success(); let alice_account = builder @@ -139,7 +142,7 @@ fn get_balance_using_public_key_should_work() { let alice_main_purse = alice_account.main_purse(); let alice_balance_result = - builder.get_public_key_balance_result(protocol_version, ALICE_KEY.clone()); + builder.get_public_key_balance_result(protocol_version, ALICE_KEY.clone(), block_time); let alice_balance = alice_balance_result .motes() diff --git a/node/Cargo.toml b/node/Cargo.toml index eb6f354eb0..cbcd67db16 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -84,7 +84,7 @@ tokio-serde = { version = "0.8.0", features = ["bincode"] } tokio-stream = { version = "0.1.4", features = ["sync"] } tokio-util = { version = "0.6.4", features = ["codec"] } mio = "0.8.11" -toml = "0.5.6" +toml = { version = "0.7.8", features = ["preserve_order"] } tower = { version = "0.4.6", features = ["limit"] } tracing = "0.1.18" tracing-futures = "0.2.5" diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index bbd2e2a0ab..0a9c346ad2 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -30,6 +30,7 @@ use casper_types::{ bytesrepr::{self, ToBytes, U32_SERIALIZED_LENGTH}, contract_messages::Messages, execution::{Effects, ExecutionResult, ExecutionResultV2, Transform, TransformKind}, + system::mint::ARG_HOLDS_EPOCH, BlockV2, CLValue, Chainspec, ChecksumRegistry, DeployHash, Digest, EraEndV2, EraId, Key, ProtocolVersion, PublicKey, Transaction, TransactionApprovalsHash, U512, }; @@ -80,6 +81,9 @@ pub fn execute_finalized_block( let mut execution_artifacts: Vec = Vec::with_capacity(executable_block.transactions.len()); let block_time = executable_block.timestamp.millis(); + let holds_epoch = + block_time.saturating_sub(chainspec.core_config.balance_hold_interval.millis()); + let start = Instant::now(); let txn_ids = executable_block .transactions @@ -94,64 +98,47 @@ pub fn execute_finalized_block( let scratch_state = data_access_layer.get_scratch_global_state(); let mut effects = Effects::new(); - // Pay out fees, if relevant. - { - let fee_req = FeeRequest::new( - native_runtime_config.clone(), - state_root_hash, - protocol_version, - block_time, - ); - match scratch_state.distribute_fees(fee_req) { - FeeResult::RootNotFound => { - return Err(BlockExecutionError::RootNotFound(state_root_hash)) - } - FeeResult::Failure(fer) => return Err(BlockExecutionError::DistributeFees(fer)), - FeeResult::Success { - //transfers: fee_transfers, - post_state_hash, - .. - } => { - //transfers.extend(fee_transfers); - state_root_hash = post_state_hash; - // TODO: looks like effects & transfer records are associated with the - // ExecutionResult struct which assumes they were caused by a - // deploy. however, systemic operations produce effects and transfer - // records also. + for transaction in executable_block.transactions { + let transaction_hash = transaction.hash(); + let mut runtime_args = transaction.session_args().clone(); + let entry_point = transaction.entry_point(); + if entry_point.requires_holds_epoch() { + if let Err(cve) = runtime_args.insert(ARG_HOLDS_EPOCH, Some(holds_epoch)) { + error!(%transaction_hash, ?cve, "failed to extend args with holds epoch"); + continue; // skip to next record } } - } - // Pay out ̶b̶l̶o̶c̶k̶ e͇r͇a͇ rewards - // NOTE: despite the name, these rewards are currently paid out per ERA not per BLOCK - // at one point, they were going to be paid out per block (and might be in the future) - // but it ended up settling on per era. the behavior is driven by Some / None as sent - // thus if in future calling logic passes rewards per block it should just work as is. - if let Some(rewards) = &executable_block.rewards { - let rewards_req = BlockRewardsRequest::new( - native_runtime_config.clone(), - state_root_hash, - protocol_version, - block_time, - rewards.clone(), - ); - match scratch_state.distribute_block_rewards(rewards_req) { - BlockRewardsResult::RootNotFound => { - return Err(BlockExecutionError::RootNotFound(state_root_hash)) - } - BlockRewardsResult::Failure(bre) => { - return Err(BlockExecutionError::DistributeBlockRewards(bre)) - } - BlockRewardsResult::Success { - post_state_hash, .. - } => { - state_root_hash = post_state_hash; - } - } - } + // handle payment per the chainspec determined fee setting + // match chainspec.core_config.fee_handling { + // FeeHandling::None => { + // // this is the "fee elimination" model...a BalanceHold for the + // // amount is placed on the paying purse(s). + // let hold_amount = transaction.gas_limit(); + // let hold_purse = get_purse_from_transaction_initiator(); + // let hold_req = HoldRequest::new(hold_purse, hold_amount); + // match scratch_state.hold(hold_req) { + // HoldResult::RootNotFound => {} + // HoldResult::Failure(tce) => {} + // HoldResult::Success{ effects } => {} + // } + // } + // FeeHandling::PayToProposer => { + // // this is the current mainnet mechanism...pay up front + // // finalize at the end + // } + // FeeHandling::Accumulate => { + // // this is a variation on PayToProposer that was added for + // // for some private networks...the fees are all accumulated + // // and distributed to administrative accounts. + // } + // FeeHandling::Burn => { + // // this is a new variation that is not currently supported. + // // this is for future use...but it is very simple...the + // // fees are simply burned, lowering total supply. + // } + // } - for transaction in executable_block.transactions { - let transaction_hash = transaction.hash(); if transaction.is_native_mint() { // native transfers are routed to the data provider let authorization_keys = transaction.authorization_keys(); @@ -163,7 +150,7 @@ pub fn execute_finalized_block( transaction_hash, transaction.initiator_addr().account_hash(), authorization_keys, - transaction.session_args().clone(), + runtime_args, U512::zero(), /* <-- this should be from chainspec cost table */ ); //NOTE: native mint interactions auto-commit @@ -216,15 +203,14 @@ pub fn execute_finalized_block( continue; } if transaction.is_native_auction() { - let args = transaction.session_args(); - let entry_point = transaction.entry_point(); - let auction_method = match AuctionMethod::from_parts(entry_point, args, chainspec) { - Ok(auction_method) => auction_method, - Err(_) => { - error!(%transaction_hash, "failed to resolve auction method"); - continue; // skip to next record - } - }; + let auction_method = + match AuctionMethod::from_parts(entry_point, &runtime_args, chainspec) { + Ok(auction_method) => auction_method, + Err(_) => { + error!(%transaction_hash, "failed to resolve auction method"); + continue; // skip to next record + } + }; let authorization_keys = transaction.authorization_keys(); let bidding_req = BiddingRequest::new( native_runtime_config.clone(), @@ -299,6 +285,62 @@ pub fn execute_finalized_block( state_root_hash = state_hash; } + // Pay out fees, if relevant. + { + let fee_req = FeeRequest::new( + native_runtime_config.clone(), + state_root_hash, + protocol_version, + block_time, + ); + match scratch_state.distribute_fees(fee_req) { + FeeResult::RootNotFound => { + return Err(BlockExecutionError::RootNotFound(state_root_hash)) + } + FeeResult::Failure(fer) => return Err(BlockExecutionError::DistributeFees(fer)), + FeeResult::Success { + //transfers: fee_transfers, + post_state_hash, + .. + } => { + //transfers.extend(fee_transfers); + state_root_hash = post_state_hash; + // TODO: looks like effects & transfer records are associated with the + // ExecutionResult struct which assumes they were caused by a + // deploy. however, systemic operations produce effects and transfer + // records also. + } + } + } + + // Pay out ̶b̶l̶o̶c̶k̶ e͇r͇a͇ rewards + // NOTE: despite the name, these rewards are currently paid out per ERA not per BLOCK + // at one point, they were going to be paid out per block (and might be in the future) + // but it ended up settling on per era. the behavior is driven by Some / None + // thus if in future the calling logic passes rewards per block it should just work as is. + if let Some(rewards) = &executable_block.rewards { + let rewards_req = BlockRewardsRequest::new( + native_runtime_config.clone(), + state_root_hash, + protocol_version, + block_time, + rewards.clone(), + ); + match scratch_state.distribute_block_rewards(rewards_req) { + BlockRewardsResult::RootNotFound => { + return Err(BlockExecutionError::RootNotFound(state_root_hash)) + } + BlockRewardsResult::Failure(bre) => { + return Err(BlockExecutionError::DistributeBlockRewards(bre)) + } + BlockRewardsResult::Success { + post_state_hash, .. + } => { + state_root_hash = post_state_hash; + } + } + } + // handle checksum registry let approvals_hashes = { let mut checksum_registry = ChecksumRegistry::new(); diff --git a/node/src/components/transaction_acceptor.rs b/node/src/components/transaction_acceptor.rs index 38d3ee9409..e7c033c02d 100644 --- a/node/src/components/transaction_acceptor.rs +++ b/node/src/components/transaction_acceptor.rs @@ -4,14 +4,14 @@ mod event; mod metrics; mod tests; -use std::{collections::BTreeSet, fmt::Debug, sync::Arc}; +use std::{collections::BTreeSet, fmt::Debug, sync::Arc, time::SystemTime}; use datasize::DataSize; use prometheus::Registry; use tracing::{debug, error, trace}; use casper_execution_engine::engine_state::MAX_PAYMENT; -use casper_storage::data_access_layer::BalanceRequest; +use casper_storage::data_access_layer::{balance::BalanceHandling, BalanceRequest}; use casper_types::{ account::AccountHash, addressable_entity::AddressableEntity, contracts::ContractHash, package::Package, system::auction::ARG_AMOUNT, AddressableEntityHash, @@ -79,6 +79,7 @@ pub struct TransactionAcceptor { administrators: BTreeSet, #[data_size(skip)] metrics: metrics::Metrics, + balance_hold_interval: u64, } impl TransactionAcceptor { @@ -101,6 +102,7 @@ impl TransactionAcceptor { max_associated_keys: chainspec.core_config.max_associated_keys, administrators, metrics: metrics::Metrics::new(registry)?, + balance_hold_interval: chainspec.core_config.balance_hold_interval.millis(), }) } @@ -241,10 +243,17 @@ impl TransactionAcceptor { return self.reject_transaction(effect_builder, *event_metadata, error); } let protocol_version = block_header.protocol_version(); + let hold_interval = self.balance_hold_interval; + let block_time = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_millis() as u64; + let balance_handling = BalanceHandling::Available { + hold_interval, + block_time, + }; let balance_request = BalanceRequest::from_purse( *block_header.state_root_hash(), protocol_version, entity.main_purse(), + balance_handling, ); effect_builder .get_balance(balance_request) diff --git a/node/src/components/transaction_acceptor/tests.rs b/node/src/components/transaction_acceptor/tests.rs index 7911255c09..343a48b8eb 100644 --- a/node/src/components/transaction_acceptor/tests.rs +++ b/node/src/components/transaction_acceptor/tests.rs @@ -31,7 +31,7 @@ use casper_types::{ Block, BlockV2, CLValue, Chainspec, ChainspecRawBytes, Contract, Deploy, DeployConfigFailure, EraId, HashAddr, Package, PublicKey, SecretKey, StoredValue, TestBlockBuilder, TimeDiff, Timestamp, Transaction, TransactionSessionKind, TransactionV1, TransactionV1Builder, - TransactionV1ConfigFailure, URef, U512, + TransactionV1ConfigFailure, URef, URefAddr, U512, }; use super::*; @@ -772,6 +772,11 @@ impl reactor::Reactor for Reactor { } => { let key = balance_request.identifier().as_key(); + let purse_addr = match balance_request.identifier().as_purse_addr() { + None => URefAddr::default(), + Some(purse_addr) => purse_addr, + }; + let proof = TrieMerkleProof::new( key, StoredValue::CLValue(CLValue::from_t(()).expect("should get CLValue")), @@ -790,8 +795,11 @@ impl reactor::Reactor for Reactor { BalanceResult::RootNotFound } else { BalanceResult::Success { - motes: U512::from(motes), - proof: Box::new(proof), + purse_addr, + total_balance: Default::default(), + available_balance: U512::from(motes), + total_balance_proof: Box::new(proof), + balance_holds: Default::default(), } }; responder.respond(balance_result).ignore() diff --git a/node/src/components/upgrade_watcher.rs b/node/src/components/upgrade_watcher.rs index 5d1cd2d710..2483c56518 100644 --- a/node/src/components/upgrade_watcher.rs +++ b/node/src/components/upgrade_watcher.rs @@ -316,7 +316,7 @@ impl UpgradePoint { fn from_chainspec_path>(path: P) -> Result { let bytes = file_utils::read_file(path.as_ref().join(CHAINSPEC_FILENAME)) .map_err(Error::LoadUpgradePoint)?; - Ok(toml::from_slice(&bytes)?) + Ok(toml::from_str(std::str::from_utf8(&bytes).unwrap())?) } } @@ -523,11 +523,9 @@ mod tests { fs::create_dir(&subdir).unwrap(); let path = subdir.join(CHAINSPEC_FILENAME); - fs::write( - path, - toml::to_string_pretty(&chainspec).expect("should encode to toml"), - ) - .expect("should install chainspec"); + + let pretty = toml::to_string_pretty(&chainspec); + fs::write(path, pretty.expect("should encode to toml")).expect("should install chainspec"); chainspec } @@ -541,20 +539,20 @@ mod tests { let mut rng = crate::new_rng(); - let mut current = ProtocolVersion::from_parts(0, 9, 9); - let v1_0_0 = ProtocolVersion::from_parts(1, 0, 0); - let chainspec_v1_0_0 = install_chainspec(&mut rng, tempdir.path(), &v1_0_0); + let mut current = ProtocolVersion::from_parts(1, 9, 9); + let v2_0_0 = ProtocolVersion::from_parts(2, 0, 0); + let chainspec_v2_0_0 = install_chainspec(&mut rng, tempdir.path(), &v2_0_0); assert_eq!( next_point(¤t), - chainspec_v1_0_0.protocol_config.into() + chainspec_v2_0_0.protocol_config.into() ); - current = v1_0_0; - let v1_0_3 = ProtocolVersion::from_parts(1, 0, 3); - let chainspec_v1_0_3 = install_chainspec(&mut rng, tempdir.path(), &v1_0_3); + current = v2_0_0; + let v2_0_3 = ProtocolVersion::from_parts(2, 0, 3); + let chainspec_v2_0_3 = install_chainspec(&mut rng, tempdir.path(), &v2_0_3); assert_eq!( next_point(¤t), - chainspec_v1_0_3.protocol_config.into() + chainspec_v2_0_3.protocol_config.into() ); } diff --git a/node/src/utils/chain_specification/parse_toml.rs b/node/src/utils/chain_specification/parse_toml.rs index 74b96979e6..e626329358 100644 --- a/node/src/utils/chain_specification/parse_toml.rs +++ b/node/src/utils/chain_specification/parse_toml.rs @@ -115,7 +115,8 @@ pub(super) fn parse_toml>( ) -> Result<(Chainspec, ChainspecRawBytes), Error> { let chainspec_bytes = file_utils::read_file(chainspec_path.as_ref()).map_err(Error::LoadChainspec)?; - let toml_chainspec: TomlChainspec = toml::from_slice(&chainspec_bytes)?; + let toml_chainspec: TomlChainspec = + toml::from_str(std::str::from_utf8(&chainspec_bytes).unwrap())?; let root = chainspec_path .as_ref() @@ -189,7 +190,7 @@ pub(super) fn parse_toml_accounts>( return Ok((config, maybe_bytes)); } let bytes = file_utils::read_file(accounts_path)?; - let config: AccountsConfig = toml::from_slice(&bytes)?; + let config: AccountsConfig = toml::from_str(std::str::from_utf8(&bytes).unwrap())?; Ok((config, Some(Bytes::from(bytes)))) } @@ -201,6 +202,6 @@ pub(super) fn parse_toml_global_state>( return Ok(None); } let bytes = file_utils::read_file(update_path)?; - let config: GlobalStateUpdateConfig = toml::from_slice(&bytes)?; + let config = toml::from_str(std::str::from_utf8(&bytes).unwrap())?; Ok(Some((config, Bytes::from(bytes)))) } diff --git a/resources/local/chainspec.toml.in b/resources/local/chainspec.toml.in index 04877f156e..3ae617227f 100644 --- a/resources/local/chainspec.toml.in +++ b/resources/local/chainspec.toml.in @@ -101,6 +101,8 @@ refund_handling = { type = 'refund', refund_ratio = [99, 100] } # administrator accounts # 'burn': fees are burned fee_handling = { type = 'pay_to_proposer' } +# How long does it take for a balance hold to fade away? +balance_hold_interval = '24 hours' # List of public keys of administrator accounts. Setting this option makes only on private chains which require # administrator accounts for regulatory reasons. administrators = [] diff --git a/resources/production/chainspec.toml b/resources/production/chainspec.toml index 24aaf4119f..7385a05d22 100644 --- a/resources/production/chainspec.toml +++ b/resources/production/chainspec.toml @@ -112,6 +112,8 @@ refund_handling = { type = 'refund', refund_ratio = [99, 100] } # administrator accounts # 'burn': fees are burned fee_handling = { type = 'pay_to_proposer' } +# How long does it take for a balance hold to fade away? +balance_hold_interval = '24 hours' # List of public keys of administrator accounts. Setting this option makes only on private chains which require # administrator accounts for regulatory reasons. administrators = [] diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index 788c1007af..5f99d2d959 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -4680,14 +4680,14 @@ "description": "Message that was emitted by an addressable entity during execution.", "type": "object", "required": [ - "entity_addr", + "entity_hash", "index", "message", "topic_name", "topic_name_hash" ], "properties": { - "entity_addr": { + "entity_hash": { "description": "The identity of the entity that produced the message.", "allOf": [ { diff --git a/storage/src/data_access_layer.rs b/storage/src/data_access_layer.rs index db824919e6..33e11d08f4 100644 --- a/storage/src/data_access_layer.rs +++ b/storage/src/data_access_layer.rs @@ -8,6 +8,7 @@ use crate::tracking_copy::TrackingCopy; mod addressable_entity; pub mod balance; +mod balance_hold; pub mod bidding; pub mod bids; pub mod block_rewards; @@ -29,6 +30,9 @@ mod trie; pub use addressable_entity::{AddressableEntityRequest, AddressableEntityResult}; pub use balance::{BalanceIdentifier, BalanceRequest, BalanceResult}; +pub use balance_hold::{ + BalanceHoldError, BalanceHoldRequest, BalanceHoldResult, InsufficientBalanceHandling, +}; pub use bidding::{BiddingRequest, BiddingResult}; pub use bids::{BidsRequest, BidsResult}; pub use block_rewards::{BlockRewardsError, BlockRewardsRequest, BlockRewardsResult}; diff --git a/storage/src/data_access_layer/balance.rs b/storage/src/data_access_layer/balance.rs index 54065b01db..21decbdd23 100644 --- a/storage/src/data_access_layer/balance.rs +++ b/storage/src/data_access_layer/balance.rs @@ -1,10 +1,27 @@ //! Types for balance queries. +use crate::data_access_layer::BalanceHoldRequest; use casper_types::{ - account::AccountHash, global_state::TrieMerkleProof, Digest, EntityAddr, Key, ProtocolVersion, - PublicKey, StoredValue, URef, URefAddr, U512, + account::AccountHash, global_state::TrieMerkleProof, system::mint::BalanceHoldAddrTag, + AccessRights, BlockTime, Digest, EntityAddr, Key, ProtocolVersion, PublicKey, StoredValue, + URef, URefAddr, U512, }; +use std::collections::BTreeMap; -use crate::tracking_copy::TrackingCopyError; +use crate::{ + global_state::state::StateReader, + tracking_copy::{TrackingCopyEntityExt, TrackingCopyError}, + TrackingCopy, +}; + +/// How to handle available balance inquiry? +#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] +pub enum BalanceHandling { + /// Ignore balance holds. + #[default] + Total, + /// Adjust for balance holds (if any). + Available { block_time: u64, hold_interval: u64 }, +} /// Represents a way to make a balance inquiry. #[derive(Debug, Clone, PartialEq, Eq)] @@ -17,6 +34,7 @@ pub enum BalanceIdentifier { } impl BalanceIdentifier { + /// Self as key. pub fn as_key(&self) -> Key { match self { BalanceIdentifier::Purse(uref) => Key::URef(*uref), @@ -26,6 +44,58 @@ impl BalanceIdentifier { BalanceIdentifier::Internal(addr) => Key::Balance(*addr), } } + + // #[cfg(test)] + pub fn as_purse_addr(&self) -> Option { + match self { + BalanceIdentifier::Purse(uref) => Some(uref.addr()), + BalanceIdentifier::Internal(addr) => Some(*addr), + BalanceIdentifier::Public(_) + | BalanceIdentifier::Account(_) + | BalanceIdentifier::Entity(_) => None, + } + } + + /// Return purse_uref, if able. + pub fn purse_uref( + &self, + tc: &mut TrackingCopy, + protocol_version: ProtocolVersion, + ) -> Result + where + S: StateReader, + { + let purse_uref = match self { + BalanceIdentifier::Purse(purse_uref) => *purse_uref, + BalanceIdentifier::Public(public_key) => { + let account_hash = public_key.to_account_hash(); + match tc.get_addressable_entity_by_account_hash(protocol_version, account_hash) { + Ok(entity) => entity.main_purse(), + Err(tce) => return Err(tce), + } + } + BalanceIdentifier::Account(account_hash) => { + match tc.get_addressable_entity_by_account_hash(protocol_version, *account_hash) { + Ok(entity) => entity.main_purse(), + Err(tce) => return Err(tce), + } + } + BalanceIdentifier::Entity(entity_addr) => { + match tc.get_addressable_entity(*entity_addr) { + Ok(entity) => entity.main_purse(), + Err(tce) => return Err(tce), + } + } + BalanceIdentifier::Internal(addr) => URef::new(*addr, AccessRights::READ), + }; + Ok(purse_uref) + } +} + +impl Default for BalanceIdentifier { + fn default() -> Self { + BalanceIdentifier::Purse(URef::default()) + } } /// Represents a balance request. @@ -34,6 +104,7 @@ pub struct BalanceRequest { state_hash: Digest, protocol_version: ProtocolVersion, identifier: BalanceIdentifier, + balance_handling: BalanceHandling, } impl BalanceRequest { @@ -42,11 +113,13 @@ impl BalanceRequest { state_hash: Digest, protocol_version: ProtocolVersion, identifier: BalanceIdentifier, + balance_handling: BalanceHandling, ) -> Self { BalanceRequest { state_hash, protocol_version, identifier, + balance_handling, } } @@ -55,11 +128,13 @@ impl BalanceRequest { state_hash: Digest, protocol_version: ProtocolVersion, purse_uref: URef, + balance_handling: BalanceHandling, ) -> Self { BalanceRequest { state_hash, protocol_version, identifier: BalanceIdentifier::Purse(purse_uref), + balance_handling, } } @@ -68,11 +143,13 @@ impl BalanceRequest { state_hash: Digest, protocol_version: ProtocolVersion, public_key: PublicKey, + balance_handling: BalanceHandling, ) -> Self { BalanceRequest { state_hash, protocol_version, identifier: BalanceIdentifier::Public(public_key), + balance_handling, } } @@ -81,11 +158,13 @@ impl BalanceRequest { state_hash: Digest, protocol_version: ProtocolVersion, account_hash: AccountHash, + balance_handling: BalanceHandling, ) -> Self { BalanceRequest { state_hash, protocol_version, identifier: BalanceIdentifier::Account(account_hash), + balance_handling, } } @@ -94,11 +173,13 @@ impl BalanceRequest { state_hash: Digest, protocol_version: ProtocolVersion, entity_addr: EntityAddr, + balance_handling: BalanceHandling, ) -> Self { BalanceRequest { state_hash, protocol_version, identifier: BalanceIdentifier::Entity(entity_addr), + balance_handling, } } @@ -107,11 +188,13 @@ impl BalanceRequest { state_hash: Digest, protocol_version: ProtocolVersion, balance_addr: URefAddr, + balance_handling: BalanceHandling, ) -> Self { BalanceRequest { state_hash, protocol_version, identifier: BalanceIdentifier::Internal(balance_addr), + balance_handling, } } @@ -129,8 +212,32 @@ impl BalanceRequest { pub fn identifier(&self) -> &BalanceIdentifier { &self.identifier } + + /// Returns the block time. + pub fn balance_handling(&self) -> BalanceHandling { + self.balance_handling + } } +impl From for BalanceRequest { + fn from(value: BalanceHoldRequest) -> Self { + let balance_handling = BalanceHandling::Available { + block_time: value.block_time().value(), + hold_interval: value.hold_interval().millis(), + }; + BalanceRequest::new( + value.state_hash(), + value.protocol_version(), + value.identifier().clone(), + balance_handling, + ) + } +} + +/// Balance holds with Merkle proofs. +pub type BalanceHoldsWithProof = + BTreeMap)>; + /// Result enum that represents all possible outcomes of a balance request. #[derive(Debug)] pub enum BalanceResult { @@ -138,10 +245,16 @@ pub enum BalanceResult { RootNotFound, /// A query returned a balance. Success { - /// Purse balance. - motes: U512, + /// The purse address. + purse_addr: URefAddr, + /// The purses total balance, not considering holds. + total_balance: U512, + /// The available balance (total balance - sum of all active holds). + available_balance: U512, /// A proof that the given value is present in the Merkle trie. - proof: Box>, + total_balance_proof: Box>, + /// Any time-relevant active holds on the balance. + balance_holds: BTreeMap, }, Failure(TrackingCopyError), } @@ -150,7 +263,10 @@ impl BalanceResult { /// Returns the amount of motes for a [`BalanceResult::Success`] variant. pub fn motes(&self) -> Option<&U512> { match self { - BalanceResult::Success { motes, .. } => Some(motes), + BalanceResult::Success { + available_balance: motes, + .. + } => Some(motes), _ => None, } } @@ -158,7 +274,10 @@ impl BalanceResult { /// Returns the Merkle proof for a given [`BalanceResult::Success`] variant. pub fn proof(self) -> Option> { match self { - BalanceResult::Success { proof, .. } => Some(*proof), + BalanceResult::Success { + total_balance_proof: proof, + .. + } => Some(*proof), _ => None, } } diff --git a/storage/src/data_access_layer/balance_hold.rs b/storage/src/data_access_layer/balance_hold.rs new file mode 100644 index 0000000000..387f0f1d9f --- /dev/null +++ b/storage/src/data_access_layer/balance_hold.rs @@ -0,0 +1,253 @@ +use crate::{data_access_layer::BalanceIdentifier, tracking_copy::TrackingCopyError}; +use casper_types::{ + account::AccountHash, system::mint::BalanceHoldAddrTag, BlockTime, Digest, EntityAddr, + ProtocolVersion, PublicKey, TimeDiff, URef, URefAddr, U512, +}; +use std::fmt::{Display, Formatter}; +use thiserror::Error; + +/// How to handle available balance is less than hold amount? +#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] +pub enum InsufficientBalanceHandling { + /// Hold however much balance remains. + #[default] + HoldRemaining, + /// No operation. Aka, do not place a hold. + Noop, +} + +#[derive(Debug, Clone, PartialEq, Eq, Default)] +pub struct BalanceHoldRequest { + state_hash: Digest, + protocol_version: ProtocolVersion, + identifier: BalanceIdentifier, + hold_kind: BalanceHoldAddrTag, + hold_amount: U512, + block_time: BlockTime, + hold_interval: TimeDiff, + insufficient_handling: InsufficientBalanceHandling, +} + +impl BalanceHoldRequest { + /// Creates a new [`BalanceHoldRequest`]. + #[allow(clippy::too_many_arguments)] + pub fn new( + state_hash: Digest, + protocol_version: ProtocolVersion, + identifier: BalanceIdentifier, + hold_kind: BalanceHoldAddrTag, + hold_amount: U512, + block_time: BlockTime, + hold_interval: TimeDiff, + insufficient_handling: InsufficientBalanceHandling, + ) -> Self { + BalanceHoldRequest { + state_hash, + protocol_version, + identifier, + hold_kind, + hold_amount, + block_time, + hold_interval, + insufficient_handling, + } + } + + /// Creates a new [`BalanceHoldRequest`]. + #[allow(clippy::too_many_arguments)] + pub fn from_purse( + state_hash: Digest, + protocol_version: ProtocolVersion, + purse_uref: URef, + hold_kind: BalanceHoldAddrTag, + hold_amount: U512, + block_time: BlockTime, + hold_interval: TimeDiff, + insufficient_handling: InsufficientBalanceHandling, + ) -> Self { + BalanceHoldRequest { + state_hash, + protocol_version, + identifier: BalanceIdentifier::Purse(purse_uref), + hold_kind, + hold_amount, + block_time, + hold_interval, + insufficient_handling, + } + } + + /// Creates a new [`BalanceHoldRequest`]. + #[allow(clippy::too_many_arguments)] + pub fn from_public_key( + state_hash: Digest, + protocol_version: ProtocolVersion, + public_key: PublicKey, + hold_kind: BalanceHoldAddrTag, + hold_amount: U512, + block_time: BlockTime, + hold_interval: TimeDiff, + insufficient_handling: InsufficientBalanceHandling, + ) -> Self { + BalanceHoldRequest { + state_hash, + protocol_version, + identifier: BalanceIdentifier::Public(public_key), + hold_kind, + hold_amount, + block_time, + hold_interval, + insufficient_handling, + } + } + + /// Creates a new [`BalanceHoldRequest`]. + #[allow(clippy::too_many_arguments)] + pub fn from_account_hash( + state_hash: Digest, + protocol_version: ProtocolVersion, + account_hash: AccountHash, + hold_kind: BalanceHoldAddrTag, + hold_amount: U512, + block_time: BlockTime, + hold_interval: TimeDiff, + insufficient_handling: InsufficientBalanceHandling, + ) -> Self { + BalanceHoldRequest { + state_hash, + protocol_version, + identifier: BalanceIdentifier::Account(account_hash), + hold_kind, + hold_amount, + block_time, + hold_interval, + insufficient_handling, + } + } + + /// Creates a new [`BalanceHoldRequest`]. + #[allow(clippy::too_many_arguments)] + pub fn from_entity_addr( + state_hash: Digest, + protocol_version: ProtocolVersion, + entity_addr: EntityAddr, + hold_kind: BalanceHoldAddrTag, + hold_amount: U512, + block_time: BlockTime, + hold_interval: TimeDiff, + insufficient_handling: InsufficientBalanceHandling, + ) -> Self { + BalanceHoldRequest { + state_hash, + protocol_version, + identifier: BalanceIdentifier::Entity(entity_addr), + hold_kind, + hold_amount, + block_time, + hold_interval, + insufficient_handling, + } + } + + /// Creates a new [`BalanceHoldRequest`]. + #[allow(clippy::too_many_arguments)] + pub fn from_internal( + state_hash: Digest, + protocol_version: ProtocolVersion, + balance_addr: URefAddr, + hold_kind: BalanceHoldAddrTag, + hold_amount: U512, + block_time: BlockTime, + hold_interval: TimeDiff, + insufficient_handling: InsufficientBalanceHandling, + ) -> Self { + BalanceHoldRequest { + state_hash, + protocol_version, + identifier: BalanceIdentifier::Internal(balance_addr), + hold_kind, + hold_amount, + block_time, + hold_interval, + insufficient_handling, + } + } + + /// Returns a state hash. + pub fn state_hash(&self) -> Digest { + self.state_hash + } + + /// Protocol version. + pub fn protocol_version(&self) -> ProtocolVersion { + self.protocol_version + } + + /// Returns the identifier [`BalanceIdentifier`]. + pub fn identifier(&self) -> &BalanceIdentifier { + &self.identifier + } + + /// Returns the hold kind. + pub fn hold_kind(&self) -> BalanceHoldAddrTag { + self.hold_kind + } + + /// Returns the hold amount. + pub fn hold_amount(&self) -> U512 { + self.hold_amount + } + + /// Returns the block time. + pub fn block_time(&self) -> BlockTime { + self.block_time + } + + /// Returns the hold interval. + pub fn hold_interval(&self) -> TimeDiff { + self.hold_interval + } + + /// Returns insufficient balance handling option. + pub fn insufficient_handling(&self) -> InsufficientBalanceHandling { + self.insufficient_handling + } +} + +/// Possible balance hold errors. +#[derive(Error, Debug, Clone)] +#[non_exhaustive] +pub enum BalanceHoldError { + TrackingCopy(TrackingCopyError), + InsufficientBalance { remaining_balance: U512 }, +} + +impl Display for BalanceHoldError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + BalanceHoldError::TrackingCopy(err) => { + write!(f, "TrackingCopy: {}", err) + } + BalanceHoldError::InsufficientBalance { remaining_balance } => { + write!(f, "InsufficientBalance: {}", remaining_balance) + } + } + } +} + +/// Result enum that represents all possible outcomes of a balance hold request. +pub enum BalanceHoldResult { + /// Returned if a passed state root hash is not found. + RootNotFound, + /// Balance hold successfully placed. + Success { + /// Purse total balance. + total_balance: U512, + /// Purse available balance after hold placed. + available_balance: U512, + /// Were we able to hold the full amount? + full_amount_held: bool, + }, + /// Failed to place balance hold. + Failure(BalanceHoldError), +} diff --git a/storage/src/data_access_layer/bidding.rs b/storage/src/data_access_layer/bidding.rs index e46dcae41f..499fb67978 100644 --- a/storage/src/data_access_layer/bidding.rs +++ b/storage/src/data_access_layer/bidding.rs @@ -5,7 +5,7 @@ use casper_types::{ account::AccountHash, bytesrepr::FromBytes, execution::Effects, - system::{auction, auction::DelegationRate}, + system::{auction, auction::DelegationRate, mint}, CLTyped, CLValue, Chainspec, Digest, ProtocolVersion, PublicKey, RuntimeArgs, TransactionEntryPoint, TransactionHash, U512, }; @@ -21,6 +21,7 @@ pub enum AuctionMethod { public_key: PublicKey, delegation_rate: DelegationRate, amount: U512, + holds_epoch: Option, }, WithdrawBid { public_key: PublicKey, @@ -32,6 +33,7 @@ pub enum AuctionMethod { amount: U512, max_delegators_per_validator: u32, minimum_delegation_amount: u64, + holds_epoch: Option, }, Undelegate { delegator_public_key: PublicKey, @@ -97,10 +99,12 @@ impl AuctionMethod { let public_key = Self::get_named_argument(runtime_args, auction::ARG_PUBLIC_KEY)?; let delegation_rate = Self::get_named_argument(runtime_args, auction::ARG_DELEGATION_RATE)?; let amount = Self::get_named_argument(runtime_args, auction::ARG_AMOUNT)?; + let holds_epoch = Self::get_named_argument(runtime_args, mint::ARG_HOLDS_EPOCH)?; Ok(Self::AddBid { public_key, delegation_rate, amount, + holds_epoch, }) } @@ -123,6 +127,7 @@ impl AuctionMethod { let max_delegators_per_validator = chainspec.core_config.max_delegators_per_validator; let minimum_delegation_amount = chainspec.core_config.minimum_delegation_amount; + let holds_epoch = Self::get_named_argument(runtime_args, mint::ARG_HOLDS_EPOCH)?; Ok(Self::Delegate { delegator_public_key, @@ -130,6 +135,7 @@ impl AuctionMethod { amount, max_delegators_per_validator, minimum_delegation_amount, + holds_epoch, }) } diff --git a/storage/src/global_state/state/mod.rs b/storage/src/global_state/state/mod.rs index 64b079a06d..7d47af9a23 100644 --- a/storage/src/global_state/state/mod.rs +++ b/storage/src/global_state/state/mod.rs @@ -6,9 +6,10 @@ pub mod lmdb; /// Lmdb implementation of global state with cache. pub mod scratch; +use itertools::Itertools; use std::{ cell::RefCell, - collections::{BTreeSet, HashMap}, + collections::{BTreeMap, BTreeSet, HashMap}, convert::TryFrom, rc::Rc, }; @@ -27,30 +28,34 @@ use casper_types::{ system::{ auction::SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY, handle_payment::ACCUMULATION_PURSE_KEY, - mint::{ARG_AMOUNT, ROUND_SEIGNIORAGE_RATE_KEY, TOTAL_SUPPLY_KEY}, + mint::{ + BalanceHoldAddr, BalanceHoldAddrTag, ARG_AMOUNT, ROUND_SEIGNIORAGE_RATE_KEY, + TOTAL_SUPPLY_KEY, + }, AUCTION, HANDLE_PAYMENT, MINT, }, - AccessRights, Account, AddressableEntity, DeployHash, Digest, EntityAddr, Key, KeyTag, Phase, + Account, AddressableEntity, CLValue, DeployHash, Digest, EntityAddr, Key, KeyTag, Phase, PublicKey, RuntimeArgs, StoredValue, TransactionHash, TransactionV1Hash, U512, }; use crate::{ data_access_layer::{ + balance::BalanceHandling, bidding::{AuctionMethodRet, BiddingRequest, BiddingResult}, era_validators::EraValidatorsResult, tagged_values::{TaggedValuesRequest, TaggedValuesResult}, transfer::{TransferRequest, TransferRequestArgs, TransferResult}, - AddressableEntityRequest, AddressableEntityResult, AuctionMethod, BalanceIdentifier, - BalanceRequest, BalanceResult, BidsRequest, BidsResult, BlockRewardsError, - BlockRewardsRequest, BlockRewardsResult, EraValidatorsRequest, - ExecutionResultsChecksumRequest, ExecutionResultsChecksumResult, FeeError, FeeRequest, - FeeResult, FlushRequest, FlushResult, GenesisRequest, GenesisResult, - ProtocolUpgradeRequest, ProtocolUpgradeResult, PruneRequest, PruneResult, PutTrieRequest, - PutTrieResult, QueryRequest, QueryResult, RoundSeigniorageRateRequest, - RoundSeigniorageRateResult, StepError, StepRequest, StepResult, - SystemEntityRegistryPayload, SystemEntityRegistryRequest, SystemEntityRegistryResult, - SystemEntityRegistrySelector, TotalSupplyRequest, TotalSupplyResult, TrieRequest, - TrieResult, EXECUTION_RESULTS_CHECKSUM_NAME, + AddressableEntityRequest, AddressableEntityResult, AuctionMethod, BalanceHoldError, + BalanceHoldRequest, BalanceHoldResult, BalanceRequest, BalanceResult, BidsRequest, + BidsResult, BlockRewardsError, BlockRewardsRequest, BlockRewardsResult, + EraValidatorsRequest, ExecutionResultsChecksumRequest, ExecutionResultsChecksumResult, + FeeError, FeeRequest, FeeResult, FlushRequest, FlushResult, GenesisRequest, GenesisResult, + InsufficientBalanceHandling, ProtocolUpgradeRequest, ProtocolUpgradeResult, PruneRequest, + PruneResult, PutTrieRequest, PutTrieResult, QueryRequest, QueryResult, + RoundSeigniorageRateRequest, RoundSeigniorageRateResult, StepError, StepRequest, + StepResult, SystemEntityRegistryPayload, SystemEntityRegistryRequest, + SystemEntityRegistryResult, SystemEntityRegistrySelector, TotalSupplyRequest, + TotalSupplyResult, TrieRequest, TrieResult, EXECUTION_RESULTS_CHECKSUM_NAME, }, global_state::{ error::Error as GlobalStateError, @@ -476,8 +481,12 @@ pub trait CommitProvider: StateProvider { let protocol_version = request.protocol_version(); let accumulated_balance = { - let balance_req = - BalanceRequest::from_purse(state_hash, protocol_version, accumulation_purse); + let balance_req = BalanceRequest::from_purse( + state_hash, + protocol_version, + accumulation_purse, + BalanceHandling::Total, + ); let balance_result = self.balance(balance_req); match balance_result { BalanceResult::RootNotFound => { @@ -486,7 +495,10 @@ pub trait CommitProvider: StateProvider { BalanceResult::Failure(tce) => { return FeeResult::Failure(FeeError::TrackingCopy(tce)); } - BalanceResult::Success { motes, .. } => motes, + BalanceResult::Success { + available_balance: motes, + .. + } => motes, } }; @@ -548,6 +560,9 @@ pub trait CommitProvider: StateProvider { )) } }; + + let holds_epoch = block_time.saturating_sub(request.config().balance_hold_interval()); + for target in administrative_accounts { let target_purse = match tc .borrow_mut() @@ -562,6 +577,7 @@ pub trait CommitProvider: StateProvider { target_purse, fee_portion, None, + Some(holds_epoch), ); let transfer_req = TransferRequest::new( @@ -607,7 +623,7 @@ pub trait CommitProvider: StateProvider { FeeResult::Failure(FeeError::NoFeesDistributed) } - /// Direct biddings. + /// Direct auction interaction for all variations of bid management. fn bidding(&self, request: BiddingRequest) -> BiddingResult { let state_hash = request.state_hash(); let tc = match self.tracking_copy(state_hash) { @@ -637,7 +653,7 @@ pub trait CommitProvider: StateProvider { } }; - // IMPORTANT: this runtime _must_ use the initiators's context. + // IMPORTANT: this runtime _must_ use the initiator's context. let mut runtime = RuntimeNative::new( protocol_version, config.clone(), @@ -666,8 +682,9 @@ pub trait CommitProvider: StateProvider { public_key, delegation_rate, amount, + holds_epoch, } => runtime - .add_bid(public_key, delegation_rate, amount) + .add_bid(public_key, delegation_rate, amount, holds_epoch) .map(AuctionMethodRet::UpdatedAmount) .map_err(TrackingCopyError::Api), AuctionMethod::WithdrawBid { public_key, amount } => runtime @@ -682,6 +699,7 @@ pub trait CommitProvider: StateProvider { amount, max_delegators_per_validator, minimum_delegation_amount, + holds_epoch, } => runtime .delegate( delegator_public_key, @@ -689,6 +707,7 @@ pub trait CommitProvider: StateProvider { amount, max_delegators_per_validator, minimum_delegation_amount, + holds_epoch, ) .map(AuctionMethodRet::UpdatedAmount) .map_err(TrackingCopyError::Api), @@ -779,43 +798,139 @@ pub trait StateProvider { Err(err) => return BalanceResult::Failure(TrackingCopyError::Storage(err)), }; let protocol_version = request.protocol_version(); - let purse_uref = match request.identifier() { - BalanceIdentifier::Purse(purse_uref) => *purse_uref, - BalanceIdentifier::Public(public_key) => { - let account_hash = public_key.to_account_hash(); - match tc.get_addressable_entity_by_account_hash(protocol_version, account_hash) { - Ok(entity) => entity.main_purse(), - Err(tce) => return BalanceResult::Failure(tce), - } + let balance_identifier = request.identifier(); + let purse_uref = match balance_identifier.purse_uref(&mut tc, protocol_version) { + Ok(value) => value, + Err(tce) => return BalanceResult::Failure(tce), + }; + let purse_key = purse_uref.into(); + let (purse_balance_key, purse_addr) = match tc.get_purse_balance_key(purse_key) { + Ok(key @ Key::Balance(addr)) => (key, addr), + Ok(key) => return BalanceResult::Failure(TrackingCopyError::UnexpectedKeyVariant(key)), + Err(tce) => return BalanceResult::Failure(tce), + }; + + let (total_balance, total_balance_proof) = + match tc.get_total_balance_with_proof(purse_balance_key) { + Err(tce) => return BalanceResult::Failure(tce), + Ok((balance, proof)) => (balance, Box::new(proof)), + }; + + let balance_holds = match request.balance_handling() { + BalanceHandling::Total => BTreeMap::new(), + BalanceHandling::Available { + block_time, + hold_interval, + } => match tc.get_balance_holds_with_proof(purse_addr, block_time, hold_interval) { + Err(tce) => return BalanceResult::Failure(tce), + Ok(holds) => holds, + }, + }; + + let available_balance = if balance_holds.is_empty() { + total_balance + } else { + let held = balance_holds + .values() + .flat_map(|holds| holds.values().map(|(v, _)| *v)) + .collect_vec() + .into_iter() + .sum(); + + debug_assert!( + total_balance >= held, + "it should not be possible to hold more than the total available" + ); + if held > total_balance { + error!(%held, %total_balance, "holds somehow exceed total balance, which should never occur."); } - BalanceIdentifier::Account(account_hash) => { - match tc.get_addressable_entity_by_account_hash(protocol_version, *account_hash) { - Ok(entity) => entity.main_purse(), - Err(tce) => return BalanceResult::Failure(tce), - } + total_balance.checked_sub(held).unwrap_or(U512::zero()) + }; + + BalanceResult::Success { + purse_addr, + total_balance, + total_balance_proof, + available_balance, + balance_holds, + } + } + + /// Balance hold. + fn balance_hold(&self, request: BalanceHoldRequest) -> BalanceHoldResult { + let mut tc = match self.tracking_copy(request.state_hash()) { + Ok(Some(tracking_copy)) => tracking_copy, + Ok(None) => return BalanceHoldResult::RootNotFound, + Err(err) => { + return BalanceHoldResult::Failure(BalanceHoldError::TrackingCopy( + TrackingCopyError::Storage(err), + )) } - BalanceIdentifier::Entity(entity_addr) => { - match tc.get_addressable_entity(*entity_addr) { - Ok(entity) => entity.main_purse(), - Err(tce) => return BalanceResult::Failure(tce), - } + }; + let balance_request = request.clone().into(); + let balance_result = self.balance(balance_request); + let (total_balance, remaining_balance, purse_addr) = match balance_result { + BalanceResult::RootNotFound => return BalanceHoldResult::RootNotFound, + BalanceResult::Failure(tce) => { + return BalanceHoldResult::Failure(BalanceHoldError::TrackingCopy(tce)) } - BalanceIdentifier::Internal(addr) => casper_types::URef::new(*addr, AccessRights::READ), + BalanceResult::Success { + total_balance, + available_balance, + purse_addr, + .. + } => (total_balance, available_balance, purse_addr), }; - let purse_key = purse_uref.into(); - // read the new hold records if any exist - // check their timestamps..if stale tc.prune(that item) - // total bal - sum(hold balance) == avail - match tc.get_purse_balance_key(purse_key) { - Ok(purse_balance_key) => match tc.get_purse_balance_with_proof(purse_balance_key) { - Ok((balance, proof)) => { - let proof = Box::new(proof); - let motes = balance.value(); - BalanceResult::Success { motes, proof } - } - Err(err) => BalanceResult::Failure(err), + + let (hold_amount, covered) = { + if remaining_balance >= request.hold_amount() { + // the purse has sufficient balance to fully cover the hold + (request.hold_amount(), true) + } else if request.insufficient_handling() == InsufficientBalanceHandling::Noop { + // the purse has insufficient balance but the holding mode is noop, so get out + return BalanceHoldResult::Failure(BalanceHoldError::InsufficientBalance { + remaining_balance, + }); + } else { + // currently this is always the default HoldRemaining variant. + // the purse holder has insufficient balance to cover the hold, + // but the system will put a hold on whatever balance remains. + // this is basically punitive to block an edge case resource consumption + // attack whereby a malicious purse holder drains a balance to not-zero + // but not-enough-to-cover-holds and then spams a bunch of transactions + // knowing that they will fail due to insufficient funds, but only + // after making the system do the work of processing the balance + // check without penalty to themselves. + (remaining_balance, false) + } + }; + + let cl_value = match CLValue::from_t(hold_amount) { + Ok(cl_value) => cl_value, + Err(cve) => { + return BalanceHoldResult::Failure(BalanceHoldError::TrackingCopy( + TrackingCopyError::CLValue(cve), + )) + } + }; + + let balance_hold_addr = match request.hold_kind() { + BalanceHoldAddrTag::Gas => BalanceHoldAddr::Gas { + purse_addr, + block_time: request.block_time(), }, - Err(err) => BalanceResult::Failure(err), + }; + + tc.write( + Key::BalanceHold(balance_hold_addr), + StoredValue::CLValue(cl_value), + ); + let available_balance = remaining_balance.saturating_sub(hold_amount); + + BalanceHoldResult::Success { + total_balance, + available_balance, + full_amount_held: covered, } } @@ -1344,6 +1459,7 @@ pub trait StateProvider { transfer_args.target(), transfer_args.amount(), transfer_args.arg_id(), + transfer_args.holds_epoch(), ) { return TransferResult::Failure(TransferError::Mint(mint_error)); } diff --git a/storage/src/system/auction.rs b/storage/src/system/auction.rs index 61b2b8e44f..5a37a70406 100644 --- a/storage/src/system/auction.rs +++ b/storage/src/system/auction.rs @@ -69,6 +69,7 @@ pub trait Auction: public_key: PublicKey, delegation_rate: DelegationRate, amount: U512, + holds_epoch: Option, ) -> Result { if !self.allow_auction_bids() { // Validation set rotation might be disabled on some private chains and we should not @@ -111,6 +112,7 @@ pub trait Auction: target, amount, None, + holds_epoch, ) .map_err(|_| Error::TransferToBidPurse)? .map_err(|mint_error| { @@ -208,6 +210,7 @@ pub trait Auction: amount: U512, max_delegators_per_validator: u32, minimum_delegation_amount: u64, + holds_epoch: Option, ) -> Result { if !self.allow_auction_bids() { // Validation set rotation might be disabled on some private chains and we should not @@ -229,6 +232,7 @@ pub trait Auction: amount, max_delegators_per_validator, minimum_delegation_amount, + holds_epoch, ) } diff --git a/storage/src/system/auction/auction_native.rs b/storage/src/system/auction/auction_native.rs index 4c5a0699df..bd96b363ef 100644 --- a/storage/src/system/auction/auction_native.rs +++ b/storage/src/system/auction/auction_native.rs @@ -256,6 +256,7 @@ where contract.main_purse(), *unbonding_purse.amount(), None, + None, // unbonding purses do not have holds on them ) .map_err(|_| Error::Transfer)? .map_err(|_| Error::Transfer)?; @@ -273,6 +274,7 @@ where target: URef, amount: U512, id: Option, + holds_epoch: Option, ) -> Result, Error> { if !(self.addressable_entity().main_purse().addr() == source.addr() || self.get_caller() == PublicKey::System.to_account_hash()) @@ -283,7 +285,7 @@ where // let gas_counter = self.gas_counter(); self.extend_access_rights(&[source, target.into_add()]); - match self.transfer(to, source, target, amount, id) { + match self.transfer(to, source, target, amount, id, holds_epoch) { Ok(ret) => { // self.set_gas_counter(gas_counter); Ok(Ok(ret)) @@ -328,8 +330,12 @@ where } } - fn get_balance(&mut self, purse: URef) -> Result, Error> { - match ::balance(self, purse) { + fn available_balance( + &mut self, + purse: URef, + holds_epoch: Option, + ) -> Result, Error> { + match ::balance(self, purse, holds_epoch) { Ok(ret) => Ok(ret), Err(err) => { error!("{}", err); diff --git a/storage/src/system/auction/detail.rs b/storage/src/system/auction/detail.rs index 38b8a1d869..e30135f481 100644 --- a/storage/src/system/auction/detail.rs +++ b/storage/src/system/auction/detail.rs @@ -270,7 +270,11 @@ pub fn create_unbonding_purse( amount: U512, new_validator: Option, ) -> Result<(), Error> { - if provider.get_balance(bonding_purse)?.unwrap_or_default() < amount { + if provider + .available_balance(bonding_purse, None)? + .unwrap_or_default() + < amount + { return Err(Error::UnbondTooLarge); } @@ -453,6 +457,7 @@ where *unbonding_purse.amount(), max_delegators_per_validator, minimum_delegation_amount, + None, ); match redelegation { Ok(_) => Ok(UnbondRedelegationOutcome::SuccessfullyRedelegated), @@ -475,6 +480,7 @@ where /// If specified validator exists, and if validator is not yet at max delegators count, processes /// delegation. For a new delegation a delegator bid record will be created to track the delegation, /// otherwise the existing tracking record will be updated. +#[allow(clippy::too_many_arguments)] pub fn handle_delegation

( provider: &mut P, delegator_public_key: PublicKey, @@ -483,6 +489,7 @@ pub fn handle_delegation

( amount: U512, max_delegators_per_validator: u32, minimum_delegation_amount: u64, + holds_epoch: Option, ) -> Result where P: StorageProvider + MintProvider + RuntimeProvider, @@ -538,6 +545,7 @@ where target, amount, None, + holds_epoch, ) .map_err(|_| Error::TransferToDelegatorPurse)? .map_err(|mint_error| { diff --git a/storage/src/system/auction/providers.rs b/storage/src/system/auction/providers.rs index 2e2c25075f..3ef806b263 100644 --- a/storage/src/system/auction/providers.rs +++ b/storage/src/system/auction/providers.rs @@ -91,6 +91,7 @@ pub trait MintProvider { target: URef, amount: U512, id: Option, + holds_epoch: Option, ) -> Result, Error>; /// Mint `amount` new token into `existing_purse`. @@ -102,7 +103,11 @@ pub trait MintProvider { fn create_purse(&mut self) -> Result; /// Gets purse balance. - fn get_balance(&mut self, purse: URef) -> Result, Error>; + fn available_balance( + &mut self, + purse: URef, + holds_epoch: Option, + ) -> Result, Error>; /// Reads the base round reward. fn read_base_round_reward(&mut self) -> Result; diff --git a/storage/src/system/handle_payment/internal.rs b/storage/src/system/handle_payment/internal.rs index 7cab48fc71..8d9c884922 100644 --- a/storage/src/system/handle_payment/internal.rs +++ b/storage/src/system/handle_payment/internal.rs @@ -100,7 +100,10 @@ pub fn finalize_payment( } let payment_purse = get_payment_purse(provider)?; - let mut payment_amount = match provider.balance(payment_purse)? { + let mut payment_amount = match provider.available_balance( + payment_purse, + None, // the internal payment purse does not have holds + )? { Some(balance) => balance, None => return Err(Error::PaymentPurseBalanceNotFound), }; @@ -247,7 +250,9 @@ where let administrative_accounts = provider.administrative_accounts().clone(); let accumulation_purse = get_accumulation_purse(provider)?; - let accumulated_balance = provider.balance(accumulation_purse)?.unwrap_or_default(); + let accumulated_balance = provider + .available_balance(accumulation_purse, None)? + .unwrap_or_default(); let reward_recipients = U512::from(administrative_accounts.len()); if let Some(reward_amount) = accumulated_balance.checked_div(reward_recipients) { diff --git a/storage/src/system/handle_payment/mint_provider.rs b/storage/src/system/handle_payment/mint_provider.rs index bcc13e83d6..b1bd6ce7ff 100644 --- a/storage/src/system/handle_payment/mint_provider.rs +++ b/storage/src/system/handle_payment/mint_provider.rs @@ -21,7 +21,11 @@ pub trait MintProvider { ) -> Result<(), Error>; /// Checks balance of a `purse`. Returns `None` if given purse does not exist. - fn balance(&mut self, purse: URef) -> Result, Error>; + fn available_balance( + &mut self, + purse: URef, + holds_epoch: Option, + ) -> Result, Error>; /// Reduce total supply by `amount`. fn reduce_total_supply(&mut self, amount: U512) -> Result<(), Error>; diff --git a/storage/src/system/mint.rs b/storage/src/system/mint.rs index 71c7ff331f..7c57454c7c 100644 --- a/storage/src/system/mint.rs +++ b/storage/src/system/mint.rs @@ -86,8 +86,8 @@ pub trait Mint: RuntimeProvider + StorageProvider + SystemProvider { } /// Read balance of given `purse`. - fn balance(&mut self, purse: URef) -> Result, Error> { - match self.read_balance(purse)? { + fn balance(&mut self, purse: URef, hold_epoch: Option) -> Result, Error> { + match self.available_balance(purse, hold_epoch)? { some @ Some(_) => Ok(some), None => Err(Error::PurseNotFound), } @@ -101,6 +101,7 @@ pub trait Mint: RuntimeProvider + StorageProvider + SystemProvider { target: URef, amount: U512, id: Option, + holds_epoch: Option, ) -> Result<(), Error> { if !self.allow_unrestricted_transfers() { let registry = match self.get_system_entity_registry() { @@ -109,7 +110,7 @@ pub trait Mint: RuntimeProvider + StorageProvider + SystemProvider { }; let immediate_caller = self.get_immediate_caller(); match immediate_caller { - Some(Caller::AddressableEntity { + Some(Caller::Entity { entity_hash: contract_hash, .. }) if registry.has_contract_hash(&contract_hash) => { @@ -117,20 +118,20 @@ pub trait Mint: RuntimeProvider + StorageProvider + SystemProvider { // transfer) } - Some(Caller::Session { account_hash: _ }) + Some(Caller::Initiator { account_hash: _ }) if self.is_called_from_standard_payment() => { // Standard payment acts as a session without separate stack frame and calls // into mint's transfer. } - Some(Caller::Session { account_hash }) + Some(Caller::Initiator { account_hash }) if account_hash == PublicKey::System.to_account_hash() => { // System calls a session code. } - Some(Caller::Session { account_hash }) => { + Some(Caller::Initiator { account_hash }) => { // For example: a session using transfer host functions, or calling the mint's // entrypoint directly @@ -179,7 +180,7 @@ pub trait Mint: RuntimeProvider + StorageProvider + SystemProvider { } } - Some(Caller::AddressableEntity { + Some(Caller::Entity { package_hash: _, entity_hash: _, }) => { @@ -210,14 +211,14 @@ pub trait Mint: RuntimeProvider + StorageProvider + SystemProvider { // a deposit of token. Generally, deposit of a desirable resource is permissive. return Err(Error::InvalidAccessRights); } - let source_balance: U512 = match self.read_balance(source)? { + let source_balance: U512 = match self.available_balance(source, holds_epoch)? { Some(source_balance) => source_balance, None => return Err(Error::SourceNotFound), }; if amount > source_balance { return Err(Error::InsufficientFunds); } - if self.read_balance(target)?.is_none() { + if self.available_balance(target, None)?.is_none() { return Err(Error::DestNotFound); } if self.get_caller() != PublicKey::System.to_account_hash() @@ -275,7 +276,7 @@ pub trait Mint: RuntimeProvider + StorageProvider + SystemProvider { // treat as noop return Ok(()); } - if self.read_balance(existing_purse)?.is_none() { + if self.available_balance(existing_purse, None)?.is_none() { return Err(Error::PurseNotFound); } self.add_balance(existing_purse, amount)?; diff --git a/storage/src/system/mint/mint_native.rs b/storage/src/system/mint/mint_native.rs index 85b648b3c3..1f61d5ee50 100644 --- a/storage/src/system/mint/mint_native.rs +++ b/storage/src/system/mint/mint_native.rs @@ -29,7 +29,7 @@ where } fn get_immediate_caller(&self) -> Option { - let caller = Caller::Session { + let caller = Caller::Initiator { account_hash: PublicKey::System.to_account_hash(), }; Some(caller) @@ -169,11 +169,15 @@ where Ok(()) } - fn read_balance(&mut self, uref: URef) -> Result, Error> { + fn available_balance( + &mut self, + uref: URef, + holds_epoch: Option, + ) -> Result, Error> { match self .tracking_copy() .borrow_mut() - .get_purse_balance(Key::Balance(uref.addr())) + .get_available_balance(Key::Balance(uref.addr()), holds_epoch) { Ok(motes) => Ok(Some(motes.value())), Err(_) => Err(Error::Storage), diff --git a/storage/src/system/mint/storage_provider.rs b/storage/src/system/mint/storage_provider.rs index efedb9110f..b6804175c1 100644 --- a/storage/src/system/mint/storage_provider.rs +++ b/storage/src/system/mint/storage_provider.rs @@ -19,7 +19,11 @@ pub trait StorageProvider { fn add(&mut self, uref: URef, value: T) -> Result<(), Error>; /// Read balance. - fn read_balance(&mut self, uref: URef) -> Result, Error>; + fn available_balance( + &mut self, + uref: URef, + holds_epoch: Option, + ) -> Result, Error>; /// Write balance. fn write_balance(&mut self, uref: URef, balance: U512) -> Result<(), Error>; diff --git a/storage/src/system/runtime_native.rs b/storage/src/system/runtime_native.rs index 6de5d8adf1..80c4d2119e 100644 --- a/storage/src/system/runtime_native.rs +++ b/storage/src/system/runtime_native.rs @@ -20,6 +20,7 @@ pub struct Config { compute_rewards: bool, max_delegators_per_validator: u32, minimum_delegation_amount: u64, + balance_hold_interval: u64, } impl Config { @@ -33,6 +34,7 @@ impl Config { compute_rewards: bool, max_delegators_per_validator: u32, minimum_delegation_amount: u64, + balance_hold_interval: u64, ) -> Self { Config { transfer_config, @@ -43,6 +45,7 @@ impl Config { compute_rewards, max_delegators_per_validator, minimum_delegation_amount, + balance_hold_interval, } } @@ -55,6 +58,7 @@ impl Config { let compute_rewards = chainspec.core_config.compute_rewards; let max_delegators_per_validator = chainspec.core_config.max_delegators_per_validator; let minimum_delegation_amount = chainspec.core_config.minimum_delegation_amount; + let balance_hold_interval = chainspec.core_config.balance_hold_interval.millis(); Config::new( transfer_config, fee_handling, @@ -64,6 +68,7 @@ impl Config { compute_rewards, max_delegators_per_validator, minimum_delegation_amount, + balance_hold_interval, ) } @@ -99,6 +104,10 @@ impl Config { self.minimum_delegation_amount } + pub fn balance_hold_interval(&self) -> u64 { + self.balance_hold_interval + } + pub fn set_transfer_config(self, transfer_config: TransferConfig) -> Self { Config { transfer_config, @@ -109,6 +118,7 @@ impl Config { allow_auction_bids: self.allow_auction_bids, minimum_delegation_amount: self.minimum_delegation_amount, compute_rewards: self.compute_rewards, + balance_hold_interval: self.balance_hold_interval, } } } diff --git a/storage/src/system/transfer.rs b/storage/src/system/transfer.rs index c23a40c940..b985615c7e 100644 --- a/storage/src/system/transfer.rs +++ b/storage/src/system/transfer.rs @@ -137,6 +137,7 @@ pub struct TransferArgs { target: URef, amount: U512, arg_id: Option, + holds_epoch: Option, } impl TransferArgs { @@ -147,6 +148,7 @@ impl TransferArgs { target: URef, amount: U512, arg_id: Option, + holds_epoch: Option, ) -> Self { Self { to, @@ -154,6 +156,7 @@ impl TransferArgs { target, amount, arg_id, + holds_epoch, } } @@ -172,14 +175,19 @@ impl TransferArgs { self.target } + /// Returns `amount` field. + pub fn amount(&self) -> U512 { + self.amount + } + /// Returns `arg_id` field. pub fn arg_id(&self) -> Option { self.arg_id } - /// Returns `amount` field. - pub fn amount(&self) -> U512 { - self.amount + /// Returns `holds_epoch` field. + pub fn holds_epoch(&self) -> Option { + self.holds_epoch } } @@ -194,6 +202,7 @@ impl TryFrom for RuntimeArgs { runtime_args.insert(mint::ARG_TARGET, transfer_args.target)?; runtime_args.insert(mint::ARG_AMOUNT, transfer_args.amount)?; runtime_args.insert(mint::ARG_ID, transfer_args.arg_id)?; + runtime_args.insert(mint::ARG_HOLDS_EPOCH, transfer_args.holds_epoch)?; Ok(runtime_args) } @@ -230,7 +239,10 @@ impl TransferRuntimeArgsBuilder { Ok(key) => key, Err(_) => return false, }; - tracking_copy.borrow_mut().get_purse_balance(key).is_ok() + tracking_copy + .borrow_mut() + .get_available_balance(key, None) + .is_ok() } /// Resolves the source purse of the transfer. @@ -406,6 +418,15 @@ impl TransferRuntimeArgsBuilder { Ok(id) } + fn resolve_holds_epoch(&self) -> Result, TransferError> { + let id_value = self + .inner + .get(mint::ARG_HOLDS_EPOCH) + .ok_or_else(|| TransferError::MissingArgument)?; + let id: Option = self.map_cl_value(id_value)?; + Ok(id) + } + /// Creates new [`TransferArgs`] instance. pub fn build( mut self, @@ -417,7 +438,7 @@ impl TransferRuntimeArgsBuilder { where R: StateReader, { - let (to, target_uref) = match self + let (to, target) = match self .resolve_transfer_target_mode(protocol_version, Rc::clone(&tracking_copy))? { NewTransferTargetMode::ExistingAccount { @@ -436,23 +457,26 @@ impl TransferRuntimeArgsBuilder { } }; - let source_uref = + let source = self.resolve_source_uref(from, entity_named_keys, Rc::clone(&tracking_copy))?; - if source_uref.addr() == target_uref.addr() { + if source.addr() == target.addr() { return Err(TransferError::InvalidPurse); } let amount = self.resolve_amount()?; - let id = self.resolve_id()?; + let arg_id = self.resolve_id()?; + + let holds_epoch = self.resolve_holds_epoch()?; Ok(TransferArgs { to, - source: source_uref, - target: target_uref, + source, + target, amount, - arg_id: id, + arg_id, + holds_epoch, }) } diff --git a/storage/src/tracking_copy/ext.rs b/storage/src/tracking_copy/ext.rs index 7cc5b4e167..3b425bc872 100644 --- a/storage/src/tracking_copy/ext.rs +++ b/storage/src/tracking_copy/ext.rs @@ -1,10 +1,17 @@ -use std::{collections::BTreeSet, convert::TryInto}; +use std::{ + collections::{btree_map::Entry, BTreeMap, BTreeSet}, + convert::TryInto, +}; -use crate::global_state::{error::Error as GlobalStateError, state::StateReader}; +use crate::{ + data_access_layer::balance::BalanceHoldsWithProof, + global_state::{error::Error as GlobalStateError, state::StateReader}, +}; use casper_types::{ - account::AccountHash, addressable_entity::NamedKeys, global_state::TrieMerkleProof, ByteCode, - ByteCodeAddr, ByteCodeHash, CLValue, ChecksumRegistry, EntityAddr, Key, KeyTag, Motes, Package, - PackageHash, StoredValue, StoredValueTypeMismatch, SystemEntityRegistry, URef, + account::AccountHash, addressable_entity::NamedKeys, global_state::TrieMerkleProof, + system::mint::BalanceHoldAddrTag, BlockTime, ByteCode, ByteCodeAddr, ByteCodeHash, CLValue, + ChecksumRegistry, EntityAddr, Key, KeyTag, Motes, Package, PackageHash, StoredValue, + StoredValueTypeMismatch, SystemEntityRegistry, URef, URefAddr, U512, }; use crate::tracking_copy::{TrackingCopy, TrackingCopyError}; @@ -20,8 +27,13 @@ pub trait TrackingCopyExt { /// Gets the purse balance key for a given purse. fn get_purse_balance_key(&self, purse_key: Key) -> Result; - /// Gets the balance for a given balance key. - fn get_purse_balance(&self, balance_key: Key) -> Result; + /// Returns the available balance, considering any holds from holds_epoch to now. + /// If holds_epoch is none, available balance == total balance. + fn get_available_balance( + &self, + balance_key: Key, + holds_epoch: Option, + ) -> Result; /// Gets the purse balance key for a given purse and provides a Merkle proof. fn get_purse_balance_key_with_proof( @@ -30,10 +42,18 @@ pub trait TrackingCopyExt { ) -> Result<(Key, TrieMerkleProof), Self::Error>; /// Gets the balance at a given balance key and provides a Merkle proof. - fn get_purse_balance_with_proof( + fn get_total_balance_with_proof( &self, balance_key: Key, - ) -> Result<(Motes, TrieMerkleProof), Self::Error>; + ) -> Result<(U512, TrieMerkleProof), Self::Error>; + + /// Gets the balance holds for a given balance, with Merkle proofs. + fn get_balance_holds_with_proof( + &self, + purse_addr: URefAddr, + block_time: u64, + hold_interval: u64, + ) -> Result, Self::Error>; /// Returns the collection of named keys for a given AddressableEntity. fn get_named_keys(&mut self, entity_addr: EntityAddr) -> Result; @@ -75,15 +95,61 @@ where Ok(Key::Balance(balance_key.addr())) } - fn get_purse_balance(&self, key: Key) -> Result { - let stored_value: StoredValue = self - .read(&key)? - .ok_or(TrackingCopyError::KeyNotFound(key))?; - let cl_value: CLValue = stored_value - .try_into() - .map_err(TrackingCopyError::TypeMismatch)?; - let balance = Motes::new(cl_value.into_t()?); - Ok(balance) + fn get_available_balance( + &self, + key: Key, + holds_epoch: Option, + ) -> Result { + let key = { + if let Key::URef(uref) = key { + Key::Balance(uref.addr()) + } else { + key + } + }; + + if let Key::Balance(purse_addr) = key { + let stored_value: StoredValue = self + .read(&key)? + .ok_or(TrackingCopyError::KeyNotFound(key))?; + let cl_value: CLValue = stored_value + .try_into() + .map_err(TrackingCopyError::TypeMismatch)?; + let total_balance = cl_value.into_t()?; + match holds_epoch { + None => Ok(Motes::new(total_balance)), + Some(epoch) => { + let mut total_holds = U512::zero(); + let tag = BalanceHoldAddrTag::Gas; + let prefix = tag.purse_prefix_by_tag(purse_addr)?; + let gas_hold_keys = self.keys_with_prefix(&prefix)?; + for gas_hold_key in gas_hold_keys { + if let Some(balance_hold_addr) = gas_hold_key.as_balance_hold() { + let block_time = balance_hold_addr.block_time(); + if block_time.value() < epoch { + // ignore holds from prior to imputed epoch + continue; + } + let stored_value: StoredValue = self + .read(&gas_hold_key)? + .ok_or(TrackingCopyError::KeyNotFound(key))?; + let cl_value: CLValue = stored_value + .try_into() + .map_err(TrackingCopyError::TypeMismatch)?; + let hold_amount = cl_value.into_t()?; + total_holds = + total_holds.checked_add(hold_amount).unwrap_or(U512::zero()); + } + } + let available = total_balance + .checked_sub(total_holds) + .unwrap_or(U512::zero()); + Ok(Motes::new(available)) + } + } + } else { + Err(Self::Error::UnexpectedKeyVariant(key)) + } } fn get_purse_balance_key_with_proof( @@ -105,20 +171,78 @@ where Ok((balance_key, proof)) } - fn get_purse_balance_with_proof( + fn get_total_balance_with_proof( &self, key: Key, - ) -> Result<(Motes, TrieMerkleProof), Self::Error> { - let proof: TrieMerkleProof = self - .read_with_proof(&key.normalize())? - .ok_or(TrackingCopyError::KeyNotFound(key))?; - let cl_value: CLValue = proof - .value() - .to_owned() - .try_into() - .map_err(TrackingCopyError::TypeMismatch)?; - let balance = Motes::new(cl_value.into_t()?); - Ok((balance, proof)) + ) -> Result<(U512, TrieMerkleProof), Self::Error> { + if let Key::Balance(_) = key { + let proof: TrieMerkleProof = self + .read_with_proof(&key.normalize())? + .ok_or(TrackingCopyError::KeyNotFound(key))?; + let cl_value: CLValue = proof + .value() + .to_owned() + .try_into() + .map_err(TrackingCopyError::TypeMismatch)?; + let balance = cl_value.into_t()?; + Ok((balance, proof)) + } else { + Err(Self::Error::UnexpectedKeyVariant(key)) + } + } + + fn get_balance_holds_with_proof( + &self, + purse_addr: URefAddr, + block_time: u64, + hold_interval: u64, + ) -> Result, Self::Error> { + let hold_epoch = block_time.saturating_sub(hold_interval); + + let mut ret: BTreeMap = BTreeMap::new(); + let tag = BalanceHoldAddrTag::Gas; + let prefix = tag.purse_prefix_by_tag(purse_addr)?; + let gas_hold_keys = self.keys_with_prefix(&prefix)?; + // if more hold kinds are added, chain them here and loop once. + for gas_hold_key in gas_hold_keys { + if let Some(balance_hold_addr) = gas_hold_key.as_balance_hold() { + let block_time = balance_hold_addr.block_time(); + if block_time.value() < hold_epoch { + // ignore holds older than the interval + continue; + } + let proof: TrieMerkleProof = self + .read_with_proof(&gas_hold_key.normalize())? + .ok_or(TrackingCopyError::KeyNotFound(gas_hold_key))?; + let cl_value: CLValue = proof + .value() + .to_owned() + .try_into() + .map_err(TrackingCopyError::TypeMismatch)?; + let hold_amount = cl_value.into_t()?; + match ret.entry(block_time) { + Entry::Vacant(entry) => { + let mut inner = BTreeMap::new(); + inner.insert(tag, (hold_amount, proof)); + entry.insert(inner); + } + Entry::Occupied(mut occupied_entry) => { + let inner = occupied_entry.get_mut(); + match inner.entry(tag) { + Entry::Vacant(entry) => { + entry.insert((hold_amount, proof)); + } + Entry::Occupied(_) => { + unreachable!( + "there should be only one entry per (block_time, hold kind)" + ); + } + } + } + } + } + } + Ok(ret) } fn get_byte_code(&mut self, byte_code_hash: ByteCodeHash) -> Result { diff --git a/types/src/chainspec/core_config.rs b/types/src/chainspec/core_config.rs index 12d40a50a7..7cad2b2e16 100644 --- a/types/src/chainspec/core_config.rs +++ b/types/src/chainspec/core_config.rs @@ -120,14 +120,16 @@ pub struct CoreConfig { pub allow_unrestricted_transfers: bool, /// If set to false then consensus doesn't compute rewards and always uses 0. pub compute_rewards: bool, - /// Administrative accounts are a valid option for a private chain only. - #[serde(default, skip_serializing_if = "BTreeSet::is_empty")] - pub administrators: BTreeSet, /// Refund handling. #[cfg_attr(feature = "datasize", data_size(skip))] pub refund_handling: RefundHandling, /// Fee handling. pub fee_handling: FeeHandling, + /// How long does it take for a balance hold to fade away? + pub balance_hold_interval: TimeDiff, + /// Administrative accounts are a valid option for a private chain only. + //#[serde(default, skip_serializing_if = "BTreeSet::is_empty")] + pub administrators: BTreeSet, } impl CoreConfig { @@ -202,6 +204,8 @@ impl CoreConfig { FeeHandling::Accumulate }; + let balance_hold_interval = TimeDiff::from_seconds(rng.gen_range(600..604_800)); + CoreConfig { era_duration, minimum_era_height, @@ -232,6 +236,7 @@ impl CoreConfig { compute_rewards, refund_handling, fee_handling, + balance_hold_interval, } } } @@ -271,6 +276,7 @@ impl Default for CoreConfig { refund_ratio: Ratio::new_raw(99, 100), }, fee_handling: FeeHandling::PayToProposer, + balance_hold_interval: TimeDiff::from_seconds(24 * 60 * 60), } } } @@ -310,6 +316,7 @@ impl ToBytes for CoreConfig { buffer.extend(self.administrators.to_bytes()?); buffer.extend(self.refund_handling.to_bytes()?); buffer.extend(self.fee_handling.to_bytes()?); + buffer.extend(self.balance_hold_interval.to_bytes()?); Ok(buffer) } @@ -345,6 +352,7 @@ impl ToBytes for CoreConfig { + self.administrators.serialized_length() + self.refund_handling.serialized_length() + self.fee_handling.serialized_length() + + self.balance_hold_interval.serialized_length() } } @@ -380,6 +388,7 @@ impl FromBytes for CoreConfig { let (administrative_accounts, remainder) = FromBytes::from_bytes(remainder)?; let (refund_handling, remainder) = FromBytes::from_bytes(remainder)?; let (fee_handling, remainder) = FromBytes::from_bytes(remainder)?; + let (balance_hold_interval, remainder) = TimeDiff::from_bytes(remainder)?; let config = CoreConfig { era_duration, minimum_era_height, @@ -410,6 +419,7 @@ impl FromBytes for CoreConfig { administrators: administrative_accounts, refund_handling, fee_handling, + balance_hold_interval, }; Ok((config, remainder)) } diff --git a/types/src/chainspec/protocol_config.rs b/types/src/chainspec/protocol_config.rs index f693578fd0..5d4aecf719 100644 --- a/types/src/chainspec/protocol_config.rs +++ b/types/src/chainspec/protocol_config.rs @@ -9,7 +9,7 @@ use std::{collections::BTreeMap, str::FromStr}; use crate::testing::TestRng; use crate::{ bytesrepr::{self, FromBytes, ToBytes}, - Key, ProtocolVersion, StoredValue, + Key, ProtocolVersion, StoredValue, Timestamp, }; use crate::{ActivationPoint, GlobalStateUpdate}; @@ -104,6 +104,17 @@ impl FromBytes for ProtocolConfig { } } +impl Default for ProtocolConfig { + fn default() -> Self { + ProtocolConfig { + activation_point: ActivationPoint::Genesis(Timestamp::now()), + global_state_update: None, + hard_reset: true, + version: ProtocolVersion::V2_0_0, + } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/types/src/contract_messages/messages.rs b/types/src/contract_messages/messages.rs index 082c95e9f6..b23a9bba7a 100644 --- a/types/src/contract_messages/messages.rs +++ b/types/src/contract_messages/messages.rs @@ -191,7 +191,7 @@ impl FromBytes for MessagePayload { #[cfg_attr(feature = "json-schema", derive(JsonSchema))] pub struct Message { /// The identity of the entity that produced the message. - entity_addr: AddressableEntityHash, + entity_hash: AddressableEntityHash, // TODO: this should be EntityAddr /// The payload of the message. message: MessagePayload, /// The name of the topic on which the message was emitted on. @@ -212,7 +212,7 @@ impl Message { index: u32, ) -> Self { Self { - entity_addr: source, + entity_hash: source, message, topic_name, topic_name_hash, @@ -221,8 +221,8 @@ impl Message { } /// Returns a reference to the identity of the entity that produced the message. - pub fn entity_addr(&self) -> &AddressableEntityHash { - &self.entity_addr + pub fn entity_hash(&self) -> &AddressableEntityHash { + &self.entity_hash } /// Returns a reference to the payload of the message. @@ -248,21 +248,21 @@ impl Message { /// Returns a new [`Key::Message`] based on the information in the message. /// This key can be used to query the checksum record for the message in global state. pub fn message_key(&self) -> Key { - Key::message(self.entity_addr, self.topic_name_hash, self.index) + Key::message(self.entity_hash, self.topic_name_hash, self.index) } /// Returns a new [`Key::Message`] based on the information in the message. /// This key can be used to query the control record for the topic of this message in global /// state. pub fn topic_key(&self) -> Key { - Key::message_topic(self.entity_addr, self.topic_name_hash) + Key::message_topic(self.entity_hash, self.topic_name_hash) } } impl ToBytes for Message { fn to_bytes(&self) -> Result, bytesrepr::Error> { let mut buffer = bytesrepr::allocate_buffer(self)?; - buffer.append(&mut self.entity_addr.to_bytes()?); + buffer.append(&mut self.entity_hash.to_bytes()?); buffer.append(&mut self.message.to_bytes()?); buffer.append(&mut self.topic_name.to_bytes()?); buffer.append(&mut self.topic_name_hash.to_bytes()?); @@ -271,7 +271,7 @@ impl ToBytes for Message { } fn serialized_length(&self) -> usize { - self.entity_addr.serialized_length() + self.entity_hash.serialized_length() + self.message.serialized_length() + self.topic_name.serialized_length() + self.topic_name_hash.serialized_length() @@ -288,7 +288,7 @@ impl FromBytes for Message { let (index, rem) = FromBytes::from_bytes(rem)?; Ok(( Message { - entity_addr, + entity_hash: entity_addr, message, topic_name, topic_name_hash, @@ -307,7 +307,7 @@ impl Distribution for Standard { let message = Alphanumeric.sample_string(rng, 64).into(); Message { - entity_addr: rng.gen(), + entity_hash: rng.gen(), message, topic_name, topic_name_hash, diff --git a/types/src/key.rs b/types/src/key.rs index 9c2510cd6c..215e5bf7db 100644 --- a/types/src/key.rs +++ b/types/src/key.rs @@ -873,6 +873,16 @@ impl Key { } } + /// Returns a reference to the inner `BalanceHoldAddr` if `self` is of type + /// [`Key::BalanceHold`], otherwise returns `None`. + pub fn as_balance_hold(&self) -> Option<&BalanceHoldAddr> { + if let Self::BalanceHold(addr) = self { + Some(addr) + } else { + None + } + } + /// Returns the inner [`URef`] if `self` is of type [`Key::URef`], otherwise returns `None`. pub fn into_uref(self) -> Option { match self { diff --git a/types/src/system/caller.rs b/types/src/system/caller.rs index b668af2aae..53f7b371b7 100644 --- a/types/src/system/caller.rs +++ b/types/src/system/caller.rs @@ -15,21 +15,21 @@ use crate::{ #[repr(u8)] pub enum CallerTag { /// Session tag. - Session = 0, + Initiator = 0, /// StoredContract tag. - StoredContract, + Entity, } /// Identity of a calling entity. #[derive(Clone, Debug, PartialEq, Eq)] pub enum Caller { - /// Session - Session { + /// Initiator (calling account) + Initiator { /// The account hash of the caller account_hash: AccountHash, }, - /// AddressableEntity - AddressableEntity { + /// Entity (smart contract / system contract) + Entity { /// The package hash package_hash: PackageHash, /// The entity hash @@ -38,19 +38,16 @@ pub enum Caller { } impl Caller { - /// Creates a [`Caller::Session`]. This represents a call into session code, and + /// Creates a [`Caller::Initiator`]. This represents a call into session code, and /// should only ever happen once in a call stack. - pub fn session(account_hash: AccountHash) -> Self { - Caller::Session { account_hash } + pub fn initiator(account_hash: AccountHash) -> Self { + Caller::Initiator { account_hash } } - /// Creates a [`'Caller::StoredContract`]. This represents a call into a contract with - /// `EntryPointType::Contract`. - pub fn stored_contract( - package_hash: PackageHash, - contract_hash: AddressableEntityHash, - ) -> Self { - Caller::AddressableEntity { + /// Creates a [`'Caller::Entity`]. This represents a call into a contract with + /// `EntryPointType::Called`. + pub fn entity(package_hash: PackageHash, contract_hash: AddressableEntityHash) -> Self { + Caller::Entity { package_hash, entity_hash: contract_hash, } @@ -59,18 +56,18 @@ impl Caller { /// Gets the tag from self. pub fn tag(&self) -> CallerTag { match self { - Caller::Session { .. } => CallerTag::Session, + Caller::Initiator { .. } => CallerTag::Initiator, - Caller::AddressableEntity { .. } => CallerTag::StoredContract, + Caller::Entity { .. } => CallerTag::Entity, } } /// Gets the [`AddressableEntityHash`] for both stored session and stored contract variants. pub fn contract_hash(&self) -> Option<&AddressableEntityHash> { match self { - Caller::Session { .. } => None, + Caller::Initiator { .. } => None, - Caller::AddressableEntity { + Caller::Entity { entity_hash: contract_hash, .. } => Some(contract_hash), @@ -83,9 +80,9 @@ impl ToBytes for Caller { let mut result = bytesrepr::allocate_buffer(self)?; result.push(self.tag() as u8); match self { - Caller::Session { account_hash } => result.append(&mut account_hash.to_bytes()?), + Caller::Initiator { account_hash } => result.append(&mut account_hash.to_bytes()?), - Caller::AddressableEntity { + Caller::Entity { package_hash, entity_hash: contract_hash, } => { @@ -99,8 +96,8 @@ impl ToBytes for Caller { fn serialized_length(&self) -> usize { U8_SERIALIZED_LENGTH + match self { - Caller::Session { account_hash } => account_hash.serialized_length(), - Caller::AddressableEntity { + Caller::Initiator { account_hash } => account_hash.serialized_length(), + Caller::Entity { package_hash, entity_hash: contract_hash, } => package_hash.serialized_length() + contract_hash.serialized_length(), @@ -113,15 +110,15 @@ impl FromBytes for Caller { let (tag, remainder): (u8, &[u8]) = FromBytes::from_bytes(bytes)?; let tag = CallerTag::from_u8(tag).ok_or(bytesrepr::Error::Formatting)?; match tag { - CallerTag::Session => { + CallerTag::Initiator => { let (account_hash, remainder) = AccountHash::from_bytes(remainder)?; - Ok((Caller::Session { account_hash }, remainder)) + Ok((Caller::Initiator { account_hash }, remainder)) } - CallerTag::StoredContract => { + CallerTag::Entity => { let (package_hash, remainder) = PackageHash::from_bytes(remainder)?; let (contract_hash, remainder) = AddressableEntityHash::from_bytes(remainder)?; Ok(( - Caller::AddressableEntity { + Caller::Entity { package_hash, entity_hash: contract_hash, }, diff --git a/types/src/system/mint/balance_hold.rs b/types/src/system/mint/balance_hold.rs index 4764b91685..3e812da239 100644 --- a/types/src/system/mint/balance_hold.rs +++ b/types/src/system/mint/balance_hold.rs @@ -50,6 +50,15 @@ impl BalanceHoldAddrTag { } None } + + /// Returns key prefix for a purse by balance hold addr tag. + pub fn purse_prefix_by_tag(&self, purse_addr: URefAddr) -> Result, bytesrepr::Error> { + let mut ret = Vec::with_capacity(purse_addr.serialized_length() + 2); + ret.push(KeyTag::BalanceHold as u8); + ret.push(*self as u8); + purse_addr.write_bytes(&mut ret)?; + Ok(ret) + } } impl Display for BalanceHoldAddrTag { @@ -118,6 +127,13 @@ impl BalanceHoldAddr { } } + /// Returns the `[BlockTime]` when this hold was written. + pub fn block_time(&self) -> BlockTime { + match self { + BalanceHoldAddr::Gas { block_time, .. } => *block_time, + } + } + /// Returns the common prefix of all holds on the cited purse. pub fn balance_hold_prefix(&self) -> Result, Error> { let purse_addr_bytes = self.purse_addr().to_bytes()?; diff --git a/types/src/system/mint/constants.rs b/types/src/system/mint/constants.rs index cffada448e..b5d73f7fab 100644 --- a/types/src/system/mint/constants.rs +++ b/types/src/system/mint/constants.rs @@ -4,6 +4,8 @@ pub const ARG_PURSE: &str = "purse"; pub const ARG_AMOUNT: &str = "amount"; /// Named constant for `id`. pub const ARG_ID: &str = "id"; +/// Named constant for `holds_epoch`. +pub const ARG_HOLDS_EPOCH: &str = "holds_epoch"; /// Named constant for `to`. pub const ARG_TO: &str = "to"; /// Named constant for `source`. diff --git a/types/src/transaction/transaction_entry_point.rs b/types/src/transaction/transaction_entry_point.rs index c7a64e429d..06c45c94e3 100644 --- a/types/src/transaction/transaction_entry_point.rs +++ b/types/src/transaction/transaction_entry_point.rs @@ -163,6 +163,20 @@ impl TransactionEntryPoint { _ => unreachable!(), } } + + /// Does this entry point kind require holds epoch? + pub fn requires_holds_epoch(&self) -> bool { + match self { + TransactionEntryPoint::AddBid + | TransactionEntryPoint::Delegate + | TransactionEntryPoint::Custom(_) + | TransactionEntryPoint::Transfer => true, + TransactionEntryPoint::WithdrawBid + | TransactionEntryPoint::Undelegate + | TransactionEntryPoint::Redelegate + | TransactionEntryPoint::ActivateBid => false, + } + } } impl Display for TransactionEntryPoint { From 46bc2f6ba9e4423ad65ef4c2206db8a19edc5a7e Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Wed, 13 Mar 2024 22:27:19 +0000 Subject: [PATCH 14/70] update Motes constructors --- .../test_support/src/lib.rs | 4 +- .../tests/src/test/check_transfer_success.rs | 12 +- .../tests/src/test/contract_api/dictionary.rs | 4 +- .../tests/src/test/private_chain.rs | 11 +- .../tests/src/test/regression/ee_1045.rs | 16 +- .../tests/src/test/regression/ee_1119.rs | 4 +- .../tests/src/test/regression/ee_1120.rs | 8 +- .../tests/src/test/regression/ee_1129.rs | 6 +- .../tests/src/test/regression/ee_1152.rs | 8 +- .../tests/src/test/regression/ee_597.rs | 7 +- .../tests/src/test/regression/ee_598.rs | 4 +- .../tests/src/test/regression/gh_3208.rs | 4 +- .../tests/src/test/regression/gov_116.rs | 6 +- .../src/test/regression/gov_89_regression.rs | 8 +- .../tests/src/test/step.rs | 8 +- .../src/test/system_contracts/auction/bids.rs | 168 +++++++++--------- .../test/system_contracts/auction_bidding.rs | 2 +- .../src/test/system_contracts/genesis.rs | 8 +- .../tests/src/test/system_costs.rs | 16 +- node/src/components/consensus/tests/utils.rs | 2 +- node/src/utils/chain_specification.rs | 8 +- storage/src/system/genesis.rs | 7 +- storage/src/tracking_copy/ext.rs | 6 +- types/src/chainspec/accounts_config.rs | 4 +- .../accounts_config/account_config.rs | 3 +- .../accounts_config/delegator_config.rs | 4 +- .../src/chainspec/accounts_config/genesis.rs | 11 +- .../accounts_config/validator_config.rs | 2 +- .../transaction_config/deploy_config.rs | 7 +- types/src/gas.rs | 2 +- types/src/motes.rs | 61 ++++--- types/src/transaction/deploy.rs | 6 +- types/src/transaction/transaction_v1.rs | 6 +- 33 files changed, 213 insertions(+), 220 deletions(-) diff --git a/execution_engine_testing/test_support/src/lib.rs b/execution_engine_testing/test_support/src/lib.rs index e2b6ba2c90..b0637d7894 100644 --- a/execution_engine_testing/test_support/src/lib.rs +++ b/execution_engine_testing/test_support/src/lib.rs @@ -114,13 +114,13 @@ pub static DEFAULT_ACCOUNTS: Lazy> = Lazy::new(|| { let mut ret = Vec::new(); let genesis_account = GenesisAccount::account( DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), None, ); ret.push(genesis_account); let proposer_account = GenesisAccount::account( DEFAULT_PROPOSER_PUBLIC_KEY.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), None, ); ret.push(proposer_account); diff --git a/execution_engine_testing/tests/src/test/check_transfer_success.rs b/execution_engine_testing/tests/src/test/check_transfer_success.rs index 3598908995..1e2cd5c079 100644 --- a/execution_engine_testing/tests/src/test/check_transfer_success.rs +++ b/execution_engine_testing/tests/src/test/check_transfer_success.rs @@ -23,7 +23,7 @@ fn test_check_transfer_success_with_source_only() { // create a genesis account. let genesis_account = GenesisAccount::account( DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), - Motes::new(U512::from(DEFAULT_ACCOUNT_INITIAL_BALANCE)), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), None, ); @@ -72,7 +72,7 @@ fn test_check_transfer_success_with_source_only() { builder.exec(exec_request).commit().expect_success(); let transaction_fee = builder.get_proposer_purse_balance() - proposer_starting_balance; - let expected_source_ending_balance = Motes::new(U512::from(DEFAULT_ACCOUNT_INITIAL_BALANCE)) + let expected_source_ending_balance = Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE) - Motes::new(transfer_amount) - Motes::new(transaction_fee); let actual_source_ending_balance = Motes::new(builder.get_purse_balance(source_purse)); @@ -85,7 +85,7 @@ fn test_check_transfer_success_with_source_only() { fn test_check_transfer_success_with_source_only_errors() { let genesis_account = GenesisAccount::account( DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), - Motes::new(U512::from(DEFAULT_ACCOUNT_INITIAL_BALANCE)), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), None, ); @@ -133,7 +133,7 @@ fn test_check_transfer_success_with_source_only_errors() { builder.exec(exec_request).commit().expect_success(); let transaction_fee = builder.get_proposer_purse_balance() - proposer_starting_balance; - let expected_source_ending_balance = Motes::new(U512::from(DEFAULT_ACCOUNT_INITIAL_BALANCE)) + let expected_source_ending_balance = Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE) - Motes::new(transfer_amount) - Motes::new(transaction_fee); let actual_source_ending_balance = Motes::new(builder.get_purse_balance(source_purse)); @@ -146,7 +146,7 @@ fn test_check_transfer_success_with_source_only_errors() { fn test_check_transfer_success_with_source_and_target() { let genesis_account = GenesisAccount::account( DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), - Motes::new(U512::from(DEFAULT_ACCOUNT_INITIAL_BALANCE)), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), None, ); @@ -191,7 +191,7 @@ fn test_check_transfer_success_with_source_and_target() { builder.exec(exec_request).commit().expect_success(); let transaction_fee = builder.get_proposer_purse_balance() - proposer_starting_balance; - let expected_source_ending_balance = Motes::new(U512::from(DEFAULT_ACCOUNT_INITIAL_BALANCE)) + let expected_source_ending_balance = Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE) - Motes::new(transfer_amount) - Motes::new(transaction_fee); let actual_source_ending_balance = Motes::new(builder.get_purse_balance(source_purse)); diff --git a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs index 3b1c7bbe94..d33a12adac 100644 --- a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs +++ b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs @@ -12,7 +12,7 @@ use casper_storage::data_access_layer::GenesisRequest; use casper_types::{ account::AccountHash, addressable_entity::EntityKindTag, runtime_args, AccessRights, AddressableEntityHash, ApiError, CLType, CLValue, GenesisAccount, Key, Motes, RuntimeArgs, - StoredValue, U512, + StoredValue, }; use dictionary_call::{NEW_DICTIONARY_ITEM_KEY, NEW_DICTIONARY_VALUE}; @@ -514,7 +514,7 @@ fn dictionary_get_should_fail_with_large_item_key() { fn should_query_dictionary_items_with_test_builder() { let genesis_account = GenesisAccount::account( DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), - Motes::new(U512::from(DEFAULT_ACCOUNT_INITIAL_BALANCE)), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), None, ); diff --git a/execution_engine_testing/tests/src/test/private_chain.rs b/execution_engine_testing/tests/src/test/private_chain.rs index 64401d0c2f..8d097193c1 100644 --- a/execution_engine_testing/tests/src/test/private_chain.rs +++ b/execution_engine_testing/tests/src/test/private_chain.rs @@ -97,17 +97,14 @@ static PRIVATE_CHAIN_GENESIS_VALIDATORS: Lazy> = Lazy::new(|| { let mut default_accounts = Vec::new(); - let proposer_account = GenesisAccount::account( - DEFAULT_PROPOSER_PUBLIC_KEY.clone(), - Motes::new(U512::zero()), - None, - ); + let proposer_account = + GenesisAccount::account(DEFAULT_PROPOSER_PUBLIC_KEY.clone(), Motes::zero(), None); default_accounts.push(proposer_account); // One normal account that starts at genesis default_accounts.push(GenesisAccount::account( ACCOUNT_1_PUBLIC_KEY.clone(), - Motes::new(U512::from(DEFAULT_ACCOUNT_INITIAL_BALANCE)), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), None, )); @@ -119,7 +116,7 @@ static PRIVATE_CHAIN_DEFAULT_ACCOUNTS: Lazy> = Lazy::new(|| public_key, // Genesis validators for a private network doesn't have balances, but they are part of // fixed set of validators - balance: Motes::new(U512::zero()), + balance: Motes::zero(), validator: Some(genesis_validator), }); } diff --git a/execution_engine_testing/tests/src/test/regression/ee_1045.rs b/execution_engine_testing/tests/src/test/regression/ee_1045.rs index 6078d123e2..310f6d0e5e 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1045.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1045.rs @@ -52,33 +52,33 @@ const ACCOUNT_4_BOND: u64 = 200_000; fn should_run_ee_1045_squash_validators() { let account_1 = GenesisAccount::account( ACCOUNT_1_PK.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), + Motes::new(ACCOUNT_1_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_1_BOND.into()), + Motes::new(ACCOUNT_1_BOND), DelegationRate::zero(), )), ); let account_2 = GenesisAccount::account( ACCOUNT_2_PK.clone(), - Motes::new(ACCOUNT_2_BALANCE.into()), + Motes::new(ACCOUNT_2_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_2_BOND.into()), + Motes::new(ACCOUNT_2_BOND), DelegationRate::zero(), )), ); let account_3 = GenesisAccount::account( ACCOUNT_3_PK.clone(), - Motes::new(ACCOUNT_3_BALANCE.into()), + Motes::new(ACCOUNT_3_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_3_BOND.into()), + Motes::new(ACCOUNT_3_BOND), DelegationRate::zero(), )), ); let account_4 = GenesisAccount::account( ACCOUNT_4_PK.clone(), - Motes::new(ACCOUNT_4_BALANCE.into()), + Motes::new(ACCOUNT_4_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_4_BOND.into()), + Motes::new(ACCOUNT_4_BOND), DelegationRate::zero(), )), ); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1119.rs b/execution_engine_testing/tests/src/test/regression/ee_1119.rs index 78bd0a7665..ef1fdaee6f 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1119.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1119.rs @@ -48,9 +48,9 @@ fn should_slash_validator_and_their_delegators() { let accounts = { let validator_1 = GenesisAccount::account( VALIDATOR_1.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), Some(GenesisValidator::new( - Motes::new(VALIDATOR_1_STAKE.into()), + Motes::new(VALIDATOR_1_STAKE), DelegationRate::zero(), )), ); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1120.rs b/execution_engine_testing/tests/src/test/regression/ee_1120.rs index 3d520f9d08..9447e0a121 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1120.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1120.rs @@ -59,17 +59,17 @@ fn should_run_ee_1120_slash_delegators() { let accounts = { let validator_1 = GenesisAccount::account( VALIDATOR_1.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), Some(GenesisValidator::new( - Motes::new(VALIDATOR_1_STAKE.into()), + Motes::new(VALIDATOR_1_STAKE), DelegationRate::zero(), )), ); let validator_2 = GenesisAccount::account( VALIDATOR_2.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), Some(GenesisValidator::new( - Motes::new(VALIDATOR_2_STAKE.into()), + Motes::new(VALIDATOR_2_STAKE), DelegationRate::zero(), )), ); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1129.rs b/execution_engine_testing/tests/src/test/regression/ee_1129.rs index e01027e304..4f86a5b654 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1129.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1129.rs @@ -48,9 +48,9 @@ fn should_run_ee_1129_underfunded_delegate_call() { let accounts = { let validator_1 = GenesisAccount::account( VALIDATOR_1.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), Some(GenesisValidator::new( - Motes::new(VALIDATOR_1_STAKE.into()), + Motes::new(VALIDATOR_1_STAKE), DelegationRate::zero(), )), ); @@ -113,7 +113,7 @@ fn should_run_ee_1129_underfunded_add_bid_call() { let accounts = { let validator_1 = GenesisAccount::account( VALIDATOR_1.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), None, ); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1152.rs b/execution_engine_testing/tests/src/test/regression/ee_1152.rs index 3ebac102f1..c435de9f77 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1152.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1152.rs @@ -37,17 +37,17 @@ fn should_run_ee_1152_regression_test() { let accounts = { let validator_1 = GenesisAccount::account( VALIDATOR_1.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), Some(GenesisValidator::new( - Motes::new(VALIDATOR_STAKE.into()), + Motes::new(VALIDATOR_STAKE), DelegationRate::zero(), )), ); let validator_2 = GenesisAccount::account( DELEGATOR_1.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), Some(GenesisValidator::new( - Motes::new(VALIDATOR_STAKE.into()), + Motes::new(VALIDATOR_STAKE), DelegationRate::zero(), )), ); diff --git a/execution_engine_testing/tests/src/test/regression/ee_597.rs b/execution_engine_testing/tests/src/test/regression/ee_597.rs index 7e79cd81b9..0d59bfcd09 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_597.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_597.rs @@ -23,11 +23,8 @@ const VALID_BALANCE: u64 = MINIMUM_ACCOUNT_CREATION_BALANCE; fn should_fail_when_bonding_amount_is_zero_ee_597_regression() { let accounts = { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); - let account = GenesisAccount::account( - VALID_PUBLIC_KEY.clone(), - Motes::new(VALID_BALANCE.into()), - None, - ); + let account = + GenesisAccount::account(VALID_PUBLIC_KEY.clone(), Motes::new(VALID_BALANCE), None); tmp.push(account); tmp }; diff --git a/execution_engine_testing/tests/src/test/regression/ee_598.rs b/execution_engine_testing/tests/src/test/regression/ee_598.rs index c8b414692b..53d1a54234 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_598.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_598.rs @@ -38,9 +38,9 @@ fn should_handle_unbond_for_more_than_stake_as_full_unbond_of_stake_ee_598_regre let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account = GenesisAccount::account( public_key, - Motes::new(GENESIS_VALIDATOR_STAKE.into()) * Motes::new(2.into()), + Motes::new(GENESIS_VALIDATOR_STAKE) * Motes::new(2), Some(GenesisValidator::new( - Motes::new(GENESIS_VALIDATOR_STAKE.into()), + Motes::new(GENESIS_VALIDATOR_STAKE), DelegationRate::zero(), )), ); diff --git a/execution_engine_testing/tests/src/test/regression/gh_3208.rs b/execution_engine_testing/tests/src/test/regression/gh_3208.rs index 1e6b9973bf..cce1df0315 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_3208.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_3208.rs @@ -32,12 +32,12 @@ static ACCOUNTS_WITH_GENESIS_VALIDATORS: Lazy> = Lazy::new(| vec![ GenesisAccount::account( DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), None, ), GenesisAccount::account( DEFAULT_PROPOSER_PUBLIC_KEY.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), Some(GenesisValidator::new( Motes::new(*DEFAULT_PROPOSER_ACCOUNT_INITIAL_STAKE), 15, diff --git a/execution_engine_testing/tests/src/test/regression/gov_116.rs b/execution_engine_testing/tests/src/test/regression/gov_116.rs index c46ae5e674..563215ec35 100644 --- a/execution_engine_testing/tests/src/test/regression/gov_116.rs +++ b/execution_engine_testing/tests/src/test/regression/gov_116.rs @@ -60,9 +60,9 @@ static GENESIS_VALIDATORS: Lazy> = Lazy::new(|| { for (index, public_key) in GENESIS_VALIDATOR_PUBLIC_KEYS.iter().enumerate() { let account = GenesisAccount::account( public_key.clone(), - Motes::new(U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE)), + Motes::new(MINIMUM_ACCOUNT_CREATION_BALANCE), Some(GenesisValidator::new( - Motes::new(U512::from(index + 1) * 1_000), + Motes::new((index + 1) * 1_000), DelegationRate::zero(), )), ); @@ -86,7 +86,7 @@ static LOWEST_STAKE_VALIDATOR: Lazy = Lazy::new(|| { assert_eq!( genesis_account.staked_amount(), - Motes::new(U512::from(MINIMUM_BONDED_AMOUNT)) + Motes::new(MINIMUM_BONDED_AMOUNT) ); genesis_account.public_key() diff --git a/execution_engine_testing/tests/src/test/regression/gov_89_regression.rs b/execution_engine_testing/tests/src/test/regression/gov_89_regression.rs index 298255662a..e5a9c40aac 100644 --- a/execution_engine_testing/tests/src/test/regression/gov_89_regression.rs +++ b/execution_engine_testing/tests/src/test/regression/gov_89_regression.rs @@ -41,17 +41,17 @@ fn initialize_builder() -> LmdbWasmTestBuilder { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( ACCOUNT_1_PUBLIC_KEY.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), + Motes::new(ACCOUNT_1_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_1_BOND.into()), + Motes::new(ACCOUNT_1_BOND), DelegationRate::zero(), )), ); let account_2 = GenesisAccount::account( ACCOUNT_2_PUBLIC_KEY.clone(), - Motes::new(ACCOUNT_2_BALANCE.into()), + Motes::new(ACCOUNT_2_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_2_BOND.into()), + Motes::new(ACCOUNT_2_BOND), DelegationRate::zero(), )), ); diff --git a/execution_engine_testing/tests/src/test/step.rs b/execution_engine_testing/tests/src/test/step.rs index 0a286ead52..82cc1730af 100644 --- a/execution_engine_testing/tests/src/test/step.rs +++ b/execution_engine_testing/tests/src/test/step.rs @@ -47,17 +47,17 @@ fn initialize_builder() -> LmdbWasmTestBuilder { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( ACCOUNT_1_PK.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), + Motes::new(ACCOUNT_1_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_1_BOND.into()), + Motes::new(ACCOUNT_1_BOND), DelegationRate::zero(), )), ); let account_2 = GenesisAccount::account( ACCOUNT_2_PK.clone(), - Motes::new(ACCOUNT_2_BALANCE.into()), + Motes::new(ACCOUNT_2_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_2_BOND.into()), + Motes::new(ACCOUNT_2_BOND), DelegationRate::zero(), )), ); diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs b/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs index eb31decaf1..58731bf5e7 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs @@ -162,7 +162,7 @@ fn should_add_new_bid() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( BID_ACCOUNT_1_PK.clone(), - Motes::new(BID_ACCOUNT_1_BALANCE.into()), + Motes::new(BID_ACCOUNT_1_BALANCE), None, ); tmp.push(account_1); @@ -206,7 +206,7 @@ fn should_increase_existing_bid() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( BID_ACCOUNT_1_PK.clone(), - Motes::new(BID_ACCOUNT_1_BALANCE.into()), + Motes::new(BID_ACCOUNT_1_BALANCE), None, ); tmp.push(account_1); @@ -265,7 +265,7 @@ fn should_decrease_existing_bid() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( BID_ACCOUNT_1_PK.clone(), - Motes::new(BID_ACCOUNT_1_BALANCE.into()), + Motes::new(BID_ACCOUNT_1_BALANCE), None, ); tmp.push(account_1); @@ -333,7 +333,7 @@ fn should_run_delegate_and_undelegate() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( BID_ACCOUNT_1_PK.clone(), - Motes::new(BID_ACCOUNT_1_BALANCE.into()), + Motes::new(BID_ACCOUNT_1_BALANCE), None, ); tmp.push(account_1); @@ -512,23 +512,23 @@ fn should_calculate_era_validators() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( ACCOUNT_1_PK.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), + Motes::new(ACCOUNT_1_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_1_BOND.into()), + Motes::new(ACCOUNT_1_BOND), DelegationRate::zero(), )), ); let account_2 = GenesisAccount::account( ACCOUNT_2_PK.clone(), - Motes::new(ACCOUNT_2_BALANCE.into()), + Motes::new(ACCOUNT_2_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_2_BOND.into()), + Motes::new(ACCOUNT_2_BOND), DelegationRate::zero(), )), ); let account_3 = GenesisAccount::account( BID_ACCOUNT_1_PK.clone(), - Motes::new(BID_ACCOUNT_1_BALANCE.into()), + Motes::new(BID_ACCOUNT_1_BALANCE), None, ); tmp.push(account_1); @@ -677,17 +677,17 @@ fn should_get_first_seigniorage_recipients() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( ACCOUNT_1_PK.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), + Motes::new(ACCOUNT_1_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_1_BOND.into()), + Motes::new(ACCOUNT_1_BOND), DelegationRate::zero(), )), ); let account_2 = GenesisAccount::account( ACCOUNT_2_PK.clone(), - Motes::new(ACCOUNT_2_BALANCE.into()), + Motes::new(ACCOUNT_2_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_2_BOND.into()), + Motes::new(ACCOUNT_2_BOND), DelegationRate::zero(), )), ); @@ -851,9 +851,9 @@ fn should_release_founder_stake() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( ACCOUNT_1_PK.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), + Motes::new(ACCOUNT_1_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_1_BOND.into()), + Motes::new(ACCOUNT_1_BOND), DelegationRate::zero(), )), ); @@ -998,9 +998,9 @@ fn should_fail_to_get_era_validators() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( ACCOUNT_1_PK.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), + Motes::new(ACCOUNT_1_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_1_BOND.into()), + Motes::new(ACCOUNT_1_BOND), DelegationRate::zero(), )), ); @@ -1026,9 +1026,9 @@ fn should_fail_to_get_era_validators() { fn should_use_era_validators_endpoint_for_first_era() { let extra_accounts = vec![GenesisAccount::account( ACCOUNT_1_PK.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), + Motes::new(ACCOUNT_1_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_1_BOND.into()), + Motes::new(ACCOUNT_1_BOND), DelegationRate::zero(), )), )]; @@ -1066,28 +1066,28 @@ fn should_calculate_era_validators_multiple_new_bids() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( ACCOUNT_1_PK.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), + Motes::new(ACCOUNT_1_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_1_BOND.into()), + Motes::new(ACCOUNT_1_BOND), DelegationRate::zero(), )), ); let account_2 = GenesisAccount::account( ACCOUNT_2_PK.clone(), - Motes::new(ACCOUNT_2_BALANCE.into()), + Motes::new(ACCOUNT_2_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_2_BOND.into()), + Motes::new(ACCOUNT_2_BOND), DelegationRate::zero(), )), ); let account_3 = GenesisAccount::account( BID_ACCOUNT_1_PK.clone(), - Motes::new(BID_ACCOUNT_1_BALANCE.into()), + Motes::new(BID_ACCOUNT_1_BALANCE), None, ); let account_4 = GenesisAccount::account( BID_ACCOUNT_2_PK.clone(), - Motes::new(BID_ACCOUNT_2_BALANCE.into()), + Motes::new(BID_ACCOUNT_2_BALANCE), None, ); tmp.push(account_1); @@ -1920,33 +1920,33 @@ fn should_handle_evictions() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( ACCOUNT_1_PK.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), + Motes::new(ACCOUNT_1_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_1_BOND.into()), + Motes::new(ACCOUNT_1_BOND), DelegationRate::zero(), )), ); let account_2 = GenesisAccount::account( ACCOUNT_2_PK.clone(), - Motes::new(ACCOUNT_2_BALANCE.into()), + Motes::new(ACCOUNT_2_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_2_BOND.into()), + Motes::new(ACCOUNT_2_BOND), DelegationRate::zero(), )), ); let account_3 = GenesisAccount::account( BID_ACCOUNT_1_PK.clone(), - Motes::new(BID_ACCOUNT_1_BALANCE.into()), + Motes::new(BID_ACCOUNT_1_BALANCE), Some(GenesisValidator::new( - Motes::new(300_000.into()), + Motes::new(300_000), DelegationRate::zero(), )), ); let account_4 = GenesisAccount::account( BID_ACCOUNT_2_PK.clone(), - Motes::new(BID_ACCOUNT_2_BALANCE.into()), + Motes::new(BID_ACCOUNT_2_BALANCE), Some(GenesisValidator::new( - Motes::new(400_000.into()), + Motes::new(400_000), DelegationRate::zero(), )), ); @@ -2079,31 +2079,31 @@ fn should_validate_orphaned_genesis_delegators() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( ACCOUNT_1_PK.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), + Motes::new(ACCOUNT_1_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_1_BOND.into()), + Motes::new(ACCOUNT_1_BOND), DelegationRate::zero(), )), ); let account_2 = GenesisAccount::account( ACCOUNT_2_PK.clone(), - Motes::new(ACCOUNT_2_BALANCE.into()), + Motes::new(ACCOUNT_2_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_2_BOND.into()), + Motes::new(ACCOUNT_2_BOND), DelegationRate::zero(), )), ); let delegator_1 = GenesisAccount::delegator( ACCOUNT_1_PK.clone(), DELEGATOR_1.clone(), - Motes::new(DELEGATOR_1_BALANCE.into()), - Motes::new(DELEGATOR_1_STAKE.into()), + Motes::new(DELEGATOR_1_BALANCE), + Motes::new(DELEGATOR_1_STAKE), ); let orphaned_delegator = GenesisAccount::delegator( missing_validator, DELEGATOR_1.clone(), - Motes::new(DELEGATOR_1_BALANCE.into()), - Motes::new(DELEGATOR_1_STAKE.into()), + Motes::new(DELEGATOR_1_BALANCE), + Motes::new(DELEGATOR_1_STAKE), ); tmp.push(account_1); tmp.push(account_2); @@ -2127,37 +2127,37 @@ fn should_validate_duplicated_genesis_delegators() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( ACCOUNT_1_PK.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), + Motes::new(ACCOUNT_1_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_1_BOND.into()), + Motes::new(ACCOUNT_1_BOND), DelegationRate::zero(), )), ); let account_2 = GenesisAccount::account( ACCOUNT_2_PK.clone(), - Motes::new(ACCOUNT_2_BALANCE.into()), + Motes::new(ACCOUNT_2_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_2_BOND.into()), + Motes::new(ACCOUNT_2_BOND), DelegationRate::zero(), )), ); let delegator_1 = GenesisAccount::delegator( ACCOUNT_1_PK.clone(), DELEGATOR_1.clone(), - Motes::new(DELEGATOR_1_BALANCE.into()), - Motes::new(DELEGATOR_1_STAKE.into()), + Motes::new(DELEGATOR_1_BALANCE), + Motes::new(DELEGATOR_1_STAKE), ); let duplicated_delegator_1 = GenesisAccount::delegator( ACCOUNT_1_PK.clone(), DELEGATOR_1.clone(), - Motes::new(DELEGATOR_1_BALANCE.into()), - Motes::new(DELEGATOR_1_STAKE.into()), + Motes::new(DELEGATOR_1_BALANCE), + Motes::new(DELEGATOR_1_STAKE), ); let duplicated_delegator_2 = GenesisAccount::delegator( ACCOUNT_1_PK.clone(), DELEGATOR_2.clone(), - Motes::new(DELEGATOR_2_BALANCE.into()), - Motes::new(DELEGATOR_2_STAKE.into()), + Motes::new(DELEGATOR_2_BALANCE), + Motes::new(DELEGATOR_2_STAKE), ); tmp.push(account_1); tmp.push(account_2); @@ -2182,9 +2182,9 @@ fn should_validate_delegation_rate_of_genesis_validator() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( ACCOUNT_1_PK.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), + Motes::new(ACCOUNT_1_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_1_BOND.into()), + Motes::new(ACCOUNT_1_BOND), DelegationRate::max_value(), )), ); @@ -2207,7 +2207,7 @@ fn should_validate_bond_amount_of_genesis_validator() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( ACCOUNT_1_PK.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), + Motes::new(ACCOUNT_1_BALANCE), Some(GenesisValidator::new(Motes::zero(), DelegationRate::zero())), ); tmp.push(account_1); @@ -2228,22 +2228,22 @@ fn should_setup_genesis_delegators() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( ACCOUNT_1_PK.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), - Some(GenesisValidator::new(Motes::new(ACCOUNT_1_BOND.into()), 80)), + Motes::new(ACCOUNT_1_BALANCE), + Some(GenesisValidator::new(Motes::new(ACCOUNT_1_BOND), 80)), ); let account_2 = GenesisAccount::account( ACCOUNT_2_PK.clone(), - Motes::new(ACCOUNT_2_BALANCE.into()), + Motes::new(ACCOUNT_2_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_2_BOND.into()), + Motes::new(ACCOUNT_2_BOND), DelegationRate::zero(), )), ); let delegator_1 = GenesisAccount::delegator( ACCOUNT_1_PK.clone(), DELEGATOR_1.clone(), - Motes::new(DELEGATOR_1_BALANCE.into()), - Motes::new(DELEGATOR_1_STAKE.into()), + Motes::new(DELEGATOR_1_BALANCE), + Motes::new(DELEGATOR_1_STAKE), ); tmp.push(account_1); tmp.push(account_2); @@ -2304,17 +2304,17 @@ fn should_not_partially_undelegate_uninitialized_vesting_schedule() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let validator_1 = GenesisAccount::account( VALIDATOR_1.clone(), - Motes::new(VALIDATOR_1_STAKE.into()), + Motes::new(VALIDATOR_1_STAKE), Some(GenesisValidator::new( - Motes::new(VALIDATOR_1_STAKE.into()), + Motes::new(VALIDATOR_1_STAKE), DelegationRate::zero(), )), ); let delegator_1 = GenesisAccount::delegator( VALIDATOR_1.clone(), DELEGATOR_1.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), - Motes::new(DELEGATOR_1_STAKE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), + Motes::new(DELEGATOR_1_STAKE), ); tmp.push(validator_1); tmp.push(delegator_1); @@ -2374,17 +2374,17 @@ fn should_not_fully_undelegate_uninitialized_vesting_schedule() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let validator_1 = GenesisAccount::account( VALIDATOR_1.clone(), - Motes::new(VALIDATOR_1_STAKE.into()), + Motes::new(VALIDATOR_1_STAKE), Some(GenesisValidator::new( - Motes::new(VALIDATOR_1_STAKE.into()), + Motes::new(VALIDATOR_1_STAKE), DelegationRate::zero(), )), ); let delegator_1 = GenesisAccount::delegator( VALIDATOR_1.clone(), DELEGATOR_1.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), - Motes::new(DELEGATOR_1_STAKE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), + Motes::new(DELEGATOR_1_STAKE), ); tmp.push(validator_1); tmp.push(delegator_1); @@ -2444,17 +2444,17 @@ fn should_not_undelegate_vfta_holder_stake() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let validator_1 = GenesisAccount::account( VALIDATOR_1.clone(), - Motes::new(VALIDATOR_1_STAKE.into()), + Motes::new(VALIDATOR_1_STAKE), Some(GenesisValidator::new( - Motes::new(VALIDATOR_1_STAKE.into()), + Motes::new(VALIDATOR_1_STAKE), DelegationRate::zero(), )), ); let delegator_1 = GenesisAccount::delegator( VALIDATOR_1.clone(), DELEGATOR_1.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), - Motes::new(DELEGATOR_1_STAKE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), + Motes::new(DELEGATOR_1_STAKE), ); tmp.push(validator_1); tmp.push(delegator_1); @@ -2634,17 +2634,17 @@ fn should_release_vfta_holder_stake() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( ACCOUNT_1_PK.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), + Motes::new(ACCOUNT_1_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_1_BOND.into()), + Motes::new(ACCOUNT_1_BOND), DelegationRate::zero(), )), ); let delegator_1 = GenesisAccount::delegator( ACCOUNT_1_PK.clone(), DELEGATOR_1.clone(), - Motes::new(DELEGATOR_1_BALANCE.into()), - Motes::new(DELEGATOR_VFTA_STAKE.into()), + Motes::new(DELEGATOR_1_BALANCE), + Motes::new(DELEGATOR_VFTA_STAKE), ); tmp.push(account_1); tmp.push(delegator_1); @@ -3063,22 +3063,22 @@ fn should_validate_genesis_delegators_bond_amount() { let mut tmp: Vec = DEFAULT_ACCOUNTS.clone(); let account_1 = GenesisAccount::account( ACCOUNT_1_PK.clone(), - Motes::new(ACCOUNT_1_BALANCE.into()), - Some(GenesisValidator::new(Motes::new(ACCOUNT_1_BOND.into()), 80)), + Motes::new(ACCOUNT_1_BALANCE), + Some(GenesisValidator::new(Motes::new(ACCOUNT_1_BOND), 80)), ); let account_2 = GenesisAccount::account( ACCOUNT_2_PK.clone(), - Motes::new(ACCOUNT_2_BALANCE.into()), + Motes::new(ACCOUNT_2_BALANCE), Some(GenesisValidator::new( - Motes::new(ACCOUNT_2_BOND.into()), + Motes::new(ACCOUNT_2_BOND), DelegationRate::zero(), )), ); let delegator_1 = GenesisAccount::delegator( ACCOUNT_1_PK.clone(), DELEGATOR_1.clone(), - Motes::new(DELEGATOR_1_BALANCE.into()), - Motes::new(U512::zero()), + Motes::new(DELEGATOR_1_BALANCE), + Motes::zero(), ); tmp.push(account_1); tmp.push(account_2); @@ -3110,8 +3110,8 @@ fn check_validator_slots_for_accounts(accounts: usize) { let account = GenesisAccount::account( public_key, - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), - Some(GenesisValidator::new(Motes::new(ACCOUNT_1_BOND.into()), 80)), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), + Some(GenesisValidator::new(Motes::new(ACCOUNT_1_BOND), 80)), ); tmp.push(account) diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs b/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs index 4feb05e03f..db0fc7123b 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs @@ -310,7 +310,7 @@ fn should_fail_unbonding_validator_with_locked_funds() { account_1_public_key.clone(), Motes::new(account_1_balance), Some(GenesisValidator::new( - Motes::new(GENESIS_VALIDATOR_STAKE.into()), + Motes::new(GENESIS_VALIDATOR_STAKE), DelegationRate::zero(), )), ); diff --git a/execution_engine_testing/tests/src/test/system_contracts/genesis.rs b/execution_engine_testing/tests/src/test/system_contracts/genesis.rs index b3d80d3554..a2ee423ec5 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/genesis.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/genesis.rs @@ -34,8 +34,8 @@ static ACCOUNT_2_ADDR: Lazy = Lazy::new(|| AccountHash::from(&*ACCO static GENESIS_CUSTOM_ACCOUNTS: Lazy> = Lazy::new(|| { let account_1 = { - let account_1_balance = Motes::new(ACCOUNT_1_BALANCE.into()); - let account_1_bonded_amount = Motes::new(ACCOUNT_1_BONDED_AMOUNT.into()); + let account_1_balance = Motes::new(ACCOUNT_1_BALANCE); + let account_1_bonded_amount = Motes::new(ACCOUNT_1_BONDED_AMOUNT); GenesisAccount::account( ACCOUNT_1_PUBLIC_KEY.clone(), account_1_balance, @@ -46,8 +46,8 @@ static GENESIS_CUSTOM_ACCOUNTS: Lazy> = Lazy::new(|| { ) }; let account_2 = { - let account_2_balance = Motes::new(ACCOUNT_2_BALANCE.into()); - let account_2_bonded_amount = Motes::new(ACCOUNT_2_BONDED_AMOUNT.into()); + let account_2_balance = Motes::new(ACCOUNT_2_BALANCE); + let account_2_bonded_amount = Motes::new(ACCOUNT_2_BONDED_AMOUNT); GenesisAccount::account( ACCOUNT_2_PUBLIC_KEY.clone(), account_2_balance, diff --git a/execution_engine_testing/tests/src/test/system_costs.rs b/execution_engine_testing/tests/src/test/system_costs.rs index 516005bc24..dd8f157f45 100644 --- a/execution_engine_testing/tests/src/test/system_costs.rs +++ b/execution_engine_testing/tests/src/test/system_costs.rs @@ -257,17 +257,17 @@ fn delegate_and_undelegate_have_expected_costs() { let accounts = { let validator_1 = GenesisAccount::account( VALIDATOR_1.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), Some(GenesisValidator::new( - Motes::new(VALIDATOR_1_STAKE.into()), + Motes::new(VALIDATOR_1_STAKE), DelegationRate::zero(), )), ); let validator_2 = GenesisAccount::account( VALIDATOR_2.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), Some(GenesisValidator::new( - Motes::new(VALIDATOR_1_STAKE.into()), + Motes::new(VALIDATOR_1_STAKE), DelegationRate::zero(), )), ); @@ -401,17 +401,17 @@ fn upgraded_delegate_and_undelegate_have_expected_costs() { let accounts = { let validator_1 = GenesisAccount::account( VALIDATOR_1.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), Some(GenesisValidator::new( - Motes::new(VALIDATOR_1_STAKE.into()), + Motes::new(VALIDATOR_1_STAKE), DelegationRate::zero(), )), ); let validator_2 = GenesisAccount::account( VALIDATOR_2.clone(), - Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE), Some(GenesisValidator::new( - Motes::new(VALIDATOR_1_STAKE.into()), + Motes::new(VALIDATOR_1_STAKE), DelegationRate::zero(), )), ); diff --git a/node/src/components/consensus/tests/utils.rs b/node/src/components/consensus/tests/utils.rs index 9c29ab9815..615bdd24f8 100644 --- a/node/src/components/consensus/tests/utils.rs +++ b/node/src/components/consensus/tests/utils.rs @@ -57,7 +57,7 @@ where let accounts = stakes .into_iter() .map(|(pk, stake)| { - let motes = Motes::new(stake.into()); + let motes = Motes::new(stake); let validator_config = ValidatorConfig::new(motes, DelegationRate::zero()); AccountConfig::new(pk, motes, Some(validator_config)) }) diff --git a/node/src/utils/chain_specification.rs b/node/src/utils/chain_specification.rs index cc739e08a8..7c8b1ee073 100644 --- a/node/src/utils/chain_specification.rs +++ b/node/src/utils/chain_specification.rs @@ -152,7 +152,7 @@ mod tests { bytesrepr::FromBytes, ActivationPoint, BrTableCost, ChainspecRawBytes, ControlFlowCosts, CoreConfig, EraId, GlobalStateUpdate, HighwayConfig, HostFunction, HostFunctionCosts, MessageLimits, Motes, OpcodeCosts, ProtocolConfig, ProtocolVersion, StorageCosts, - StoredValue, TestBlockBuilder, TimeDiff, Timestamp, TransactionConfig, WasmConfig, U512, + StoredValue, TestBlockBuilder, TimeDiff, Timestamp, TransactionConfig, WasmConfig, }; use super::*; @@ -562,10 +562,10 @@ mod tests { }; for (index, account_config) in accounts.into_iter().enumerate() { - assert_eq!(account_config.balance(), Motes::new(U512::from(index + 1)),); + assert_eq!(account_config.balance(), Motes::new(index + 1),); assert_eq!( account_config.bonded_amount(), - Motes::new(U512::from((index as u64 + 1) * 10)) + Motes::new((index as u64 + 1) * 10) ); } } else { @@ -616,7 +616,7 @@ mod tests { assert_eq!( spec.transaction_config.deploy_config.max_payment_cost, - Motes::new(U512::from(9)) + Motes::new(9) ); assert_eq!( spec.transaction_config.max_ttl, diff --git a/storage/src/system/genesis.rs b/storage/src/system/genesis.rs index b057ee464c..727f5d3396 100644 --- a/storage/src/system/genesis.rs +++ b/storage/src/system/genesis.rs @@ -901,13 +901,12 @@ mod tests { let secret_key = SecretKey::ed25519_from_bytes(bytes).unwrap(); let public_key: PublicKey = PublicKey::from(&secret_key); - let genesis_account_1 = - GenesisAccount::account(public_key.clone(), Motes::new(U512::from(100)), None); + let genesis_account_1 = GenesisAccount::account(public_key.clone(), Motes::new(100), None); bytesrepr::test_serialization_roundtrip(&genesis_account_1); let genesis_account_2 = - GenesisAccount::account(public_key, Motes::new(U512::from(100)), Some(rng.gen())); + GenesisAccount::account(public_key, Motes::new(100), Some(rng.gen())); bytesrepr::test_serialization_roundtrip(&genesis_account_2); } @@ -928,7 +927,7 @@ mod tests { let genesis_account = GenesisAccount::delegator( validator_public_key, delegator_public_key, - Motes::new(U512::from(100)), + Motes::new(100), Motes::zero(), ); diff --git a/storage/src/tracking_copy/ext.rs b/storage/src/tracking_copy/ext.rs index 66f39a6e0a..9bc2e5d6ca 100644 --- a/storage/src/tracking_copy/ext.rs +++ b/storage/src/tracking_copy/ext.rs @@ -4,7 +4,7 @@ use crate::global_state::{error::Error as GlobalStateError, state::StateReader}; use casper_types::{ account::AccountHash, addressable_entity::NamedKeys, global_state::TrieMerkleProof, ByteCode, ByteCodeAddr, ByteCodeHash, CLValue, ChecksumRegistry, EntityAddr, Key, KeyTag, Motes, Package, - PackageHash, StoredValue, StoredValueTypeMismatch, SystemEntityRegistry, URef, + PackageHash, StoredValue, StoredValueTypeMismatch, SystemEntityRegistry, URef, U512, }; use crate::tracking_copy::{TrackingCopy, TrackingCopyError}; @@ -82,7 +82,7 @@ where let cl_value: CLValue = stored_value .try_into() .map_err(TrackingCopyError::TypeMismatch)?; - let balance = Motes::new(cl_value.into_t()?); + let balance = Motes::new(cl_value.into_t::()?); Ok(balance) } @@ -117,7 +117,7 @@ where .to_owned() .try_into() .map_err(TrackingCopyError::TypeMismatch)?; - let balance = Motes::new(cl_value.into_t()?); + let balance = Motes::new(cl_value.into_t::()?); Ok((balance, proof)) } diff --git a/types/src/chainspec/accounts_config.rs b/types/src/chainspec/accounts_config.rs index 1b820eb5ff..e5e3fb278a 100644 --- a/types/src/chainspec/accounts_config.rs +++ b/types/src/chainspec/accounts_config.rs @@ -102,7 +102,7 @@ impl AccountsConfig { pub fn random(rng: &mut TestRng) -> Self { use rand::Rng; - use crate::{Motes, U512}; + use crate::Motes; let alpha = AccountConfig::random(rng); let accounts = vec![ @@ -120,7 +120,7 @@ impl AccountsConfig { let admin_balance: u32 = rng.gen(); let administrators = vec![AdministratorAccount::new( PublicKey::random(rng), - Motes::new(U512::from(admin_balance)), + Motes::new(admin_balance), )]; AccountsConfig { diff --git a/types/src/chainspec/accounts_config/account_config.rs b/types/src/chainspec/accounts_config/account_config.rs index 7c998d355c..b64cb97efb 100644 --- a/types/src/chainspec/accounts_config/account_config.rs +++ b/types/src/chainspec/accounts_config/account_config.rs @@ -1,6 +1,5 @@ #[cfg(feature = "datasize")] use datasize::DataSize; -use num::Zero; #[cfg(any(feature = "testing", test))] use rand::{distributions::Standard, prelude::*}; @@ -69,7 +68,7 @@ impl AccountConfig { pub fn random(rng: &mut TestRng) -> Self { let public_key = PublicKey::from(&SecretKey::ed25519_from_bytes(rng.gen::<[u8; 32]>()).unwrap()); - let balance = Motes::new(rng.gen()); + let balance = Motes::new(rng.gen::()); let validator = rng.gen(); AccountConfig { diff --git a/types/src/chainspec/accounts_config/delegator_config.rs b/types/src/chainspec/accounts_config/delegator_config.rs index b91422b5c1..f6fa63afc3 100644 --- a/types/src/chainspec/accounts_config/delegator_config.rs +++ b/types/src/chainspec/accounts_config/delegator_config.rs @@ -50,8 +50,8 @@ impl DelegatorConfig { PublicKey::from(&SecretKey::ed25519_from_bytes(rng.gen::<[u8; 32]>()).unwrap()); let delegator_public_key = PublicKey::from(&SecretKey::ed25519_from_bytes(rng.gen::<[u8; 32]>()).unwrap()); - let balance = Motes::new(U512::from(rng.gen::())); - let delegated_amount = Motes::new(U512::from(rng.gen::())); + let balance = Motes::new(rng.gen::()); + let delegated_amount = Motes::new(rng.gen::()); DelegatorConfig { validator_public_key, diff --git a/types/src/chainspec/accounts_config/genesis.rs b/types/src/chainspec/accounts_config/genesis.rs index dae8d3fe18..8691578f93 100644 --- a/types/src/chainspec/accounts_config/genesis.rs +++ b/types/src/chainspec/accounts_config/genesis.rs @@ -1,6 +1,5 @@ #[cfg(feature = "datasize")] use datasize::DataSize; -use num_traits::Zero; #[cfg(any(feature = "testing", test))] use rand::{ distributions::{Distribution, Standard}, @@ -86,7 +85,7 @@ impl GenesisValidator { #[cfg(any(feature = "testing", test))] impl Distribution for Standard { fn sample(&self, rng: &mut R) -> GenesisValidator { - let bonded_amount = Motes::new(rng.gen()); + let bonded_amount = Motes::new(rng.gen::()); let delegation_rate = rng.gen(); GenesisValidator::new(bonded_amount, delegation_rate) @@ -386,7 +385,7 @@ impl Distribution for Standard { rng.fill_bytes(&mut bytes[..]); let secret_key = SecretKey::ed25519_from_bytes(bytes).unwrap(); let public_key = PublicKey::from(&secret_key); - let balance = Motes::new(rng.gen()); + let balance = Motes::new(rng.gen::()); let validator = rng.gen(); GenesisAccount::account(public_key, balance, validator) @@ -419,8 +418,8 @@ impl ToBytes for GenesisAccount { buffer.push(GenesisAccountTag::Delegator as u8); buffer.extend(validator_public_key.to_bytes()?); buffer.extend(delegator_public_key.to_bytes()?); - buffer.extend(balance.value().to_bytes()?); - buffer.extend(delegated_amount.value().to_bytes()?); + buffer.extend(balance.to_bytes()?); + buffer.extend(delegated_amount.to_bytes()?); } GenesisAccount::Administrator(administrator_account) => { buffer.push(GenesisAccountTag::Administrator as u8); @@ -486,7 +485,7 @@ impl FromBytes for GenesisAccount { validator_public_key, delegator_public_key, balance, - Motes::new(delegated_amount_value), + delegated_amount_value, ); Ok((genesis_account, remainder)) } diff --git a/types/src/chainspec/accounts_config/validator_config.rs b/types/src/chainspec/accounts_config/validator_config.rs index 588faa49ee..6b308b7c37 100644 --- a/types/src/chainspec/accounts_config/validator_config.rs +++ b/types/src/chainspec/accounts_config/validator_config.rs @@ -44,7 +44,7 @@ impl ValidatorConfig { /// Returns a random `ValidatorConfig`. #[cfg(any(feature = "testing", test))] pub fn random(rng: &mut TestRng) -> Self { - let bonded_amount = Motes::new(U512::from(rng.gen::())); + let bonded_amount = Motes::new(rng.gen::()); let delegation_rate = rng.gen(); ValidatorConfig { diff --git a/types/src/chainspec/transaction_config/deploy_config.rs b/types/src/chainspec/transaction_config/deploy_config.rs index 7d5757c8ab..b1aeadcfdc 100644 --- a/types/src/chainspec/transaction_config/deploy_config.rs +++ b/types/src/chainspec/transaction_config/deploy_config.rs @@ -11,9 +11,6 @@ use crate::{ Motes, }; -#[cfg(any(feature = "std", test))] -use crate::U512; - /// The default maximum number of motes that payment code execution can cost. pub const DEFAULT_MAX_PAYMENT_MOTES: u64 = 2_500_000_000; @@ -37,7 +34,7 @@ pub struct DeployConfig { impl DeployConfig { /// Generates a random instance using a `TestRng`. pub fn random(rng: &mut TestRng) -> Self { - let max_payment_cost = Motes::new(U512::from(rng.gen_range(1_000_000..1_000_000_000))); + let max_payment_cost = Motes::new(rng.gen_range(1_000_000..1_000_000_000)); let max_dependencies = 0; let payment_args_max_length = rng.gen(); let session_args_max_length = rng.gen(); @@ -55,7 +52,7 @@ impl DeployConfig { impl Default for DeployConfig { fn default() -> Self { DeployConfig { - max_payment_cost: Motes::new(U512::from(DEFAULT_MAX_PAYMENT_MOTES)), + max_payment_cost: Motes::new(DEFAULT_MAX_PAYMENT_MOTES), max_dependencies: 0, payment_args_max_length: 1024, session_args_max_length: 1024, diff --git a/types/src/gas.rs b/types/src/gas.rs index 508102d1e0..63bbb8d1ca 100644 --- a/types/src/gas.rs +++ b/types/src/gas.rs @@ -259,7 +259,7 @@ mod tests { #[test] fn should_support_checked_div_from_motes() { - let motes = Motes::new(U512::zero()); + let motes = Motes::zero(); let conv_rate = 0; let maybe = Gas::from_motes(motes, conv_rate); assert!(maybe.is_none(), "should be none due to divide by zero"); diff --git a/types/src/motes.rs b/types/src/motes.rs index 8008a81c61..0a70d10668 100644 --- a/types/src/motes.rs +++ b/types/src/motes.rs @@ -24,8 +24,13 @@ pub struct Motes(U512); impl Motes { /// Constructs a new `Motes`. - pub fn new(value: U512) -> Motes { - Motes(value) + pub fn new>(value: T) -> Self { + Motes(value.into()) + } + + /// Constructs a new `Motes` with value `0`. + pub const fn zero() -> Self { + Motes(U512::zero()) } /// Checked integer addition. Computes `self + rhs`, returning `None` if overflow occurred. @@ -97,7 +102,7 @@ impl Mul for Motes { impl Zero for Motes { fn zero() -> Self { - Motes::new(U512::zero()) + Motes::zero() } fn is_zero(&self) -> bool { @@ -124,7 +129,7 @@ impl ToBytes for Motes { impl FromBytes for Motes { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { let (value, remainder) = FromBytes::from_bytes(bytes)?; - Ok((Motes::new(value), remainder)) + Ok((Motes(value), remainder)) } } @@ -137,7 +142,7 @@ mod tests { #[test] fn should_be_able_to_get_instance_of_motes() { let initial_value = 1; - let motes = Motes::new(U512::from(initial_value)); + let motes = Motes::new(initial_value); assert_eq!( initial_value, motes.value().as_u64(), @@ -147,18 +152,18 @@ mod tests { #[test] fn should_be_able_to_compare_two_instances_of_motes() { - let left_motes = Motes::new(U512::from(1)); - let right_motes = Motes::new(U512::from(1)); + let left_motes = Motes::new(1); + let right_motes = Motes::new(1); assert_eq!(left_motes, right_motes, "should be equal"); - let right_motes = Motes::new(U512::from(2)); + let right_motes = Motes::new(2); assert_ne!(left_motes, right_motes, "should not be equal") } #[test] fn should_be_able_to_add_two_instances_of_motes() { - let left_motes = Motes::new(U512::from(1)); - let right_motes = Motes::new(U512::from(1)); - let expected_motes = Motes::new(U512::from(2)); + let left_motes = Motes::new(1); + let right_motes = Motes::new(1); + let expected_motes = Motes::new(2); assert_eq!( (left_motes + right_motes), expected_motes, @@ -168,9 +173,9 @@ mod tests { #[test] fn should_be_able_to_subtract_two_instances_of_motes() { - let left_motes = Motes::new(U512::from(1)); - let right_motes = Motes::new(U512::from(1)); - let expected_motes = Motes::new(U512::from(0)); + let left_motes = Motes::new(1); + let right_motes = Motes::new(1); + let expected_motes = Motes::new(0); assert_eq!( (left_motes - right_motes), expected_motes, @@ -180,9 +185,9 @@ mod tests { #[test] fn should_be_able_to_multiply_two_instances_of_motes() { - let left_motes = Motes::new(U512::from(100)); - let right_motes = Motes::new(U512::from(10)); - let expected_motes = Motes::new(U512::from(1000)); + let left_motes = Motes::new(100); + let right_motes = Motes::new(10); + let expected_motes = Motes::new(1000); assert_eq!( (left_motes * right_motes), expected_motes, @@ -192,9 +197,9 @@ mod tests { #[test] fn should_be_able_to_divide_two_instances_of_motes() { - let left_motes = Motes::new(U512::from(1000)); - let right_motes = Motes::new(U512::from(100)); - let expected_motes = Motes::new(U512::from(10)); + let left_motes = Motes::new(1000); + let right_motes = Motes::new(100); + let expected_motes = Motes::new(10); assert_eq!( (left_motes / right_motes), expected_motes, @@ -204,34 +209,34 @@ mod tests { #[test] fn should_be_able_to_convert_from_motes() { - let gas = Gas::new(U512::from(100)); + let gas = Gas::new(100); let motes = Motes::from_gas(gas, 10).expect("should have value"); - let expected_motes = Motes::new(U512::from(1000)); + let expected_motes = Motes::new(1000); assert_eq!(motes, expected_motes, "should be equal") } #[test] fn should_be_able_to_default() { let motes = Motes::default(); - let expected_motes = Motes::new(U512::from(0)); + let expected_motes = Motes::new(0); assert_eq!(motes, expected_motes, "should be equal") } #[test] fn should_be_able_to_compare_relative_value() { - let left_motes = Motes::new(U512::from(100)); - let right_motes = Motes::new(U512::from(10)); + let left_motes = Motes::new(100); + let right_motes = Motes::new(10); assert!(left_motes > right_motes, "should be gt"); - let right_motes = Motes::new(U512::from(100)); + let right_motes = Motes::new(100); assert!(left_motes >= right_motes, "should be gte"); assert!(left_motes <= right_motes, "should be lte"); - let left_motes = Motes::new(U512::from(10)); + let left_motes = Motes::new(10); assert!(left_motes < right_motes, "should be lt"); } #[test] fn should_default() { - let left_motes = Motes::new(U512::from(0)); + let left_motes = Motes::new(0); let right_motes = Motes::default(); assert_eq!(left_motes, right_motes, "should be equal"); let u512 = U512::zero(); diff --git a/types/src/transaction/deploy.rs b/types/src/transaction/deploy.rs index 934f73d259..3a300c5612 100644 --- a/types/src/transaction/deploy.rs +++ b/types/src/transaction/deploy.rs @@ -49,7 +49,7 @@ use crate::{ }, testing::TestRng, AddressableEntityHash, RuntimeArgs, TransactionConfig, DEFAULT_MAX_PAYMENT_MOTES, - DEFAULT_MIN_TRANSFER_MOTES, U512, + DEFAULT_MIN_TRANSFER_MOTES, }; use crate::{ bytesrepr::{self, FromBytes, ToBytes}, @@ -58,7 +58,7 @@ use crate::{ Digest, DisplayIter, PublicKey, SecretKey, TimeDiff, Timestamp, }; #[cfg(any(feature = "std", test))] -use crate::{system::auction::ARG_AMOUNT, Gas, Motes, SystemConfig}; +use crate::{system::auction::ARG_AMOUNT, Gas, Motes, SystemConfig, U512}; #[cfg(any(feature = "std", test))] pub use deploy_builder::{DeployBuilder, DeployBuilderError}; pub use deploy_category::DeployCategory; @@ -395,7 +395,7 @@ impl Deploy { }; let motes = { if self.is_transfer() { - Motes::new(U512::from(system_costs.mint_costs().transfer)) + Motes::new(system_costs.mint_costs().transfer) } else { let value = self .payment() diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index f3b1c394db..88efd19129 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -241,7 +241,7 @@ impl TransactionV1 { } None => *user_specified_price, }; - let motes = Motes::new(U512::from(*payment_amount)); + let motes = Motes::new(*payment_amount); Gas::from_motes(motes, actual_price) } PricingMode::Fixed { .. } => { @@ -277,11 +277,11 @@ impl TransactionV1 { costs.standard_transaction_limit() } }; - Gas::from_motes(Motes::new(U512::from(cost)), gas_price) + Gas::from_motes(Motes::new(cost), gas_price) } PricingMode::Reserved { paid_amount, .. } => { // prepaid, if receipt is legit (future use, not currently implemented) - Gas::from_motes(Motes::new(U512::from(paid_amount)), 1) + Gas::from_motes(Motes::new(paid_amount), 1) } } } From 6c57b5bffb95d45111aef0e4dacd9ad8d2e9bc80 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Thu, 14 Mar 2024 00:26:48 +0000 Subject: [PATCH 15/70] fix failing tests after merge --- .../src/engine_state/execute_request.rs | 16 ++++++---------- .../src/engine_state/execution_kind.rs | 13 ------------- execution_engine/src/engine_state/mod.rs | 6 ------ .../tests/src/test/explorer/faucet.rs | 8 ++++---- node/src/components/block_validator/state.rs | 6 +++--- resources/test/sse_data_schema.json | 2 +- types/src/api_error.rs | 2 +- 7 files changed, 15 insertions(+), 38 deletions(-) diff --git a/execution_engine/src/engine_state/execute_request.rs b/execution_engine/src/engine_state/execute_request.rs index 01c83b490f..a6680d1972 100644 --- a/execution_engine/src/engine_state/execute_request.rs +++ b/execution_engine/src/engine_state/execute_request.rs @@ -4,10 +4,10 @@ use serde::Serialize; use thiserror::Error; use casper_types::{ - account::AccountHash, bytesrepr::Bytes, BlockTime, DeployHash, Digest, ExecutableDeployItem, - InitiatorAddr, PublicKey, RuntimeArgs, Transaction, TransactionEntryPoint, TransactionHash, - TransactionInvocationTarget, TransactionSessionKind, TransactionTarget, TransactionV1Body, - TransactionV1Hash, + account::AccountHash, bytesrepr::Bytes, runtime_args, BlockTime, DeployHash, Digest, + ExecutableDeployItem, InitiatorAddr, PublicKey, RuntimeArgs, Transaction, + TransactionEntryPoint, TransactionHash, TransactionInvocationTarget, TransactionSessionKind, + TransactionTarget, TransactionV1Body, TransactionV1Hash, U512, }; const DEFAULT_ENTRY_POINT: &str = "call"; @@ -21,8 +21,6 @@ pub enum Payment { Stored(TransactionInvocationTarget), /// Compiled Wasm as byte code to be executed as custom payment. ModuleBytes(Bytes), - /// The session from this transaction should be executed as custom payment. - UseSession, } /// The payment-related portion of an `ExecuteRequest`. @@ -306,12 +304,10 @@ impl ExecuteRequest { Transaction::V1(v1_txn) => { let (hash, _header, body, _approvals) = v1_txn.destructure(); gas_price = 1; - // If the payment amount is `None`, the provided session will be invoked - // during the payment and session phases. payment_info = PaymentInfo { - payment: Payment::UseSession, + payment: Payment::Standard, entry_point: DEFAULT_ENTRY_POINT.to_string(), - args: RuntimeArgs::new(), + args: runtime_args! { "amount" => U512::from(1_500_000_000_000_u64) }, /* TODO - this is bogus: should be resolved once new payment logic is merged. */ }; session_info = SessionInfo::try_from((body, hash))?; } diff --git a/execution_engine/src/engine_state/execution_kind.rs b/execution_engine/src/engine_state/execution_kind.rs index 63b4261e90..735d1c8a7d 100644 --- a/execution_engine/src/engine_state/execution_kind.rs +++ b/execution_engine/src/engine_state/execution_kind.rs @@ -71,19 +71,6 @@ impl<'a> ExecutionKind<'a> { Ok(ExecutionKind::Standard(module_bytes)) } - /// Returns a new `ExecutionKind` cloned from `self`, but converting any Wasm bytes variant to - /// `Standard`, and returning an error if they are empty. - pub fn convert_for_payment(&self) -> Result { - match self { - ExecutionKind::Standard(module_bytes) - | ExecutionKind::Installer(module_bytes) - | ExecutionKind::Upgrader(module_bytes) - | ExecutionKind::Isolated(module_bytes) - | ExecutionKind::Deploy(module_bytes) => Self::new_standard_for_payment(module_bytes), - ExecutionKind::Stored { .. } => Ok(self.clone()), - } - } - /// Returns a new contract variant of `ExecutionKind`. pub fn new_stored( tracking_copy: &mut TrackingCopy, diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index 03f836ad0a..55a5140f1e 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -349,12 +349,6 @@ impl ExecutionEngineV1 { } } } - Payment::UseSession => match session_execution_kind.convert_for_payment() { - Ok(execution_kind) => Some(execution_kind), - Err(error) => { - return Ok(ExecutionResult::precondition_failure(error)); - } - }, }; if let Some(custom_payment) = maybe_custom_payment { diff --git a/execution_engine_testing/tests/src/test/explorer/faucet.rs b/execution_engine_testing/tests/src/test/explorer/faucet.rs index 74cbc2f984..e1711a8b27 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet.rs @@ -925,10 +925,10 @@ fn faucet_costs() { // This test will fail if execution costs vary. The expected costs should not be updated // without understanding why the cost has changed. If the costs do change, it should be // reflected in the "Costs by Entry Point" section of the faucet crate's README.md. - const EXPECTED_FAUCET_INSTALL_COST: u64 = 91_881_365_540; - const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_727_890; - const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_307_630; - const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_774_270; + const EXPECTED_FAUCET_INSTALL_COST: u64 = 91_918_543_000; + const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_738_410; + const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_321_730; + const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_795_850; let installer_account = AccountHash::new([1u8; 32]); let user_account: AccountHash = AccountHash::new([2u8; 32]); diff --git a/node/src/components/block_validator/state.rs b/node/src/components/block_validator/state.rs index d1bb5c8f40..40f831dbcd 100644 --- a/node/src/components/block_validator/state.rs +++ b/node/src/components/block_validator/state.rs @@ -658,10 +658,10 @@ mod tests { } // Please note: values in the following test cases must much the production chainspec. - const MAX_STANDARD_COUNT: u64 = 100; - const MAX_AUCTION_COUNT: u64 = 200; + const MAX_STANDARD_COUNT: u64 = 50; + const MAX_AUCTION_COUNT: u64 = 100; const MAX_INSTALL_UPGRADE_COUNT: u64 = 2; - const MAX_MINT_COUNT: u64 = 1000; + const MAX_MINT_COUNT: u64 = 500; struct TestCase { mint_count: u64, diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index 32a4c0a5c3..c8ca8a13e9 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -3406,7 +3406,7 @@ "additionalProperties": false }, "TransformKindV2": { - "description": "Representation of a single transformation occurring during execution.\n\nNote that all arithmetic variants of [`TransformKind`] are commutative which means that a given collection of them can be executed in any order to produce the same end result.", + "description": "Representation of a single transformation occurring during execution.\n\nNote that all arithmetic variants of `TransformKindV2` are commutative which means that a given collection of them can be executed in any order to produce the same end result.", "oneOf": [ { "description": "An identity transformation that does not modify a value in the global state.\n\nCreated as a result of reading from the global state.", diff --git a/types/src/api_error.rs b/types/src/api_error.rs index 4b447084b4..3979456573 100644 --- a/types/src/api_error.rs +++ b/types/src/api_error.rs @@ -443,7 +443,7 @@ pub enum ApiError { /// as an installer/upgrader. /// ``` /// # use casper_types::ApiError; - /// assert_eq!(ApiError::from(47), ApiError::NotAllowedToAddContractVersion); + /// assert_eq!(ApiError::from(48), ApiError::NotAllowedToAddContractVersion); /// ``` NotAllowedToAddContractVersion, } From 1a97cf085eac3f3d8e9fb37d7df7639a71cb1fda Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Wed, 13 Mar 2024 22:22:13 -0700 Subject: [PATCH 16/70] making tests use local chainspec, and misc tweaks --- .../src/engine_state/engine_config.rs | 5 +- execution_engine/src/engine_state/mod.rs | 12 +- execution_engine/src/execution/executor.rs | 4 - .../src/runtime/auction_internal.rs | 3 +- execution_engine/src/runtime/mod.rs | 19 +- execution_engine/src/runtime_context/mod.rs | 4 +- .../test_support/resources/chainspec.toml | 2 +- .../test_support/src/auction.rs | 12 +- .../test_support/src/chainspec_config.rs | 6 +- .../test_support/src/lib.rs | 25 +- .../test_support/src/transfer.rs | 4 +- .../test_support/src/utils.rs | 9 +- .../test_support/src/wasm_test_builder.rs | 181 +++-- .../tests/benches/transfer_bench.rs | 5 +- .../tests/src/test/chainspec_registry.rs | 4 +- .../contract_api/account/associated_keys.rs | 6 +- .../contract_api/account/authorized_keys.rs | 16 +- .../account/key_management_thresholds.rs | 6 +- .../test/contract_api/account/named_keys.rs | 5 +- .../contract_api/account/named_keys_stored.rs | 5 +- .../src/test/contract_api/create_purse.rs | 6 +- .../tests/src/test/contract_api/dictionary.rs | 14 +- .../tests/src/test/contract_api/get_arg.rs | 5 +- .../src/test/contract_api/get_blocktime.rs | 5 +- .../tests/src/test/contract_api/get_caller.rs | 10 +- .../tests/src/test/contract_api/get_phase.rs | 4 +- .../contract_api/list_authorization_keys.rs | 4 +- .../src/test/contract_api/list_named_keys.rs | 5 +- .../tests/src/test/contract_api/main_purse.rs | 6 +- .../tests/src/test/contract_api/mint_purse.rs | 8 +- .../contract_api/multisig_authorization.rs | 4 +- .../test/contract_api/named_dictionaries.rs | 5 +- .../tests/src/test/contract_api/revert.rs | 5 +- .../tests/src/test/contract_api/runtime.rs | 8 +- .../tests/src/test/contract_api/subcall.rs | 9 +- .../tests/src/test/contract_api/transfer.rs | 18 +- .../src/test/contract_api/transfer_cached.rs | 6 +- .../contract_api/transfer_purse_to_account.rs | 6 +- .../contract_api/transfer_purse_to_purse.rs | 6 +- .../tests/src/test/contract_context.rs | 9 +- .../tests/src/test/contract_messages.rs | 26 +- .../tests/src/test/counter_factory.rs | 5 +- .../src/test/deploy/context_association.rs | 4 +- .../src/test/deploy/non_standard_payment.rs | 4 +- .../tests/src/test/deploy/preconditions.rs | 8 +- .../tests/src/test/deploy/receipts.rs | 13 +- .../tests/src/test/deploy/stored_contracts.rs | 28 +- .../tests/src/test/explorer/faucet.rs | 30 +- .../tests/src/test/gas_counter.rs | 6 +- .../tests/src/test/get_balance.rs | 7 +- .../tests/src/test/host_function_costs.rs | 9 +- .../tests/src/test/private_chain.rs | 2 - .../private_chain/burn_fees_and_refund.rs | 14 +- .../test/private_chain/fees_accumulation.rs | 6 +- .../src/test/private_chain/management.rs | 2 - .../test/private_chain/restricted_auction.rs | 5 +- .../tests/src/test/regression/ee_1071.rs | 5 +- .../tests/src/test/regression/ee_1129.rs | 25 +- .../tests/src/test/regression/ee_1160.rs | 8 +- .../tests/src/test/regression/ee_1163.rs | 4 +- .../tests/src/test/regression/ee_1174.rs | 4 +- .../tests/src/test/regression/ee_1217.rs | 22 +- .../tests/src/test/regression/ee_1225.rs | 4 +- .../tests/src/test/regression/ee_221.rs | 5 +- .../tests/src/test/regression/ee_401.rs | 5 +- .../tests/src/test/regression/ee_441.rs | 4 +- .../tests/src/test/regression/ee_460.rs | 5 +- .../tests/src/test/regression/ee_468.rs | 5 +- .../tests/src/test/regression/ee_470.rs | 7 +- .../tests/src/test/regression/ee_532.rs | 4 +- .../tests/src/test/regression/ee_536.rs | 5 +- .../tests/src/test/regression/ee_539.rs | 5 +- .../tests/src/test/regression/ee_549.rs | 5 +- .../tests/src/test/regression/ee_550.rs | 6 +- .../tests/src/test/regression/ee_572.rs | 4 +- .../tests/src/test/regression/ee_584.rs | 5 +- .../tests/src/test/regression/ee_599.rs | 4 +- .../tests/src/test/regression/ee_601.rs | 4 +- .../tests/src/test/regression/ee_771.rs | 5 +- .../tests/src/test/regression/ee_890.rs | 6 +- .../tests/src/test/regression/ee_966.rs | 20 +- .../tests/src/test/regression/gh_1470.rs | 4 +- .../tests/src/test/regression/gh_1688.rs | 4 +- .../tests/src/test/regression/gh_1902.rs | 41 +- .../tests/src/test/regression/gh_1931.rs | 7 +- .../tests/src/test/regression/gh_2280.rs | 6 +- .../tests/src/test/regression/gh_3097.rs | 5 +- .../tests/src/test/regression/gh_3710.rs | 12 +- .../tests/src/test/regression/gov_42.rs | 4 +- .../tests/src/test/regression/gov_427.rs | 4 +- .../tests/src/test/regression/gov_74.rs | 4 +- ...host_function_metrics_size_and_gas_cost.rs | 4 +- .../test/regression/regression_20210707.rs | 21 +- .../test/regression/regression_20210831.rs | 6 +- .../test/regression/regression_20210924.rs | 8 +- .../test/regression/regression_20211110.rs | 4 +- .../test/regression/regression_20220119.rs | 5 +- .../test/regression/regression_20220204.rs | 5 +- .../test/regression/regression_20220207.rs | 9 +- .../test/regression/regression_20220208.rs | 7 +- .../test/regression/regression_20220211.rs | 5 +- .../test/regression/regression_20220217.rs | 8 +- .../test/regression/regression_20220221.rs | 6 +- .../test/regression/regression_20220222.rs | 6 +- .../test/regression/regression_20220223.rs | 4 +- .../test/regression/regression_20220224.rs | 4 +- .../test/regression/regression_20220727.rs | 29 +- .../tests/src/test/regression/slow_input.rs | 13 +- .../regression/transforms_must_be_ordered.rs | 4 +- .../tests/src/test/stack_overflow.rs | 5 +- .../tests/src/test/storage_costs.rs | 8 +- .../src/test/system_contracts/auction/bids.rs | 30 +- .../system_contracts/auction/distribute.rs | 666 ++++++++---------- .../test/system_contracts/auction_bidding.rs | 16 +- .../src/test/system_contracts/genesis.rs | 14 +- .../handle_payment/finalize_payment.rs | 6 +- .../handle_payment/get_payment_purse.rs | 6 +- .../handle_payment/refund_purse.rs | 4 +- .../test/system_contracts/standard_payment.rs | 20 +- .../src/test/system_contracts/upgrade.rs | 28 +- .../tests/src/test/system_costs.rs | 28 +- .../tests/src/test/tutorial/counter.rs | 5 +- .../tests/src/test/tutorial/hello_world.rs | 5 +- .../tests/src/test/upgrade.rs | 16 +- .../tests/src/test/wasmless_transfer.rs | 7 +- .../components/contract_runtime/operations.rs | 45 +- node/src/components/contract_runtime/tests.rs | 4 +- storage/src/data_access_layer/bidding.rs | 22 +- storage/src/data_access_layer/fee.rs | 12 +- storage/src/data_access_layer/transfer.rs | 16 +- storage/src/global_state/state/mod.rs | 68 +- storage/src/system/auction.rs | 8 +- storage/src/system/auction/detail.rs | 8 +- storage/src/system/transfer.rs | 21 - types/src/chainspec.rs | 19 +- types/src/chainspec/core_config.rs | 19 +- types/src/chainspec/genesis_config.rs | 43 +- .../src/chainspec/vm_config/auction_costs.rs | 8 +- types/src/gas.rs | 8 - types/src/key.rs | 26 +- types/src/lib.rs | 10 +- types/src/system/auction/error.rs | 10 +- types/src/system/mint/balance_hold.rs | 89 ++- types/src/system/mint/constants.rs | 2 - utils/global-state-update-gen/src/admins.rs | 6 +- utils/validation/src/generators.rs | 21 +- utils/validation/tests/fixtures/ABI/key.json | 9 + .../tests/fixtures/ABI/stored_value.json | 10 +- 148 files changed, 1195 insertions(+), 1213 deletions(-) diff --git a/execution_engine/src/engine_state/engine_config.rs b/execution_engine/src/engine_state/engine_config.rs index f5ebcf5966..d43046431a 100644 --- a/execution_engine/src/engine_state/engine_config.rs +++ b/execution_engine/src/engine_state/engine_config.rs @@ -8,7 +8,7 @@ use num_traits::One; use casper_types::{ account::AccountHash, FeeHandling, PublicKey, RefundHandling, SystemConfig, TimeDiff, - WasmConfig, DEFAULT_REFUND_HANDLING, + WasmConfig, DEFAULT_FEE_HANDLING, DEFAULT_REFUND_HANDLING, }; /// Default value for a maximum query depth configuration option. @@ -40,9 +40,6 @@ pub const DEFAULT_MAX_DELEGATORS_PER_VALIDATOR: u32 = 1200; pub const DEFAULT_ALLOW_AUCTION_BIDS: bool = true; /// Default value for allowing unrestricted transfers. pub const DEFAULT_ALLOW_UNRESTRICTED_TRANSFERS: bool = true; - -/// Default fee handling. -pub const DEFAULT_FEE_HANDLING: FeeHandling = FeeHandling::PayToProposer; /// Default compute rewards. pub const DEFAULT_COMPUTE_REWARDS: bool = true; /// Default period for balance holds to decay (currently 24 hours). diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index e51f32187c..0941920417 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -16,13 +16,12 @@ use casper_storage::{ data_access_layer::TransferRequest, global_state::state::StateProvider, system::runtime_native::TransferConfig, - tracking_copy::{FeesPurseHandling, TrackingCopyEntityExt, TrackingCopyError, TrackingCopyExt}, + tracking_copy::{FeesPurseHandling, TrackingCopyEntityExt, TrackingCopyExt}, }; use casper_types::{ system::{ handle_payment::{self}, - mint::ARG_HOLDS_EPOCH, HANDLE_PAYMENT, }, BlockTime, DeployInfo, Digest, EntityAddr, ExecutableDeployItem, FeeHandling, Gas, Key, Motes, @@ -177,14 +176,11 @@ impl ExecutionEngineV1 { .value() .saturating_sub(self.config.balance_hold_interval.millis()), ); - let mut runtime_args = deploy_item.session.args().clone(); - if let Err(cve) = runtime_args.insert(ARG_HOLDS_EPOCH, holds_epoch) { - return Err(Error::TrackingCopy(TrackingCopyError::CLValue(cve))); - } + let runtime_args = deploy_item.session.args().clone(); let transfer_req = TransferRequest::with_runtime_args( native_runtime_config, prestate_hash, - blocktime.value(), + holds_epoch, protocol_version, transaction_hash, deploy_item.address, @@ -636,7 +632,6 @@ impl ExecutionEngineV1 { )) } }; - executor.exec( session_execution_kind, session_args, @@ -711,7 +706,6 @@ impl ExecutionEngineV1 { // NOTE: session_code_spec_3: (do not include session execution effects in // results) is enforced in execution_result_builder.build() execution_result_builder.set_session_execution_result(session_result); - // payment_code_spec_5: run finalize process let finalize_result: ExecutionResult = { let post_session_tc = post_session_rc.borrow(); diff --git a/execution_engine/src/execution/executor.rs b/execution_engine/src/execution/executor.rs index ce33e21a46..e853c7ef7d 100644 --- a/execution_engine/src/execution/executor.rs +++ b/execution_engine/src/execution/executor.rs @@ -370,9 +370,6 @@ impl Executor { None => return Err(EngineStateError::reverter(ApiError::HandlePayment(12))), }; - let holds_epoch = blocktime - .value() - .saturating_sub(self.config.balance_hold_interval.millis()); let runtime_args = { let transfer_args = TransferArgs::new( None, @@ -380,7 +377,6 @@ impl Executor { payment_purse, payment_amount, None, - Some(holds_epoch), ); match RuntimeArgs::try_from(transfer_args) { diff --git a/execution_engine/src/runtime/auction_internal.rs b/execution_engine/src/runtime/auction_internal.rs index ea34b25dfd..d0f26285cf 100644 --- a/execution_engine/src/runtime/auction_internal.rs +++ b/execution_engine/src/runtime/auction_internal.rs @@ -265,7 +265,7 @@ where target: URef, amount: U512, id: Option, - holds_epoch: Option, + _holds_epoch: Option, ) -> Result, Error> { if !(self.context.entity().main_purse().addr() == source.addr() || self.context.get_caller() == PublicKey::System.to_account_hash()) @@ -279,7 +279,6 @@ where args.insert(mint::ARG_TARGET, target)?; args.insert(mint::ARG_AMOUNT, amount)?; args.insert(mint::ARG_ID, id)?; - args.insert(mint::ARG_HOLDS_EPOCH, holds_epoch)?; Ok(()) }) .map_err(|_| Error::CLValue)?; diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index f92d8785f6..e9acc82ed9 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -630,9 +630,10 @@ where mint_runtime.charge_system_contract_call(mint_costs.balance)?; let uref: URef = Self::get_named_argument(runtime_args, mint::ARG_PURSE)?; + let holds_epoch = Some(self.holds_epoch()); let maybe_balance: Option = mint_runtime - .balance(uref, Some(self.holds_epoch())) + .balance(uref, holds_epoch) .map_err(Self::reverter)?; CLValue::from_t(maybe_balance).map_err(Self::reverter) })(), @@ -647,14 +648,9 @@ where let target: URef = Self::get_named_argument(runtime_args, mint::ARG_TARGET)?; let amount: U512 = Self::get_named_argument(runtime_args, mint::ARG_AMOUNT)?; let id: Option = Self::get_named_argument(runtime_args, mint::ARG_ID)?; - let result: Result<(), mint::Error> = mint_runtime.transfer( - maybe_to, - source, - target, - amount, - id, - Some(self.holds_epoch()), - ); + let holds_epoch = Some(self.holds_epoch()); + let result: Result<(), mint::Error> = + mint_runtime.transfer(maybe_to, source, target, amount, id, holds_epoch); CLValue::from_t(result).map_err(Self::reverter) })(), @@ -853,7 +849,6 @@ where auction::METHOD_ADD_BID => (|| { runtime.charge_system_contract_call(auction_costs.add_bid)?; - let account_hash = Self::get_named_argument(runtime_args, auction::ARG_PUBLIC_KEY)?; let delegation_rate = Self::get_named_argument(runtime_args, auction::ARG_DELEGATION_RATE)?; @@ -2521,12 +2516,12 @@ where return Err(ExecError::DisabledUnrestrictedTransfers); } - let holds_epoch = self.holds_epoch(); + let holds_epoch = Some(self.holds_epoch()); // A precondition check that verifies that the transfer can be done // as the source purse has enough funds to cover the transfer. if amount > self - .available_balance(source, Some(holds_epoch))? + .available_balance(source, holds_epoch)? .unwrap_or_default() { return Ok(Err(mint::Error::InsufficientFunds.into())); diff --git a/execution_engine/src/runtime_context/mod.rs b/execution_engine/src/runtime_context/mod.rs index c5502ae7a5..5563e2896e 100644 --- a/execution_engine/src/runtime_context/mod.rs +++ b/execution_engine/src/runtime_context/mod.rs @@ -780,10 +780,8 @@ where pub(crate) fn charge_gas(&mut self, gas: Gas) -> Result<(), ExecError> { let prev = self.gas_counter(); let gas_limit = self.gas_limit(); - let is_system = self.entity_key.is_system_key(); - // gas charge overflow protection - match prev.checked_add(gas.cost(is_system)) { + match prev.checked_add(gas) { None => { self.set_gas_counter(gas_limit); Err(ExecError::GasLimit) diff --git a/execution_engine_testing/test_support/resources/chainspec.toml b/execution_engine_testing/test_support/resources/chainspec.toml index 18f4fbd206..8815ac74ee 120000 --- a/execution_engine_testing/test_support/resources/chainspec.toml +++ b/execution_engine_testing/test_support/resources/chainspec.toml @@ -1 +1 @@ -../../../resources/production/chainspec.toml \ No newline at end of file +../../../resources/local/chainspec.toml \ No newline at end of file diff --git a/execution_engine_testing/test_support/src/auction.rs b/execution_engine_testing/test_support/src/auction.rs index 3f0a48dcc8..e8d631a11d 100644 --- a/execution_engine_testing/test_support/src/auction.rs +++ b/execution_engine_testing/test_support/src/auction.rs @@ -19,16 +19,16 @@ use casper_types::{ runtime_args, system::auction, ChainspecRegistry, Digest, GenesisAccount, GenesisConfigBuilder, GenesisValidator, Key, Motes, - ProtocolVersion, PublicKey, SecretKey, StoredValue, DEFAULT_REFUND_HANDLING, U512, + ProtocolVersion, PublicKey, SecretKey, StoredValue, U512, }; use crate::{ transfer, DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, StepRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_ACCOUNT_PUBLIC_KEY, - DEFAULT_AUCTION_DELAY, DEFAULT_FEE_HANDLING, DEFAULT_GENESIS_CONFIG_HASH, - DEFAULT_GENESIS_TIMESTAMP_MILLIS, DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, - DEFAULT_PROPOSER_PUBLIC_KEY, DEFAULT_PROTOCOL_VERSION, DEFAULT_ROUND_SEIGNIORAGE_RATE, - DEFAULT_SYSTEM_CONFIG, DEFAULT_UNBONDING_DELAY, DEFAULT_WASM_CONFIG, SYSTEM_ADDR, + DEFAULT_AUCTION_DELAY, DEFAULT_GENESIS_CONFIG_HASH, DEFAULT_GENESIS_TIMESTAMP_MILLIS, + DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, DEFAULT_PROPOSER_PUBLIC_KEY, DEFAULT_PROTOCOL_VERSION, + DEFAULT_ROUND_SEIGNIORAGE_RATE, DEFAULT_SYSTEM_CONFIG, DEFAULT_UNBONDING_DELAY, + DEFAULT_WASM_CONFIG, SYSTEM_ADDR, }; const ARG_AMOUNT: &str = "amount"; @@ -325,8 +325,6 @@ fn create_run_genesis_request( .with_round_seigniorage_rate(DEFAULT_ROUND_SEIGNIORAGE_RATE) .with_unbonding_delay(DEFAULT_UNBONDING_DELAY) .with_genesis_timestamp_millis(DEFAULT_GENESIS_TIMESTAMP_MILLIS) - .with_refund_handling(DEFAULT_REFUND_HANDLING) - .with_fee_handling(DEFAULT_FEE_HANDLING) .build(); GenesisRequest::new( diff --git a/execution_engine_testing/test_support/src/chainspec_config.rs b/execution_engine_testing/test_support/src/chainspec_config.rs index bd992f2ee7..d0ee74a989 100644 --- a/execution_engine_testing/test_support/src/chainspec_config.rs +++ b/execution_engine_testing/test_support/src/chainspec_config.rs @@ -47,7 +47,7 @@ pub enum Error { /// This struct can be parsed from a TOML-encoded chainspec file. It means that as the /// chainspec format changes over versions, as long as we maintain the core config in this form /// in the chainspec file, it can continue to be parsed as an `ChainspecConfig`. -#[derive(Deserialize, Clone, Default)] +#[derive(Deserialize, Clone, Default, Debug)] pub struct ChainspecConfig { /// CoreConfig #[serde(rename = "core")] @@ -142,8 +142,8 @@ impl ChainspecConfig { )) } - /// Create a `RunGenesisRequest` using values from the production `chainspec.toml`. - pub fn create_genesis_request_from_production_chainspec( + /// Create a `RunGenesisRequest` using values from the local `chainspec.toml`. + pub fn create_genesis_request_from_local_chainspec( genesis_accounts: Vec, protocol_version: ProtocolVersion, ) -> Result { diff --git a/execution_engine_testing/test_support/src/lib.rs b/execution_engine_testing/test_support/src/lib.rs index 3f992c93db..c620b61693 100644 --- a/execution_engine_testing/test_support/src/lib.rs +++ b/execution_engine_testing/test_support/src/lib.rs @@ -27,9 +27,9 @@ use once_cell::sync::Lazy; use casper_storage::data_access_layer::GenesisRequest; use casper_types::{ - account::AccountHash, ChainspecRegistry, Digest, GenesisAccount, GenesisConfig, - GenesisConfigBuilder, Motes, ProtocolVersion, PublicKey, SecretKey, SystemConfig, WasmConfig, - DEFAULT_FEE_HANDLING, DEFAULT_REFUND_HANDLING, U512, + account::AccountHash, testing::TestRng, ChainspecRegistry, Digest, GenesisAccount, + GenesisConfig, GenesisConfigBuilder, Motes, ProtocolVersion, PublicKey, SecretKey, + SystemConfig, WasmConfig, U512, }; pub use chainspec_config::ChainspecConfig; @@ -59,7 +59,7 @@ pub const DEFAULT_UNBONDING_DELAY: u64 = 7; /// Ticks per year: 31536000000 /// /// (1+0.08)^((2^14)/31536000000)-1 is expressed as a fractional number below. -pub const DEFAULT_ROUND_SEIGNIORAGE_RATE: Ratio = Ratio::new_raw(7, 175070816); +pub const DEFAULT_ROUND_SEIGNIORAGE_RATE: Ratio = Ratio::new_raw(1, 4200000000000000000); /// Default chain name. pub const DEFAULT_CHAIN_NAME: &str = "casper-execution-engine-testing"; @@ -99,7 +99,7 @@ pub static DEFAULT_ACCOUNT_ADDR: Lazy = pub static DEFAULT_ACCOUNT_KEY: Lazy = Lazy::new(|| AccountHash::from(&*DEFAULT_ACCOUNT_PUBLIC_KEY)); /// Default initial balance of a test account in motes. -pub const DEFAULT_ACCOUNT_INITIAL_BALANCE: u64 = 100_000_000_000_000_000u64; +pub const DEFAULT_ACCOUNT_INITIAL_BALANCE: u64 = 10_000_000_000_000_000_000u64; /// Minimal amount for a transfer that creates new accounts. pub const MINIMUM_ACCOUNT_CREATION_BALANCE: u64 = 7_500_000_000_000_000u64; /// Default proposer public key. @@ -125,6 +125,15 @@ pub static DEFAULT_ACCOUNTS: Lazy> = Lazy::new(|| { None, ); ret.push(proposer_account); + let rng = &mut TestRng::new(); + for _ in 0..10 { + let filler_account = GenesisAccount::account( + PublicKey::random(rng), + Motes::new(DEFAULT_ACCOUNT_INITIAL_BALANCE.into()), + None, + ); + ret.push(filler_account); + } ret }); /// Default [`ProtocolVersion`]. @@ -148,8 +157,6 @@ pub static DEFAULT_EXEC_CONFIG: Lazy = Lazy::new(|| { .with_round_seigniorage_rate(DEFAULT_ROUND_SEIGNIORAGE_RATE) .with_unbonding_delay(DEFAULT_UNBONDING_DELAY) .with_genesis_timestamp_millis(DEFAULT_GENESIS_TIMESTAMP_MILLIS) - .with_refund_handling(DEFAULT_REFUND_HANDLING) - .with_fee_handling(DEFAULT_FEE_HANDLING) .build() }); @@ -158,8 +165,8 @@ pub static DEFAULT_CHAINSPEC_REGISTRY: Lazy = Lazy::new(|| ChainspecRegistry::new_with_genesis(&[1, 2, 3], &[4, 5, 6])); /// A [`GenesisRequest`] using cost tables matching those used in Casper Mainnet. -pub static PRODUCTION_RUN_GENESIS_REQUEST: Lazy = Lazy::new(|| { - ChainspecConfig::create_genesis_request_from_production_chainspec( +pub static LOCAL_GENESIS_REQUEST: Lazy = Lazy::new(|| { + ChainspecConfig::create_genesis_request_from_local_chainspec( DEFAULT_ACCOUNTS.clone(), *DEFAULT_PROTOCOL_VERSION, ) diff --git a/execution_engine_testing/test_support/src/transfer.rs b/execution_engine_testing/test_support/src/transfer.rs index a7eb234f6c..70c0155aa9 100644 --- a/execution_engine_testing/test_support/src/transfer.rs +++ b/execution_engine_testing/test_support/src/transfer.rs @@ -4,7 +4,7 @@ use casper_types::{account::AccountHash, runtime_args, Key, URef, U512}; use crate::{ DeployItemBuilder, ExecuteRequestBuilder, WasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; const CONTRACT_CREATE_ACCOUNTS: &str = "create_accounts.wasm"; @@ -46,7 +46,7 @@ pub fn create_initial_accounts_and_run_genesis( ) { let exec_request = create_accounts_request(accounts, amount); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .expect_success() .commit(); diff --git a/execution_engine_testing/test_support/src/utils.rs b/execution_engine_testing/test_support/src/utils.rs index e8316cab9f..0d24d446c9 100644 --- a/execution_engine_testing/test_support/src/utils.rs +++ b/execution_engine_testing/test_support/src/utils.rs @@ -10,10 +10,7 @@ use once_cell::sync::Lazy; use casper_execution_engine::engine_state::{execution_result::ExecutionResult, Error}; use casper_storage::data_access_layer::GenesisRequest; -use casper_types::{ - Gas, GenesisAccount, GenesisConfig, GenesisConfigBuilder, DEFAULT_FEE_HANDLING, - DEFAULT_REFUND_HANDLING, -}; +use casper_types::{Gas, GenesisAccount, GenesisConfig, GenesisConfigBuilder}; use super::{DEFAULT_ROUND_SEIGNIORAGE_RATE, DEFAULT_SYSTEM_CONFIG, DEFAULT_UNBONDING_DELAY}; use crate::{ @@ -137,8 +134,6 @@ pub fn create_genesis_config(accounts: Vec) -> GenesisConfig { let round_seigniorage_rate = DEFAULT_ROUND_SEIGNIORAGE_RATE; let unbonding_delay = DEFAULT_UNBONDING_DELAY; let genesis_timestamp_millis = DEFAULT_GENESIS_TIMESTAMP_MILLIS; - let refund_handling = DEFAULT_REFUND_HANDLING; - let fee_handling = DEFAULT_FEE_HANDLING; GenesisConfigBuilder::default() .with_accounts(accounts) @@ -150,8 +145,6 @@ pub fn create_genesis_config(accounts: Vec) -> GenesisConfig { .with_round_seigniorage_rate(round_seigniorage_rate) .with_unbonding_delay(unbonding_delay) .with_genesis_timestamp_millis(genesis_timestamp_millis) - .with_refund_handling(refund_handling) - .with_fee_handling(fee_handling) .build() } diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index 300d6e041b..5ba6d08eea 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -3,6 +3,7 @@ use std::{ convert::{TryFrom, TryInto}, ffi::OsStr, fs, + iter::FromIterator, ops::Deref, path::{Path, PathBuf}, rc::Rc, @@ -20,13 +21,14 @@ use casper_execution_engine::engine_state::{ }; use casper_storage::{ data_access_layer::{ - balance::BalanceHandling, BalanceRequest, BalanceResult, BidsRequest, BlockRewardsRequest, - BlockRewardsResult, BlockStore, DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, - FeeRequest, FeeResult, FlushRequest, FlushResult, GenesisRequest, GenesisResult, - ProtocolUpgradeRequest, ProtocolUpgradeResult, PruneRequest, PruneResult, QueryRequest, - QueryResult, StepRequest, StepResult, SystemEntityRegistryPayload, - SystemEntityRegistryRequest, SystemEntityRegistryResult, SystemEntityRegistrySelector, - TrieRequest, + balance::BalanceHandling, AuctionMethod, BalanceRequest, BalanceResult, BiddingRequest, + BiddingResult, BidsRequest, BlockRewardsRequest, BlockRewardsResult, BlockStore, + DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, FeeRequest, FeeResult, + FlushRequest, FlushResult, GenesisRequest, GenesisResult, ProtocolUpgradeRequest, + ProtocolUpgradeResult, PruneRequest, PruneResult, QueryRequest, QueryResult, + RoundSeigniorageRateRequest, RoundSeigniorageRateResult, StepRequest, StepResult, + SystemEntityRegistryPayload, SystemEntityRegistryRequest, SystemEntityRegistryResult, + SystemEntityRegistrySelector, TotalSupplyRequest, TotalSupplyResult, TrieRequest, }, global_state::{ state::{ @@ -54,14 +56,13 @@ use casper_types::{ WithdrawPurses, ARG_ERA_END_TIMESTAMP_MILLIS, ARG_EVICTED_VALIDATORS, AUCTION_DELAY_KEY, ERA_ID_KEY, METHOD_RUN_AUCTION, UNBONDING_DELAY_KEY, }, - mint::{ROUND_SEIGNIORAGE_RATE_KEY, TOTAL_SUPPLY_KEY}, AUCTION, HANDLE_PAYMENT, MINT, STANDARD_PAYMENT, }, AddressableEntity, AddressableEntityHash, AuctionCosts, ByteCode, ByteCodeAddr, ByteCodeHash, CLTyped, CLValue, Contract, DeployHash, DeployInfo, Digest, EntityAddr, EraId, Gas, HandlePaymentCosts, Key, KeyTag, MintCosts, Motes, Package, PackageHash, ProtocolUpgradeConfig, - ProtocolVersion, PublicKey, RefundHandling, StoredValue, SystemEntityRegistry, Transfer, - TransferAddr, URef, OS_PAGE_SIZE, U512, + ProtocolVersion, PublicKey, RefundHandling, StoredValue, SystemEntityRegistry, Timestamp, + TransactionHash, TransactionV1Hash, Transfer, TransferAddr, URef, OS_PAGE_SIZE, U512, }; use tempfile::TempDir; @@ -679,62 +680,128 @@ where /// Queries for the total supply of token. /// # Panics /// Panics if the total supply can't be found. - pub fn total_supply(&self, maybe_post_state: Option) -> U512 { - let mint_entity_hash = self - .get_system_entity_hash(MINT) - .expect("should have mint_contract_hash"); - - let mint_key = Key::addressable_entity_key(EntityKindTag::System, mint_entity_hash); - - let result = self.query(maybe_post_state, mint_key, &[TOTAL_SUPPLY_KEY.to_string()]); - - let total_supply: U512 = if let Ok(StoredValue::CLValue(total_supply)) = result { - total_supply.into_t().expect("total supply should be U512") + pub fn total_supply( + &self, + maybe_post_state: Option, + protocol_version: ProtocolVersion, + ) -> U512 { + let post_state = maybe_post_state + .or(self.post_state_hash) + .expect("builder must have a post-state hash"); + let result = self + .data_access_layer + .total_supply(TotalSupplyRequest::new(post_state, protocol_version)); + if let TotalSupplyResult::Success { total_supply } = result { + total_supply } else { - panic!("mint should track total supply"); - }; + panic!("total supply should exist at every root hash {:?}", result); + } + } - total_supply + /// Queries for the round seigniorage rate. + /// # Panics + /// Panics if the total supply or seigniorage rate can't be found. + pub fn round_seigniorage_rate( + &mut self, + maybe_post_state: Option, + protocol_version: ProtocolVersion, + ) -> Ratio { + let post_state = maybe_post_state + .or(self.post_state_hash) + .expect("builder must have a post-state hash"); + let result = + self.data_access_layer + .round_seigniorage_rate(RoundSeigniorageRateRequest::new( + post_state, + protocol_version, + )); + if let RoundSeigniorageRateResult::Success { rate } = result { + rate + } else { + panic!( + "round seigniorage rate should exist at every root hash {:?}", + result + ); + } } /// Queries for the base round reward. /// # Panics /// Panics if the total supply or seigniorage rate can't be found. - pub fn base_round_reward(&mut self, maybe_post_state: Option) -> U512 { - let mint_named_keys = - self.get_named_keys(EntityAddr::System(self.get_mint_contract_hash().value())); - - let total_supply_uref = *mint_named_keys - .get(TOTAL_SUPPLY_KEY) - .expect("must track total supply") - .as_uref() - .expect("must get uref"); - - let round_seigniorage_rate_uref = *mint_named_keys - .get(ROUND_SEIGNIORAGE_RATE_KEY) - .expect("must track round seigniorage rate"); - - let total_supply = self - .query(maybe_post_state, Key::URef(total_supply_uref), &[]) - .expect("must read value under total supply URef") - .into_cl_value() - .expect("must convert into CL value") - .into_t::() - .expect("must convert into U512"); - - let rate = self - .query(maybe_post_state, round_seigniorage_rate_uref, &[]) - .expect("must read value") - .into_cl_value() - .expect("must conver to cl value") - .into_t::>() - .expect("must conver to ratio"); - + pub fn base_round_reward( + &mut self, + maybe_post_state: Option, + protocol_version: ProtocolVersion, + ) -> U512 { + let post_state = maybe_post_state + .or(self.post_state_hash) + .expect("builder must have a post-state hash"); + let total_supply = self.total_supply(Some(post_state), protocol_version); + let rate = self.round_seigniorage_rate(Some(post_state), protocol_version); rate.checked_mul(&Ratio::from(total_supply)) .map(|ratio| ratio.to_integer()) .expect("must get base round reward") } + /// Direct auction interactions for stake management. + pub fn bidding( + &mut self, + maybe_post_state: Option, + maybe_block_time: Option, + protocol_version: ProtocolVersion, + account_hash: AccountHash, + auction_method: AuctionMethod, + ) -> BiddingResult { + let post_state = maybe_post_state + .or(self.post_state_hash) + .expect("builder must have a post-state hash"); + + let block_time = maybe_block_time.unwrap_or(Timestamp::now()).millis(); + let transaction_hash = TransactionHash::V1(TransactionV1Hash::default()); + let authorization_keys = BTreeSet::from_iter(vec![account_hash]); + + let config = &self.chainspec; + let fee_handling = config.core_config.fee_handling; + let refund_handling = config.core_config.refund_handling; + let vesting_schedule_period_millis = config.core_config.vesting_schedule_period.millis(); + let allow_auction_bids = config.core_config.allow_auction_bids; + let compute_rewards = config.core_config.compute_rewards; + let max_delegators_per_validator = config.core_config.max_delegators_per_validator; + let minimum_delegation_amount = config.core_config.minimum_delegation_amount; + let balance_hold_interval = config.core_config.balance_hold_interval.millis(); + + let native_runtime_config = casper_storage::system::runtime_native::Config::new( + TransferConfig::Unadministered, + fee_handling, + refund_handling, + vesting_schedule_period_millis, + allow_auction_bids, + compute_rewards, + max_delegators_per_validator, + minimum_delegation_amount, + balance_hold_interval, + ); + + let bidding_req = BiddingRequest::new( + native_runtime_config, + post_state, + block_time, + protocol_version, + transaction_hash, + account_hash, + authorization_keys, + auction_method, + ); + let ret = self.data_access_layer().bidding(bidding_req); + if let BiddingResult::Success { + post_state_hash, .. + } = ret + { + self.post_state_hash = Some(post_state_hash); + } + ret + } + /// Runs an [`ExecuteRequest`]. pub fn exec(&mut self, mut exec_request: ExecuteRequest) -> &mut Self { let exec_request = { @@ -878,13 +945,15 @@ where block_time: u64, ) -> FeeResult { let native_runtime_config = self.native_runtime_config(); - + let holds_epoch = Some( + block_time.saturating_sub(self.chainspec.core_config.balance_hold_interval.millis()), + ); let pre_state_hash = pre_state_hash.or(self.post_state_hash).unwrap(); let fee_req = FeeRequest::new( native_runtime_config, pre_state_hash, protocol_version, - block_time, + holds_epoch, ); let fee_result = self.data_access_layer.distribute_fees(fee_req); diff --git a/execution_engine_testing/tests/benches/transfer_bench.rs b/execution_engine_testing/tests/benches/transfer_bench.rs index 389919d21b..d09be0b5c3 100644 --- a/execution_engine_testing/tests/benches/transfer_bench.rs +++ b/execution_engine_testing/tests/benches/transfer_bench.rs @@ -9,8 +9,7 @@ use tempfile::TempDir; use casper_engine_test_support::{ ChainspecConfig, DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, - DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, - PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_execution_engine::engine_state::ExecuteRequest; use casper_types::{account::AccountHash, runtime_args, Key, URef, U512}; @@ -53,7 +52,7 @@ fn bootstrap(data_dir: &Path, accounts: Vec, amount: U512) -> LmdbW let mut builder = LmdbWasmTestBuilder::new_with_config(data_dir, ChainspecConfig::default()); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .expect_success() .commit(); diff --git a/execution_engine_testing/tests/src/test/chainspec_registry.rs b/execution_engine_testing/tests/src/test/chainspec_registry.rs index 8f00fd7fc0..ab5ed5a189 100644 --- a/execution_engine_testing/tests/src/test/chainspec_registry.rs +++ b/execution_engine_testing/tests/src/test/chainspec_registry.rs @@ -4,7 +4,7 @@ use tempfile::TempDir; use casper_engine_test_support::{ LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_EXEC_CONFIG, DEFAULT_GENESIS_CONFIG_HASH, - DEFAULT_PROTOCOL_VERSION, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PROTOCOL_VERSION, LOCAL_GENESIS_REQUEST, }; use casper_storage::data_access_layer::GenesisRequest; use casper_types::{ChainspecRegistry, Digest, EraId, Key, ProtocolVersion}; @@ -99,7 +99,7 @@ fn should_upgrade_chainspec_registry(cfg: TestConfig) { builder } else { let mut builder = LmdbWasmTestBuilder::new(data_dir.path()); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder }; diff --git a/execution_engine_testing/tests/src/test/contract_api/account/associated_keys.rs b/execution_engine_testing/tests/src/test/contract_api/account/associated_keys.rs index fbe7fe1ceb..86b62c066d 100644 --- a/execution_engine_testing/tests/src/test/contract_api/account/associated_keys.rs +++ b/execution_engine_testing/tests/src/test/contract_api/account/associated_keys.rs @@ -2,7 +2,7 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, - PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, }; use casper_types::{account::AccountHash, addressable_entity::Weight, runtime_args, U512}; @@ -34,9 +34,7 @@ fn should_manage_associated_key() { ) .build(); - builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) - .commit(); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()).commit(); builder.exec(exec_request_1).expect_success().commit(); diff --git a/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs b/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs index 4cb410d868..b17e9cd687 100644 --- a/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs +++ b/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, ARG_AMOUNT, - DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{ engine_state::{self, Error}, @@ -37,7 +37,7 @@ fn should_deploy_with_authorized_identity_key() { .build(); // Basic deploy with single key LmdbWasmTestBuilder::default() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .commit() .expect_success(); @@ -70,7 +70,7 @@ fn should_raise_auth_failure_with_invalid_key() { // Basic deploy with single key let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .commit(); @@ -126,7 +126,7 @@ fn should_raise_auth_failure_with_invalid_keys() { // Basic deploy with single key let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .commit(); @@ -192,7 +192,7 @@ fn should_raise_deploy_authorization_failure() { // Basic deploy with single key let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) // Reusing a test contract that would add new key .exec(exec_request_1) .expect_success() @@ -353,7 +353,7 @@ fn should_authorize_deploy_with_multiple_keys() { // Basic deploy with single key let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) // Reusing a test contract that would add new key .exec(exec_request_1) .expect_success() @@ -420,7 +420,7 @@ fn should_not_authorize_deploy_with_duplicated_keys() { .build(); // Basic deploy with single key let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder // Reusing a test contract that would add new key @@ -508,7 +508,7 @@ fn should_not_authorize_transfer_without_deploy_key_threshold() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) // Reusing a test contract that would add new key .exec(add_key_1_request) .expect_success() diff --git a/execution_engine_testing/tests/src/test/contract_api/account/key_management_thresholds.rs b/execution_engine_testing/tests/src/test/contract_api/account/key_management_thresholds.rs index 3d43f5f3bb..c145a05484 100644 --- a/execution_engine_testing/tests/src/test/contract_api/account/key_management_thresholds.rs +++ b/execution_engine_testing/tests/src/test/contract_api/account/key_management_thresholds.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, ARG_AMOUNT, - DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_types::{account::AccountHash, runtime_args}; @@ -24,7 +24,7 @@ fn should_verify_key_management_permission_with_low_weight() { ) .build(); LmdbWasmTestBuilder::default() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request_1) .expect_success() .commit() @@ -61,7 +61,7 @@ fn should_verify_key_management_permission_with_sufficient_weight() { ExecuteRequestBuilder::from_deploy_item(deploy).build() }; LmdbWasmTestBuilder::default() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request_1) .expect_success() .commit() diff --git a/execution_engine_testing/tests/src/test/contract_api/account/named_keys.rs b/execution_engine_testing/tests/src/test/contract_api/account/named_keys.rs index 1a03dd35a8..7098b23c19 100644 --- a/execution_engine_testing/tests/src/test/contract_api/account/named_keys.rs +++ b/execution_engine_testing/tests/src/test/contract_api/account/named_keys.rs @@ -1,8 +1,7 @@ use std::convert::TryFrom; use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::{bytesrepr::FromBytes, runtime_args, CLTyped, CLValue, Key, U512}; @@ -44,7 +43,7 @@ fn read_value(builder: &mut LmdbWasmTestBuilder, key: Ke fn should_run_named_keys_contract() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); run_command(&mut builder, COMMAND_CREATE_UREF1); diff --git a/execution_engine_testing/tests/src/test/contract_api/account/named_keys_stored.rs b/execution_engine_testing/tests/src/test/contract_api/account/named_keys_stored.rs index 17cf9b4847..2fc1c1fd8d 100644 --- a/execution_engine_testing/tests/src/test/contract_api/account/named_keys_stored.rs +++ b/execution_engine_testing/tests/src/test/contract_api/account/named_keys_stored.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::execution::ExecError; use casper_types::{runtime_args, ApiError, RuntimeArgs}; @@ -95,7 +94,7 @@ fn should_run_stored_named_keys_module_bytes_to_contract_to_contract() { fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request_1 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, "named_keys_stored.wasm", diff --git a/execution_engine_testing/tests/src/test/contract_api/create_purse.rs b/execution_engine_testing/tests/src/test/contract_api/create_purse.rs index b28c7eceb3..1abb7fadad 100644 --- a/execution_engine_testing/tests/src/test/contract_api/create_purse.rs +++ b/execution_engine_testing/tests/src/test/contract_api/create_purse.rs @@ -2,7 +2,7 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, - PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, }; use casper_types::{account::AccountHash, runtime_args, U512}; @@ -33,7 +33,7 @@ fn should_insert_account_into_named_keys() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).expect_success().commit(); @@ -67,7 +67,7 @@ fn should_create_usable_purse() { .build(); let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request_1) .expect_success() .commit() diff --git a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs index 04e2ac88ec..3a304f5b7d 100644 --- a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs +++ b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs @@ -2,8 +2,8 @@ use casper_engine_test_support::{ utils::create_genesis_config, DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, ARG_AMOUNT, DEFAULT_ACCOUNTS, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_ACCOUNT_PUBLIC_KEY, DEFAULT_CHAINSPEC_REGISTRY, DEFAULT_GENESIS_CONFIG_HASH, - DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, MINIMUM_ACCOUNT_CREATION_BALANCE, - PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, LOCAL_GENESIS_REQUEST, + MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_execution_engine::{engine_state::Error as EngineError, execution::ExecError}; use casper_storage::data_access_layer::GenesisRequest; @@ -26,7 +26,7 @@ const ACCOUNT_1_ADDR: AccountHash = AccountHash::new([1u8; 32]); fn setup() -> (LmdbWasmTestBuilder, AddressableEntityHash) { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let fund_request = ExecuteRequestBuilder::transfer( *DEFAULT_ACCOUNT_ADDR, @@ -460,7 +460,7 @@ fn should_fail_get_with_invalid_dictionary_item_key() { fn dictionary_put_should_fail_with_large_item_key() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let fund_request = ExecuteRequestBuilder::transfer( *DEFAULT_ACCOUNT_ADDR, @@ -501,7 +501,7 @@ fn dictionary_put_should_fail_with_large_item_key() { fn dictionary_get_should_fail_with_large_item_key() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let fund_request = ExecuteRequestBuilder::transfer( *DEFAULT_ACCOUNT_ADDR, @@ -664,7 +664,7 @@ fn should_query_dictionary_items_with_test_builder() { #[test] fn should_be_able_to_perform_dictionary_read() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let dictionary_session_call = ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, DICTIONARY_READ, RuntimeArgs::new()) @@ -680,7 +680,7 @@ fn should_be_able_to_perform_dictionary_read() { #[test] fn should_be_able_to_perform_read_from_key() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let read_from_key_session_call = ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, READ_FROM_KEY, RuntimeArgs::new()) diff --git a/execution_engine_testing/tests/src/test/contract_api/get_arg.rs b/execution_engine_testing/tests/src/test/contract_api/get_arg.rs index ad548a0710..fa802e21a9 100644 --- a/execution_engine_testing/tests/src/test/contract_api/get_arg.rs +++ b/execution_engine_testing/tests/src/test/contract_api/get_arg.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - utils, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + utils, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::{runtime_args, ApiError, RuntimeArgs, U512}; @@ -17,7 +16,7 @@ fn call_get_arg(args: RuntimeArgs) -> Result<(), String> { ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CONTRACT_GET_ARG, args).build(); let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .commit(); diff --git a/execution_engine_testing/tests/src/test/contract_api/get_blocktime.rs b/execution_engine_testing/tests/src/test/contract_api/get_blocktime.rs index 033897ba20..0b65a29dca 100644 --- a/execution_engine_testing/tests/src/test/contract_api/get_blocktime.rs +++ b/execution_engine_testing/tests/src/test/contract_api/get_blocktime.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::runtime_args; @@ -20,7 +19,7 @@ fn should_run_get_blocktime_contract() { .with_block_time(block_time) .build(); LmdbWasmTestBuilder::default() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .commit() .expect_success(); diff --git a/execution_engine_testing/tests/src/test/contract_api/get_caller.rs b/execution_engine_testing/tests/src/test/contract_api/get_caller.rs index 2f0d2b8e1c..7e369eb846 100644 --- a/execution_engine_testing/tests/src/test/contract_api/get_caller.rs +++ b/execution_engine_testing/tests/src/test/contract_api/get_caller.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, - PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, }; use casper_types::{account::AccountHash, runtime_args}; @@ -13,7 +13,7 @@ const ACCOUNT_1_ADDR: AccountHash = AccountHash::new([1u8; 32]); #[test] fn should_run_get_caller_contract() { LmdbWasmTestBuilder::default() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec( ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -31,7 +31,7 @@ fn should_run_get_caller_contract() { fn should_run_get_caller_contract_other_account() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder .exec( @@ -63,7 +63,7 @@ fn should_run_get_caller_contract_other_account() { fn should_run_get_caller_subcall_contract() { { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder .exec( @@ -80,7 +80,7 @@ fn should_run_get_caller_subcall_contract() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec( ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, diff --git a/execution_engine_testing/tests/src/test/contract_api/get_phase.rs b/execution_engine_testing/tests/src/test/contract_api/get_phase.rs index 578257c57f..c89ead88cc 100644 --- a/execution_engine_testing/tests/src/test/contract_api/get_phase.rs +++ b/execution_engine_testing/tests/src/test/contract_api/get_phase.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_types::{runtime_args, Phase}; @@ -34,7 +34,7 @@ fn should_run_get_phase_contract() { }; LmdbWasmTestBuilder::default() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .commit() .expect_success(); diff --git a/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs b/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs index d282c9b655..8cf69f81ea 100644 --- a/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs +++ b/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_execution_engine::{engine_state::Error, execution::ExecError}; use casper_types::{ @@ -134,7 +134,7 @@ fn test_match( fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); for account in [*ACCOUNT_1_ADDR, *ACCOUNT_2_ADDR] { let add_key_request = { diff --git a/execution_engine_testing/tests/src/test/contract_api/list_named_keys.rs b/execution_engine_testing/tests/src/test/contract_api/list_named_keys.rs index 1e33837ec8..869d07b006 100644 --- a/execution_engine_testing/tests/src/test/contract_api/list_named_keys.rs +++ b/execution_engine_testing/tests/src/test/contract_api/list_named_keys.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::{account::AccountHash, addressable_entity::NamedKeys, runtime_args, Key}; @@ -14,7 +13,7 @@ const ARG_NEW_NAMED_KEYS: &str = "new_named_keys"; #[test] fn should_list_named_keys() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let initial_named_keys: NamedKeys = NamedKeys::new(); diff --git a/execution_engine_testing/tests/src/test/contract_api/main_purse.rs b/execution_engine_testing/tests/src/test/contract_api/main_purse.rs index 5a1fd0049c..330ec9a014 100644 --- a/execution_engine_testing/tests/src/test/contract_api/main_purse.rs +++ b/execution_engine_testing/tests/src/test/contract_api/main_purse.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, - PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, }; use casper_types::{account::AccountHash, runtime_args}; @@ -15,7 +15,7 @@ const ARG_AMOUNT: &str = "amount"; fn should_run_main_purse_contract_default_account() { let mut builder = LmdbWasmTestBuilder::default(); - let builder = builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + let builder = builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -44,7 +44,7 @@ fn should_run_main_purse_contract_account_1() { .build(); let builder = builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request_1) .expect_success() .commit(); diff --git a/execution_engine_testing/tests/src/test/contract_api/mint_purse.rs b/execution_engine_testing/tests/src/test/contract_api/mint_purse.rs index 31d18cd74a..347246ceb1 100644 --- a/execution_engine_testing/tests/src/test/contract_api/mint_purse.rs +++ b/execution_engine_testing/tests/src/test/contract_api/mint_purse.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, SYSTEM_ADDR, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, + MINIMUM_ACCOUNT_CREATION_BALANCE, SYSTEM_ADDR, }; use casper_types::{runtime_args, RuntimeArgs, U512}; @@ -23,7 +23,7 @@ fn should_run_mint_purse_contract() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).commit().expect_success(); builder.exec(exec_request_2).commit().expect_success(); @@ -40,7 +40,7 @@ fn should_not_allow_non_system_accounts_to_mint() { .build(); assert!(LmdbWasmTestBuilder::default() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .commit() .is_error()); diff --git a/execution_engine_testing/tests/src/test/contract_api/multisig_authorization.rs b/execution_engine_testing/tests/src/test/contract_api/multisig_authorization.rs index 4419685c58..dfdb46e21c 100644 --- a/execution_engine_testing/tests/src/test/contract_api/multisig_authorization.rs +++ b/execution_engine_testing/tests/src/test/contract_api/multisig_authorization.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state::Error, execution::ExecError}; use casper_types::{ @@ -175,7 +175,7 @@ fn test_multisig_auth( fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); for account in ROLE_A_KEYS.iter().chain(&ROLE_B_KEYS) { let add_key_request = { diff --git a/execution_engine_testing/tests/src/test/contract_api/named_dictionaries.rs b/execution_engine_testing/tests/src/test/contract_api/named_dictionaries.rs index ad6a7f056b..41764f61b0 100644 --- a/execution_engine_testing/tests/src/test/contract_api/named_dictionaries.rs +++ b/execution_engine_testing/tests/src/test/contract_api/named_dictionaries.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::runtime_args; use rand::{rngs::StdRng, Rng, SeedableRng}; @@ -20,7 +19,7 @@ fn named_dictionaries_should_work_as_expected() { .collect(); let builder = &mut LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder .exec( ExecuteRequestBuilder::standard( diff --git a/execution_engine_testing/tests/src/test/contract_api/revert.rs b/execution_engine_testing/tests/src/test/contract_api/revert.rs index ea8b4e6aa5..56ab34bedb 100644 --- a/execution_engine_testing/tests/src/test/contract_api/revert.rs +++ b/execution_engine_testing/tests/src/test/contract_api/revert.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::RuntimeArgs; @@ -13,7 +12,7 @@ fn should_revert() { ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, REVERT_WASM, RuntimeArgs::default()) .build(); LmdbWasmTestBuilder::default() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .commit() .is_error(); diff --git a/execution_engine_testing/tests/src/test/contract_api/runtime.rs b/execution_engine_testing/tests/src/test/contract_api/runtime.rs index 8939bcca39..d2b67b3446 100644 --- a/execution_engine_testing/tests/src/test/contract_api/runtime.rs +++ b/execution_engine_testing/tests/src/test/contract_api/runtime.rs @@ -4,7 +4,7 @@ use rand::Rng; use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::runtime_context::RANDOM_BYTES_COUNT; use casper_storage::address_generator::ADDRESS_LENGTH; @@ -42,7 +42,7 @@ fn get_value(builder: &LmdbWasmTestBuilder, result: &str) -> #[test] fn should_return_different_random_bytes_on_different_phases() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let execute_request = { let mut rng = rand::thread_rng(); @@ -79,7 +79,7 @@ fn should_return_different_random_bytes_on_each_call() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let all_addresses: HashSet<_> = (0..RUNS) .map(|_| { @@ -109,7 +109,7 @@ fn should_hash() { let mut rng = rand::thread_rng(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); for _ in 0..RUNS { let input: [u8; INPUT_LENGTH] = rng.gen(); diff --git a/execution_engine_testing/tests/src/test/contract_api/subcall.rs b/execution_engine_testing/tests/src/test/contract_api/subcall.rs index 2cca9dedf5..fb015a6421 100644 --- a/execution_engine_testing/tests/src/test/contract_api/subcall.rs +++ b/execution_engine_testing/tests/src/test/contract_api/subcall.rs @@ -1,8 +1,7 @@ use num_traits::cast::AsPrimitive; use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::{ package::ENTITY_INITIAL_VERSION, runtime_args, RuntimeArgs, StorageCosts, U512, @@ -43,7 +42,7 @@ fn should_charge_gas_for_subcall() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(do_nothing_request).expect_success().commit(); @@ -131,7 +130,7 @@ fn should_add_all_gas_for_subcall() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder .exec(add_zero_gas_from_session_request) @@ -187,7 +186,7 @@ fn expensive_subcall_should_cost_more() { let mut builder = LmdbWasmTestBuilder::default(); // store the contracts first - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder .exec(store_do_nothing_request) diff --git a/execution_engine_testing/tests/src/test/contract_api/transfer.rs b/execution_engine_testing/tests/src/test/contract_api/transfer.rs index e1502d274a..1b6056113a 100644 --- a/execution_engine_testing/tests/src/test/contract_api/transfer.rs +++ b/execution_engine_testing/tests/src/test/contract_api/transfer.rs @@ -3,8 +3,8 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, - PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, + MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_execution_engine::{engine_state::Error as EngineError, execution::ExecError}; use casper_types::{ @@ -54,7 +54,7 @@ fn should_transfer_to_account() { // Run genesis let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -107,7 +107,7 @@ fn should_transfer_to_public_key() { // Run genesis let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -158,7 +158,7 @@ fn should_transfer_from_purse_to_public_key() { // Run genesis let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // Create a funded a purse, and store it in named keys let exec_request_1 = ExecuteRequestBuilder::standard( @@ -240,7 +240,7 @@ fn should_transfer_from_account_to_account() { // Run genesis let mut builder = LmdbWasmTestBuilder::default(); - let builder = builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + let builder = builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -330,7 +330,7 @@ fn should_transfer_to_existing_account() { // Run genesis let mut builder = LmdbWasmTestBuilder::default(); - let builder = builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + let builder = builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -447,7 +447,7 @@ fn should_fail_when_insufficient_funds() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) // Exec transfer contract .exec(exec_request_1) .expect_success() @@ -490,7 +490,7 @@ fn should_transfer_total_amount() { ) .build(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).expect_success().commit(); diff --git a/execution_engine_testing/tests/src/test/contract_api/transfer_cached.rs b/execution_engine_testing/tests/src/test/contract_api/transfer_cached.rs index da5c9261f9..c5785120d4 100644 --- a/execution_engine_testing/tests/src/test/contract_api/transfer_cached.rs +++ b/execution_engine_testing/tests/src/test/contract_api/transfer_cached.rs @@ -4,7 +4,7 @@ use tempfile::TempDir; use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_ACCOUNT_INITIAL_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_INITIAL_BALANCE, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::engine_state::{DeployItem, MAX_PAYMENT_AMOUNT}; use casper_types::{ @@ -36,7 +36,7 @@ fn should_transfer_to_account_with_correct_balances() { let data_dir = TempDir::new().expect("should create temp dir"); let mut builder = LmdbWasmTestBuilder::new(data_dir.path()); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let pre_state_hash = builder.get_post_state_hash(); @@ -93,7 +93,7 @@ fn should_transfer_from_default_and_then_to_another_account() { let data_dir = TempDir::new().expect("should create temp dir"); let mut builder = LmdbWasmTestBuilder::new(data_dir.path()); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let pre_state_hash = builder.get_post_state_hash(); diff --git a/execution_engine_testing/tests/src/test/contract_api/transfer_purse_to_account.rs b/execution_engine_testing/tests/src/test/contract_api/transfer_purse_to_account.rs index 6d414e22a6..7f056cde43 100644 --- a/execution_engine_testing/tests/src/test/contract_api/transfer_purse_to_account.rs +++ b/execution_engine_testing/tests/src/test/contract_api/transfer_purse_to_account.rs @@ -3,7 +3,7 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_types::{ account::AccountHash, @@ -24,7 +24,7 @@ static ACCOUNT_1_INITIAL_FUND: Lazy = Lazy::new(|| *DEFAULT_PAYMENT + 42); #[test] fn should_run_purse_to_account_transfer() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let account_1_account_hash = ACCOUNT_1_ADDR; assert!( @@ -69,7 +69,7 @@ fn should_fail_when_sending_too_much_from_purse_to_account() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).expect_failure().commit(); diff --git a/execution_engine_testing/tests/src/test/contract_api/transfer_purse_to_purse.rs b/execution_engine_testing/tests/src/test/contract_api/transfer_purse_to_purse.rs index ceb613ad05..db0c38f0de 100644 --- a/execution_engine_testing/tests/src/test/contract_api/transfer_purse_to_purse.rs +++ b/execution_engine_testing/tests/src/test/contract_api/transfer_purse_to_purse.rs @@ -4,7 +4,7 @@ use casper_types::{runtime_args, system::mint, ApiError, CLValue, U512}; use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; const CONTRACT_TRANSFER_PURSE_TO_PURSE: &str = "transfer_purse_to_purse.wasm"; @@ -32,7 +32,7 @@ fn should_run_purse_to_purse_transfer() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request_1) .expect_success() .commit(); @@ -103,7 +103,7 @@ fn should_run_purse_to_purse_transfer_with_error() { .build(); let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request_1) .expect_success() .commit(); diff --git a/execution_engine_testing/tests/src/test/contract_context.rs b/execution_engine_testing/tests/src/test/contract_context.rs index 850cd237aa..99fe0e1bd1 100644 --- a/execution_engine_testing/tests/src/test/contract_context.rs +++ b/execution_engine_testing/tests/src/test/contract_context.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::{package::ENTITY_INITIAL_VERSION, runtime_args, Key, RuntimeArgs}; @@ -38,7 +37,7 @@ fn should_enforce_intended_execution_contexts() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).expect_success().commit(); @@ -95,7 +94,7 @@ fn should_enforce_intended_execution_context_direct_by_name() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).expect_success().commit(); @@ -130,7 +129,7 @@ fn should_enforce_intended_execution_context_direct_by_hash() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).expect_success().commit(); diff --git a/execution_engine_testing/tests/src/test/contract_messages.rs b/execution_engine_testing/tests/src/test/contract_messages.rs index ac650a8c6e..5b6cfda8d9 100644 --- a/execution_engine_testing/tests/src/test/contract_messages.rs +++ b/execution_engine_testing/tests/src/test/contract_messages.rs @@ -3,7 +3,7 @@ use std::cell::RefCell; use casper_engine_test_support::{ ChainspecConfig, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_BLOCK_TIME, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_BLOCK_TIME, LOCAL_GENESIS_REQUEST, }; use casper_types::{ bytesrepr::ToBytes, @@ -239,7 +239,7 @@ fn should_emit_messages() { let builder = RefCell::new(LmdbWasmTestBuilder::default()); builder .borrow_mut() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + .run_genesis(LOCAL_GENESIS_REQUEST.clone()); let contract_hash = install_messages_emitter_contract(&builder, true); let query_view = ContractQueryView::new(&builder, contract_hash); @@ -331,7 +331,7 @@ fn should_emit_message_on_empty_topic_in_new_block() { let builder = RefCell::new(LmdbWasmTestBuilder::default()); builder .borrow_mut() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + .run_genesis(LOCAL_GENESIS_REQUEST.clone()); let contract_hash = install_messages_emitter_contract(&builder, true); let query_view = ContractQueryView::new(&builder, contract_hash); @@ -370,7 +370,7 @@ fn should_add_topics() { let builder = RefCell::new(LmdbWasmTestBuilder::default()); builder .borrow_mut() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + .run_genesis(LOCAL_GENESIS_REQUEST.clone()); let contract_hash = install_messages_emitter_contract(&builder, true); let query_view = ContractQueryView::new(&builder, contract_hash); @@ -434,7 +434,7 @@ fn should_not_add_duplicate_topics() { let builder = RefCell::new(LmdbWasmTestBuilder::default()); builder .borrow_mut() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + .run_genesis(LOCAL_GENESIS_REQUEST.clone()); let contract_hash = install_messages_emitter_contract(&builder, true); let query_view = ContractQueryView::new(&builder, contract_hash); @@ -488,7 +488,7 @@ fn should_not_exceed_configured_limits() { let builder = RefCell::new(LmdbWasmTestBuilder::new_temporary_with_config(chainspec)); builder .borrow_mut() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + .run_genesis(LOCAL_GENESIS_REQUEST.clone()); let contract_hash = install_messages_emitter_contract(&builder, true); @@ -572,7 +572,7 @@ fn should_carry_message_topics_on_upgraded_contract(use_initializer: bool) { let builder = RefCell::new(LmdbWasmTestBuilder::default()); builder .borrow_mut() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + .run_genesis(LOCAL_GENESIS_REQUEST.clone()); let _ = install_messages_emitter_contract(&builder, true); let contract_hash = upgrade_messages_emitter_contract(&builder, use_initializer, false); @@ -611,7 +611,7 @@ fn should_not_emit_messages_from_account() { let builder = RefCell::new(LmdbWasmTestBuilder::default()); builder .borrow_mut() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + .run_genesis(LOCAL_GENESIS_REQUEST.clone()); // Request to run a deploy that tries to register a message topic without a stored contract. let install_request = ExecuteRequestBuilder::standard( @@ -650,7 +650,7 @@ fn should_charge_expected_gas_for_storage() { let builder = RefCell::new(LmdbWasmTestBuilder::new_temporary_with_config(chainspec)); builder .borrow_mut() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + .run_genesis(LOCAL_GENESIS_REQUEST.clone()); let contract_hash = install_messages_emitter_contract(&builder, true); let query_view = ContractQueryView::new(&builder, contract_hash); @@ -753,7 +753,7 @@ fn should_charge_increasing_gas_cost_for_multiple_messages_emitted() { let builder = RefCell::new(LmdbWasmTestBuilder::new_temporary_with_config(chainspec)); builder .borrow_mut() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + .run_genesis(LOCAL_GENESIS_REQUEST.clone()); let contract_hash = install_messages_emitter_contract(&builder, true); @@ -823,7 +823,7 @@ fn should_register_topic_on_contract_creation() { let builder = RefCell::new(LmdbWasmTestBuilder::default()); builder .borrow_mut() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + .run_genesis(LOCAL_GENESIS_REQUEST.clone()); let contract_hash = install_messages_emitter_contract(&builder, false); let query_view = ContractQueryView::new(&builder, contract_hash); @@ -870,7 +870,7 @@ fn should_not_exceed_configured_topic_name_limits_on_contract_upgrade_no_init() let builder = RefCell::new(LmdbWasmTestBuilder::new_temporary_with_config(chainspec)); builder .borrow_mut() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + .run_genesis(LOCAL_GENESIS_REQUEST.clone()); let _ = install_messages_emitter_contract(&builder, false); let _ = upgrade_messages_emitter_contract(&builder, false, true); @@ -902,7 +902,7 @@ fn should_not_exceed_configured_max_topics_per_contract_upgrade_no_init() { let builder = RefCell::new(LmdbWasmTestBuilder::new_temporary_with_config(chainspec)); builder .borrow_mut() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + .run_genesis(LOCAL_GENESIS_REQUEST.clone()); let _ = install_messages_emitter_contract(&builder, false); let _ = upgrade_messages_emitter_contract(&builder, false, true); diff --git a/execution_engine_testing/tests/src/test/counter_factory.rs b/execution_engine_testing/tests/src/test/counter_factory.rs index 5c54279498..b9af4aae07 100644 --- a/execution_engine_testing/tests/src/test/counter_factory.rs +++ b/execution_engine_testing/tests/src/test/counter_factory.rs @@ -2,8 +2,7 @@ use std::{collections::BTreeSet, iter::FromIterator}; use crate::wasm_utils; use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state::Error, execution::ExecError}; use casper_types::{ @@ -222,7 +221,7 @@ fn should_install_and_use_factory_pattern() { fn setup() -> (LmdbWasmTestBuilder, AddressableEntityHash) { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, diff --git a/execution_engine_testing/tests/src/test/deploy/context_association.rs b/execution_engine_testing/tests/src/test/deploy/context_association.rs index 7f8f60632c..a00aa43430 100644 --- a/execution_engine_testing/tests/src/test/deploy/context_association.rs +++ b/execution_engine_testing/tests/src/test/deploy/context_association.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_ACCOUNT_KEY, DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_KEY, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_types::{ @@ -30,7 +30,7 @@ fn should_put_system_contract_hashes_to_account_context() { }; builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(request) .expect_success() .commit(); diff --git a/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs b/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs index 7adcd310aa..1205c4d9e1 100644 --- a/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs +++ b/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_types::{account::AccountHash, runtime_args, RuntimeArgs, U512}; @@ -42,7 +42,7 @@ fn should_charge_non_main_purse() { ) .build(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder .exec(setup_exec_request) diff --git a/execution_engine_testing/tests/src/test/deploy/preconditions.rs b/execution_engine_testing/tests/src/test/deploy/preconditions.rs index 16a56f7d9d..9add267cbf 100644 --- a/execution_engine_testing/tests/src/test/deploy/preconditions.rs +++ b/execution_engine_testing/tests/src/test/deploy/preconditions.rs @@ -2,7 +2,7 @@ use assert_matches::assert_matches; use casper_engine_test_support::{ utils, DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::engine_state::Error; use casper_storage::tracking_copy::TrackingCopyError; @@ -37,7 +37,7 @@ fn should_raise_precondition_authorization_failure_invalid_account() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .commit(); @@ -71,7 +71,7 @@ fn should_raise_precondition_authorization_failure_empty_authorized_keys() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .commit(); @@ -112,7 +112,7 @@ fn should_raise_precondition_authorization_failure_invalid_authorized_keys() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .commit(); diff --git a/execution_engine_testing/tests/src/test/deploy/receipts.rs b/execution_engine_testing/tests/src/test/deploy/receipts.rs index 1374e20caf..bcdb3eaf4a 100644 --- a/execution_engine_testing/tests/src/test/deploy/receipts.rs +++ b/execution_engine_testing/tests/src/test/deploy/receipts.rs @@ -3,8 +3,7 @@ use std::collections::{BTreeMap, BTreeSet}; use once_cell::sync::Lazy; use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::{ account::AccountHash, runtime_args, system::mint, AccessRights, DeployHash, PublicKey, @@ -51,7 +50,7 @@ static TRANSFER_AMOUNT_3: Lazy = Lazy::new(|| U512::from(300_100_000)); #[test] fn should_record_wasmless_transfer() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let id = Some(0); @@ -120,7 +119,7 @@ fn should_record_wasmless_transfer() { #[test] fn should_record_wasm_transfer() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let transfer_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -183,7 +182,7 @@ fn should_record_wasm_transfer() { #[test] fn should_record_wasm_transfer_with_id() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let id = Some(0); @@ -250,7 +249,7 @@ fn should_record_wasm_transfer_with_id() { #[test] fn should_record_wasm_transfers() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let alice_id = Some(0); let bob_id = Some(1); @@ -385,7 +384,7 @@ fn should_record_wasm_transfers() { #[test] fn should_record_wasm_transfers_with_subcall() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let alice_id = Some(0); let bob_id = Some(1); diff --git a/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs b/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs index 65f0d8f668..d4045e60e8 100644 --- a/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs +++ b/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs @@ -2,7 +2,7 @@ use assert_matches::assert_matches; use casper_engine_test_support::{ DeployItemBuilder, EntityWithNamedKeys, ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_INITIAL_BALANCE, - DEFAULT_ACCOUNT_KEY, DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_KEY, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state::Error, execution::ExecError}; use casper_types::{ @@ -97,7 +97,7 @@ fn should_exec_non_stored_code() { }; let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let proposer_reward_starting_balance = builder.get_proposer_purse_balance(); @@ -131,7 +131,7 @@ fn should_fail_if_calling_non_existent_entry_point() { let payment_purse_amount = *DEFAULT_PAYMENT; let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // first, store payment contract with entry point named "pay" let exec_request = ExecuteRequestBuilder::standard( @@ -190,7 +190,7 @@ fn should_exec_stored_code_by_hash() { // genesis let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // store payment let (sending_account, custom_payment_package_hash, _) = install_custom_payment(&mut builder); @@ -247,7 +247,7 @@ fn should_not_transfer_above_balance_using_stored_payment_code_by_hash() { // genesis let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // store payment let (default_account, hash, _) = install_custom_payment(&mut builder); @@ -295,7 +295,7 @@ fn should_empty_account_using_stored_payment_code_by_hash() { // genesis let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // store payment @@ -345,7 +345,7 @@ fn should_exec_stored_code_by_named_hash() { // genesis let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); install_custom_payment(&mut builder); @@ -400,7 +400,7 @@ fn should_fail_payment_stored_at_hash_with_incompatible_major_version() { .build(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request).expect_success().commit(); @@ -478,7 +478,7 @@ fn should_fail_session_stored_at_named_key_with_incompatible_major_version() { let payment_purse_amount = *DEFAULT_PAYMENT; let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // first, store payment contract for v1.0.0 let exec_request_1 = ExecuteRequestBuilder::standard( @@ -489,7 +489,7 @@ fn should_fail_session_stored_at_named_key_with_incompatible_major_version() { .build(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).commit(); @@ -586,7 +586,7 @@ fn should_fail_session_stored_at_named_key_with_missing_new_major_version() { .build(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).commit(); @@ -660,7 +660,7 @@ fn should_fail_session_stored_at_hash_with_incompatible_major_version() { let payment_purse_amount = *DEFAULT_PAYMENT; let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // first, store payment contract for v1.0.0 let exec_request_1 = ExecuteRequestBuilder::standard( @@ -671,7 +671,7 @@ fn should_fail_session_stored_at_hash_with_incompatible_major_version() { .build(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).commit(); @@ -759,7 +759,7 @@ fn should_execute_stored_payment_and_session_code_with_new_major_version() { let payment_purse_amount = *DEFAULT_PAYMENT; let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // // upgrade with new wasm costs with modified mint for given version diff --git a/execution_engine_testing/tests/src/test/explorer/faucet.rs b/execution_engine_testing/tests/src/test/explorer/faucet.rs index 90993cb01e..a11848be4a 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet.rs @@ -4,7 +4,7 @@ use casper_execution_engine::{engine_state, execution::ExecError}; use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_types::{ account::AccountHash, addressable_entity::EntityKindTag, runtime_args, system::mint, ApiError, @@ -34,7 +34,7 @@ const FAUCET_CALL_BY_USER_WITH_AUTHORIZED_ACCOUNT_SET: u16 = 25; #[test] fn should_install_faucet_contract() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let fund_installer_account_request = FundAccountRequestBuilder::new() .with_target_account(INSTALLER_ACCOUNT) @@ -133,7 +133,7 @@ fn should_install_faucet_contract() { #[test] fn should_allow_installer_to_set_variables() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let mut helper = FaucetDeployHelper::new() .with_installer_account(INSTALLER_ACCOUNT) @@ -227,7 +227,7 @@ fn should_allow_installer_to_set_variables() { fn should_fund_new_account() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let faucet_purse_fund_amount = U512::from(9_000_000_000u64); let faucet_distributions_per_interval = 3; @@ -294,7 +294,7 @@ fn should_fund_existing_account() { let user_account = AccountHash::new([7u8; 32]); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let faucet_purse_fund_amount = U512::from(9_000_000_000u64); let faucet_distributions_per_interval = 3; @@ -367,7 +367,7 @@ fn should_not_fund_once_exhausted() { let user_account = AccountHash::new([2u8; 32]); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let faucet_fund_amount = U512::from(400_000_000_000_000u64); let half_of_faucet_fund_amount = faucet_fund_amount / 2; @@ -565,7 +565,7 @@ fn should_allow_installer_to_fund_freely() { let user_account = AccountHash::new([2u8; 32]); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let faucet_fund_amount = U512::from(200_000_000_000u64); let half_of_faucet_fund_amount = faucet_fund_amount / 2; @@ -665,7 +665,7 @@ fn should_not_fund_if_zero_distributions_per_interval() { let user_account = AccountHash::new([2u8; 32]); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // Fund installer account let fund_installer_account_request = FundAccountRequestBuilder::new() @@ -723,7 +723,7 @@ fn should_allow_funding_by_an_authorized_account() { let half_of_faucet_fund_amount = faucet_fund_amount / 2; let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let mut helper = FaucetDeployHelper::new() .with_installer_account(installer_account) @@ -873,7 +873,7 @@ fn should_refund_proper_amount() { let user_account = AccountHash::new([7u8; 32]); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let payment_amount = U512::from(10_000_000_000u64); @@ -935,16 +935,16 @@ fn faucet_costs() { // This test will fail if execution costs vary. The expected costs should not be updated // without understanding why the cost has changed. If the costs do change, it should be // reflected in the "Costs by Entry Point" section of the faucet crate's README.md. - const EXPECTED_FAUCET_INSTALL_COST: u64 = 91_345_647_010; - const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_698_030; - const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_277_250; - const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_715_430; + const EXPECTED_FAUCET_INSTALL_COST: u64 = 92_469_652_420; + const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_731_720; + const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_304_280; + const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_809_400; let installer_account = AccountHash::new([1u8; 32]); let user_account: AccountHash = AccountHash::new([2u8; 32]); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let fund_installer_account_request = ExecuteRequestBuilder::transfer( *DEFAULT_ACCOUNT_ADDR, diff --git a/execution_engine_testing/tests/src/test/gas_counter.rs b/execution_engine_testing/tests/src/test/gas_counter.rs index 86068a00e7..b685910f20 100644 --- a/execution_engine_testing/tests/src/test/gas_counter.rs +++ b/execution_engine_testing/tests/src/test/gas_counter.rs @@ -6,7 +6,7 @@ use casper_wasm::{ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, ARG_AMOUNT, - DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, DEFAULT_WASM_CONFIG, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, DEFAULT_WASM_CONFIG, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state::Error, runtime::PreprocessingError}; use casper_types::{addressable_entity::DEFAULT_ENTRY_POINT_NAME, runtime_args, Gas, RuntimeArgs}; @@ -56,7 +56,7 @@ fn should_fail_to_overflow_gas_counter() { ExecuteRequestBuilder::from_deploy_item(deploy_item).build() }; - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request).commit(); @@ -151,7 +151,7 @@ fn should_correctly_measure_gas_for_opcodes() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = { let deploy_item = DeployItemBuilder::new() diff --git a/execution_engine_testing/tests/src/test/get_balance.rs b/execution_engine_testing/tests/src/test/get_balance.rs index a648b2fa74..ed6a1208cf 100644 --- a/execution_engine_testing/tests/src/test/get_balance.rs +++ b/execution_engine_testing/tests/src/test/get_balance.rs @@ -1,8 +1,7 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_storage::tracking_copy::{self, ValidationError}; use casper_types::{ @@ -27,7 +26,7 @@ static TRANSFER_AMOUNT_1: Lazy = Lazy::new(|| U512::from(100_000_000)); fn get_balance_should_work() { let protocol_version = ProtocolVersion::V2_0_0; let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let transfer_request = ExecuteRequestBuilder::transfer( *DEFAULT_ACCOUNT_ADDR, @@ -120,7 +119,7 @@ fn get_balance_should_work() { fn get_balance_using_public_key_should_work() { let protocol_version = ProtocolVersion::V2_0_0; let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let transfer_request = ExecuteRequestBuilder::transfer( *DEFAULT_ACCOUNT_ADDR, diff --git a/execution_engine_testing/tests/src/test/host_function_costs.rs b/execution_engine_testing/tests/src/test/host_function_costs.rs index 91065fb4c7..227859624e 100644 --- a/execution_engine_testing/tests/src/test/host_function_costs.rs +++ b/execution_engine_testing/tests/src/test/host_function_costs.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::{bytesrepr::Bytes, runtime_args, AddressableEntityHash, RuntimeArgs}; @@ -30,7 +29,7 @@ fn should_measure_gas_cost() { .build(); // Create Accounts - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).expect_success().commit(); @@ -98,7 +97,7 @@ fn should_measure_nested_host_function_call_cost() { .build(); // Create Accounts - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).expect_success().commit(); @@ -176,7 +175,7 @@ fn should_measure_argument_size_in_host_function_call() { .build(); // Create Accounts - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).expect_success().commit(); diff --git a/execution_engine_testing/tests/src/test/private_chain.rs b/execution_engine_testing/tests/src/test/private_chain.rs index 22b783f68d..12d3c05736 100644 --- a/execution_engine_testing/tests/src/test/private_chain.rs +++ b/execution_engine_testing/tests/src/test/private_chain.rs @@ -148,8 +148,6 @@ static DEFUALT_PRIVATE_CHAIN_EXEC_CONFIG: Lazy = Lazy::new(|| { .with_round_seigniorage_rate(DEFAULT_ROUND_SEIGNIORAGE_RATE) .with_unbonding_delay(DEFAULT_UNBONDING_DELAY) .with_genesis_timestamp_millis(DEFAULT_GENESIS_TIMESTAMP_MILLIS) - .with_refund_handling(PRIVATE_CHAIN_REFUND_HANDLING) - .with_fee_handling(PRIVATE_CHAIN_FEE_HANDLING) .build() }); diff --git a/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs b/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs index 6e3fab8503..da6f2c7cb0 100644 --- a/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs +++ b/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs @@ -1,5 +1,6 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, + ExecuteRequestBuilder, DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, + MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_types::{ runtime_args, @@ -107,6 +108,9 @@ fn test_burning_fees( fee_handling, PRIVATE_CHAIN_COMPUTE_REWARDS, ); + + let protocol_version = *DEFAULT_PROTOCOL_VERSION; + let handle_payment = builder.get_handle_payment_contract_hash(); let handle_payment_1 = builder.get_named_keys(EntityAddr::System(handle_payment.value())); let rewards_purse_key = handle_payment_1 @@ -120,7 +124,7 @@ fn test_burning_fees( RuntimeArgs::default(), ) .build(); - let total_supply_before = builder.total_supply(None); + let total_supply_before = builder.total_supply(None, protocol_version); let exec_request_1_proposer = exec_request_1.proposer.clone(); let proposer_account_1 = builder .get_entity_by_account_hash(exec_request_1_proposer.to_account_hash()) @@ -131,7 +135,7 @@ fn test_burning_fees( U512::zero(), "proposer should not receive anything", ); - let total_supply_after = builder.total_supply(None); + let total_supply_after = builder.total_supply(None, protocol_version); assert_eq!( total_supply_before - total_supply_after, expected_burn_amount, @@ -145,9 +149,9 @@ fn test_burning_fees( }; ExecuteRequestBuilder::transfer(*DEFAULT_ADMIN_ACCOUNT_ADDR, transfer_args).build() }; - let total_supply_before = builder.total_supply(None); + let total_supply_before = builder.total_supply(None, protocol_version); builder.exec(exec_request_2).expect_success().commit(); - let total_supply_after = builder.total_supply(None); + let total_supply_after = builder.total_supply(None, protocol_version); match fee_handling { FeeHandling::PayToProposer | FeeHandling::Accumulate | FeeHandling::None => { diff --git a/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs b/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs index add67b366b..555d672f13 100644 --- a/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs +++ b/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs @@ -1,7 +1,7 @@ use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_BLOCK_TIME, DEFAULT_PROPOSER_ADDR, DEFAULT_PROTOCOL_VERSION, - MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_BLOCK_TIME, DEFAULT_PROPOSER_ADDR, DEFAULT_PROTOCOL_VERSION, LOCAL_GENESIS_REQUEST, + MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_types::{ account::AccountHash, @@ -31,7 +31,7 @@ static NEW_PROTOCOL_VERSION: Lazy = Lazy::new(|| { #[test] fn default_genesis_config_should_not_have_rewards_purse() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let handle_payment = builder.get_handle_payment_contract_hash(); let handle_payment_contract = diff --git a/execution_engine_testing/tests/src/test/private_chain/management.rs b/execution_engine_testing/tests/src/test/private_chain/management.rs index bca9b6484d..bd1550a9a6 100644 --- a/execution_engine_testing/tests/src/test/private_chain/management.rs +++ b/execution_engine_testing/tests/src/test/private_chain/management.rs @@ -104,8 +104,6 @@ fn should_not_run_genesis_with_duplicated_administrator_accounts() { .with_round_seigniorage_rate(DEFAULT_ROUND_SEIGNIORAGE_RATE) .with_unbonding_delay(DEFAULT_UNBONDING_DELAY) .with_genesis_timestamp_millis(DEFAULT_GENESIS_TIMESTAMP_MILLIS) - .with_refund_handling(PRIVATE_CHAIN_REFUND_HANDLING) - .with_fee_handling(PRIVATE_CHAIN_FEE_HANDLING) .build(); let modified_genesis_request = GenesisRequest::new( diff --git a/execution_engine_testing/tests/src/test/private_chain/restricted_auction.rs b/execution_engine_testing/tests/src/test/private_chain/restricted_auction.rs index 0e522b6188..6dde897ae9 100644 --- a/execution_engine_testing/tests/src/test/private_chain/restricted_auction.rs +++ b/execution_engine_testing/tests/src/test/private_chain/restricted_auction.rs @@ -17,8 +17,9 @@ fn should_not_distribute_rewards_but_compute_next_set() { let mut builder = super::private_chain_setup(); + let protocol_version = *DEFAULT_PROTOCOL_VERSION; // initial token supply - let initial_supply = builder.total_supply(None); + let initial_supply = builder.total_supply(None, protocol_version); for _ in 0..3 { builder.distribute( @@ -100,7 +101,7 @@ fn should_not_distribute_rewards_but_compute_next_set() { era_info ); - let total_supply_after_distribution = builder.total_supply(None); + let total_supply_after_distribution = builder.total_supply(None, protocol_version); assert_eq!( initial_supply, total_supply_after_distribution, "total supply of tokens should not increase after an auction is ran" diff --git a/execution_engine_testing/tests/src/test/regression/ee_1071.rs b/execution_engine_testing/tests/src/test/regression/ee_1071.rs index 5b18f35937..5981580cd7 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1071.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1071.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::{EntityAddr, RuntimeArgs}; @@ -20,7 +19,7 @@ fn should_run_ee_1071_regression() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).expect_success().commit(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1129.rs b/execution_engine_testing/tests/src/test/regression/ee_1129.rs index 96312c12ba..ac93aca479 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1129.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1129.rs @@ -7,7 +7,7 @@ use casper_types::{GenesisAccount, GenesisValidator}; use casper_engine_test_support::{ utils, DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNTS, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_ACCOUNT_PUBLIC_KEY, - DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{ engine_state::Error, execution::ExecError, runtime::PreprocessingError, @@ -17,7 +17,7 @@ use casper_types::{ addressable_entity::DEFAULT_ENTRY_POINT_NAME, runtime_args, system::auction::{self, DelegationRate}, - Motes, PublicKey, RuntimeArgs, SecretKey, DEFAULT_ADD_BID_COST, DEFAULT_DELEGATE_COST, U512, + Motes, PublicKey, RuntimeArgs, SecretKey, DEFAULT_DELEGATE_COST, U512, }; use crate::wasm_utils; @@ -35,9 +35,8 @@ static VALIDATOR_1: Lazy = Lazy::new(|| { }); static VALIDATOR_1_ADDR: Lazy = Lazy::new(|| AccountHash::from(&*VALIDATOR_1)); const VALIDATOR_1_STAKE: u64 = 250_000; -static UNDERFUNDED_DELEGATE_AMOUNT: Lazy = - Lazy::new(|| U512::from(DEFAULT_DELEGATE_COST - 1)); -static UNDERFUNDED_ADD_BID_AMOUNT: Lazy = Lazy::new(|| U512::from(DEFAULT_ADD_BID_COST - 1)); +static UNDERFUNDED_DELEGATE_AMOUNT: Lazy = Lazy::new(|| U512::from(1)); +static UNDERFUNDED_ADD_BID_AMOUNT: Lazy = Lazy::new(|| U512::from(1)); static CALL_STORED_CONTRACT_OVERHEAD: Lazy = Lazy::new(|| U512::from(10_001)); #[ignore] @@ -67,7 +66,7 @@ fn should_run_ee_1129_underfunded_delegate_call() { let auction = builder.get_auction_contract_hash(); - let bid_amount = U512::one(); + let bid_amount = U512::from(100_000_000_000_000u64); let deploy_hash = [42; 32]; @@ -110,8 +109,6 @@ fn should_run_ee_1129_underfunded_delegate_call() { #[ignore] #[test] fn should_run_ee_1129_underfunded_add_bid_call() { - assert!(U512::from(DEFAULT_ADD_BID_COST) > *UNDERFUNDED_ADD_BID_AMOUNT); - let accounts = { let validator_1 = GenesisAccount::account( VALIDATOR_1.clone(), @@ -176,7 +173,7 @@ fn should_run_ee_1129_underfunded_add_bid_call() { fn should_run_ee_1129_underfunded_mint_contract_call() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let install_exec_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -224,7 +221,7 @@ fn should_run_ee_1129_underfunded_mint_contract_call() { fn should_not_panic_when_calling_session_contract_by_uref() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let install_exec_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -272,7 +269,7 @@ fn should_not_panic_when_calling_session_contract_by_uref() { fn should_not_panic_when_calling_payment_contract_by_uref() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let install_exec_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -318,7 +315,7 @@ fn should_not_panic_when_calling_payment_contract_by_uref() { fn should_not_panic_when_calling_contract_package_by_uref() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let install_exec_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -371,7 +368,7 @@ fn should_not_panic_when_calling_contract_package_by_uref() { fn should_not_panic_when_calling_payment_versioned_contract_by_uref() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let install_exec_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -438,7 +435,7 @@ fn do_nothing_without_memory() -> Vec { fn should_not_panic_when_calling_module_without_memory() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = { let deploy = DeployItemBuilder::new() diff --git a/execution_engine_testing/tests/src/test/regression/ee_1160.rs b/execution_engine_testing/tests/src/test/regression/ee_1160.rs index 15eb0c5d46..ad87d6fc94 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1160.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1160.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_ACCOUNT_INITIAL_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_INITIAL_BALANCE, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::engine_state::WASMLESS_TRANSFER_FIXED_GAS_PRICE; use casper_types::{ @@ -24,7 +24,7 @@ fn ee_1160_wasmless_transfer_should_empty_account() { U512::from(DEFAULT_ACCOUNT_INITIAL_BALANCE) - wasmless_transfer_cost.value(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -78,7 +78,7 @@ fn ee_1160_transfer_larger_than_balance_should_fail() { + U512::one(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -140,7 +140,7 @@ fn ee_1160_large_wasmless_transfer_should_avoid_overflow() { let transfer_amount = U512::max_value(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) diff --git a/execution_engine_testing/tests/src/test/regression/ee_1163.rs b/execution_engine_testing/tests/src/test/regression/ee_1163.rs index f0cd0ab489..cdd4015ab6 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1163.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1163.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_GAS_PRICE, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_GAS_PRICE, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::engine_state::{ Error, ExecuteRequest, WASMLESS_TRANSFER_FIXED_GAS_PRICE, @@ -18,7 +18,7 @@ const ACCOUNT_1_ADDR: AccountHash = AccountHash::new([1u8; 32]); fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder } diff --git a/execution_engine_testing/tests/src/test/regression/ee_1174.rs b/execution_engine_testing/tests/src/test/regression/ee_1174.rs index ee5c59fcf3..83777f6192 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1174.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1174.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, - PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state::Error, execution::ExecError}; @@ -21,7 +21,7 @@ fn should_run_ee_1174_delegation_rate_too_high() { let bid_amount = U512::one(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let auction = builder.get_auction_contract_hash(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1217.rs b/execution_engine_testing/tests/src/test/regression/ee_1217.rs index ff530caa2d..c31d976e0a 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1217.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1217.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, - MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_execution_engine::{ engine_state::{engine_config::DEFAULT_MINIMUM_DELEGATION_AMOUNT, Error as CoreError}, @@ -55,7 +55,7 @@ fn should_fail_to_add_bid_from_stored_session_code() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder .exec(store_call_auction_request) @@ -97,7 +97,7 @@ fn should_fail_to_add_bid_from_stored_contract_code() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder .exec(store_call_auction_request) @@ -150,7 +150,7 @@ fn should_fail_to_withdraw_bid_from_stored_session_code() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(add_bid_request).commit().expect_success(); @@ -205,7 +205,7 @@ fn should_fail_to_withdraw_bid_from_stored_contract_code() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(add_bid_request).commit().expect_success(); @@ -280,7 +280,7 @@ fn should_fail_to_delegate_from_stored_session_code() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder .exec(validator_fund_request) @@ -360,7 +360,7 @@ fn should_fail_to_delegate_from_stored_contract_code() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder .exec(validator_fund_request) @@ -428,7 +428,7 @@ fn should_fail_to_undelegate_from_stored_session_code() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let delegate_request = ExecuteRequestBuilder::contract_call_by_hash( *DEFAULT_ACCOUNT_ADDR, @@ -522,7 +522,7 @@ fn should_fail_to_undelegate_from_stored_contract_code() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let delegate_request = ExecuteRequestBuilder::contract_call_by_hash( *DEFAULT_ACCOUNT_ADDR, @@ -607,7 +607,7 @@ fn should_fail_to_activate_bid_from_stored_session_code() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(add_bid_request).commit().expect_success(); builder.exec(withdraw_bid_request).commit().expect_success(); @@ -673,7 +673,7 @@ fn should_fail_to_activate_bid_from_stored_contract_code() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(add_bid_request).commit().expect_success(); builder.exec(withdraw_bid_request).commit().expect_success(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1225.rs b/execution_engine_testing/tests/src/test/regression/ee_1225.rs index dd2e09ce23..3b08db303f 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1225.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1225.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_types::{runtime_args, RuntimeArgs}; @@ -14,7 +14,7 @@ const DO_NOTHING_CONTRACT: &str = "do_nothing.wasm"; #[test] fn should_run_ee_1225_verify_finalize_payment_invariants() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = { let deploy = DeployItemBuilder::new() diff --git a/execution_engine_testing/tests/src/test/regression/ee_221.rs b/execution_engine_testing/tests/src/test/regression/ee_221.rs index 906cbdd96c..8dde2173f0 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_221.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_221.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::RuntimeArgs; @@ -20,7 +19,7 @@ fn should_run_ee_221_get_uref_regression_test() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .expect_success() .commit(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_401.rs b/execution_engine_testing/tests/src/test/regression/ee_401.rs index 6cf99a2090..1f3c6dca04 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_401.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_401.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::RuntimeArgs; @@ -25,7 +24,7 @@ fn should_execute_contracts_which_provide_extra_urefs() { .build(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).expect_success().commit(); builder.exec(exec_request_2).expect_success().commit(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_441.rs b/execution_engine_testing/tests/src/test/regression/ee_441.rs index af29e95cd5..91d6005189 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_441.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_441.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, ARG_AMOUNT, - DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_types::{runtime_args, Key, URef}; @@ -34,7 +34,7 @@ fn do_pass(pass: &str) -> (URef, URef) { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .expect_success() .commit(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_460.rs b/execution_engine_testing/tests/src/test/regression/ee_460.rs index 22fc2f301f..6b5f6d9fce 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_460.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_460.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::{ addressable_entity::EntityKindTag, execution::TransformKind, runtime_args, Key, U512, @@ -21,7 +20,7 @@ fn should_run_ee_460_no_side_effects_on_error_regression() { .build(); let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request_1) .expect_success() .commit(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_468.rs b/execution_engine_testing/tests/src/test/regression/ee_468.rs index 624a6ef9f5..95fc6ce32b 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_468.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_468.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::RuntimeArgs; @@ -16,7 +15,7 @@ fn should_not_fail_deserializing() { ) .build(); let is_error = LmdbWasmTestBuilder::default() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .commit() .is_error(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_470.rs b/execution_engine_testing/tests/src/test/regression/ee_470.rs index 8caa2c9cf1..546b2a8bfa 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_470.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_470.rs @@ -1,8 +1,7 @@ use std::sync::Arc; use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_storage::global_state::{ state::{lmdb::LmdbGlobalState, StateProvider}, @@ -27,7 +26,7 @@ fn regression_test_genesis_hash_mismatch() { .build(); // Step 1. - let builder = builder_base.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + let builder = builder_base.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // This is trie's post state hash after calling run_genesis endpoint. // Step 1a) @@ -63,7 +62,7 @@ fn regression_test_genesis_hash_mismatch() { // No step 3. // Step 4. - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // Step 4a) let second_genesis_run_hash = builder.get_genesis_hash(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_532.rs b/execution_engine_testing/tests/src/test/regression/ee_532.rs index 373aff0b04..4433910e0e 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_532.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_532.rs @@ -1,5 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::engine_state::Error; use casper_storage::tracking_copy::TrackingCopyError; @@ -20,7 +20,7 @@ fn should_run_ee_532_non_existent_account_regression_test() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .commit(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_536.rs b/execution_engine_testing/tests/src/test/regression/ee_536.rs index d2421bf300..8761d8667c 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_536.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_536.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::RuntimeArgs; @@ -18,7 +17,7 @@ fn should_run_ee_536_associated_account_management_regression() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .expect_success() .commit(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_539.rs b/execution_engine_testing/tests/src/test/regression/ee_539.rs index 1559479a46..f6a0a58424 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_539.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_539.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::{addressable_entity::Weight, runtime_args}; @@ -22,7 +21,7 @@ fn should_run_ee_539_serialize_action_thresholds_regression() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .expect_success() .commit(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_549.rs b/execution_engine_testing/tests/src/test/regression/ee_549.rs index afc56931db..df1743d9da 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_549.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_549.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::RuntimeArgs; @@ -19,7 +18,7 @@ fn should_run_ee_549_set_refund_regression() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request); // Execution should encounter an error because set_refund diff --git a/execution_engine_testing/tests/src/test/regression/ee_550.rs b/execution_engine_testing/tests/src/test/regression/ee_550.rs index 10982ffffc..90e43c3e60 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_550.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_550.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, ARG_AMOUNT, - DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_types::{account::AccountHash, runtime_args}; @@ -42,7 +42,7 @@ fn should_run_ee_550_remove_with_saturated_threshold_regression() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request_1) .expect_success() .commit() @@ -79,7 +79,7 @@ fn should_run_ee_550_update_with_saturated_threshold_regression() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request_1) .expect_success() .commit() diff --git a/execution_engine_testing/tests/src/test/regression/ee_572.rs b/execution_engine_testing/tests/src/test/regression/ee_572.rs index 330fc14a64..8f67611fea 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_572.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_572.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ utils, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, - PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, }; use casper_types::{account::AccountHash, runtime_args, Key, U512}; @@ -48,7 +48,7 @@ fn should_run_ee_572_regression() { // Create Accounts builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request_1) .expect_success() .commit(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_584.rs b/execution_engine_testing/tests/src/test/regression/ee_584.rs index 212e0130f9..d4ce7d911c 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_584.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_584.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::{execution::TransformKind, RuntimeArgs, StoredValue}; @@ -19,7 +18,7 @@ fn should_run_ee_584_no_errored_session_transforms() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request); assert!(builder.is_error()); diff --git a/execution_engine_testing/tests/src/test/regression/ee_599.rs b/execution_engine_testing/tests/src/test/regression/ee_599.rs index 4b0dd4190a..697debfd06 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_599.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_599.rs @@ -2,7 +2,7 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, - PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, }; use casper_types::{account::AccountHash, runtime_args, U512}; @@ -36,7 +36,7 @@ fn setup() -> LmdbWasmTestBuilder { }; let mut ctx = LmdbWasmTestBuilder::default(); - ctx.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + ctx.run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request_1) .expect_success() .commit() diff --git a/execution_engine_testing/tests/src/test/regression/ee_601.rs b/execution_engine_testing/tests/src/test/regression/ee_601.rs index 9a0b7042a9..69ba6aa03e 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_601.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_601.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_types::{ addressable_entity::NamedKeyAddr, execution::TransformKind, runtime_args, CLValue, EntityAddr, @@ -32,7 +32,7 @@ fn should_run_ee_601_pay_session_new_uref_collision() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request); let entity_hash = builder diff --git a/execution_engine_testing/tests/src/test/regression/ee_771.rs b/execution_engine_testing/tests/src/test/regression/ee_771.rs index 9ee1e9850d..38735c0dc3 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_771.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_771.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::RuntimeArgs; @@ -18,7 +17,7 @@ fn should_run_ee_771_regression() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .commit(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_890.rs b/execution_engine_testing/tests/src/test/regression/ee_890.rs index 0d090a499f..48de693dd7 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_890.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_890.rs @@ -2,7 +2,7 @@ use casper_wasm::{self, builder}; use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, ARG_AMOUNT, - DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_types::{addressable_entity::DEFAULT_ENTRY_POINT_NAME, runtime_args, RuntimeArgs}; @@ -52,7 +52,7 @@ fn should_run_ee_890_gracefully_reject_start_node_in_session() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request_1) .commit(); let message = builder.exec_error_message(0).expect("should fail"); @@ -80,7 +80,7 @@ fn should_run_ee_890_gracefully_reject_start_node_in_payment() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request_1) .commit(); let message = builder.exec_error_message(0).expect("should fail"); diff --git a/execution_engine_testing/tests/src/test/regression/ee_966.rs b/execution_engine_testing/tests/src/test/regression/ee_966.rs index 4656ca196b..9f3d48f258 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_966.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_966.rs @@ -5,7 +5,7 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, ARG_AMOUNT, DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, - PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{ engine_state::{Error, ExecuteRequest}, @@ -86,7 +86,7 @@ fn should_run_ee_966_with_zero_min_and_zero_max_memory() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request).commit().expect_success(); } @@ -100,7 +100,7 @@ fn should_run_ee_966_cant_have_too_much_initial_memory() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request).commit(); @@ -121,7 +121,7 @@ fn should_run_ee_966_should_request_exactly_maximum() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request).commit().expect_success(); } @@ -135,7 +135,7 @@ fn should_run_ee_966_should_request_exactly_maximum_as_initial() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request).commit().expect_success(); } @@ -152,7 +152,7 @@ fn should_run_ee_966_cant_have_too_much_max_memory() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request).commit(); @@ -175,7 +175,7 @@ fn should_run_ee_966_cant_have_way_too_much_max_memory() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request).commit(); @@ -196,7 +196,7 @@ fn should_run_ee_966_cant_have_larger_initial_than_max_memory() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request).commit(); @@ -219,7 +219,7 @@ fn should_run_ee_966_regression_fail_when_growing_mem_past_max() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request).commit(); @@ -242,7 +242,7 @@ fn should_run_ee_966_regression_when_growing_mem_after_upgrade() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).commit(); diff --git a/execution_engine_testing/tests/src/test/regression/gh_1470.rs b/execution_engine_testing/tests/src/test/regression/gh_1470.rs index 38b41028ec..018c4a1ac6 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1470.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1470.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_ACCOUNT_PUBLIC_KEY, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_PUBLIC_KEY, LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_execution_engine::{engine_state::Error, execution::ExecError}; use casper_types::{ @@ -33,7 +33,7 @@ const PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::V1_0_0; fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let transfer = ExecuteRequestBuilder::transfer( *DEFAULT_ACCOUNT_ADDR, diff --git a/execution_engine_testing/tests/src/test/regression/gh_1688.rs b/execution_engine_testing/tests/src/test/regression/gh_1688.rs index 8040483950..c64dc69790 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1688.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1688.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::engine_state::ExecuteRequest; use casper_types::{ @@ -17,7 +17,7 @@ const CONTRACT_HASH_KEY: &str = "contract_hash"; fn setup() -> (LmdbWasmTestBuilder, PackageHash, AddressableEntityHash) { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let install_contract_request_1 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, diff --git a/execution_engine_testing/tests/src/test/regression/gh_1902.rs b/execution_engine_testing/tests/src/test/regression/gh_1902.rs index 229289d93a..1456a5c1b5 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1902.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1902.rs @@ -1,8 +1,9 @@ +use num_rational::Ratio; use once_cell::sync::Lazy; use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_ACCOUNT_PUBLIC_KEY, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_PUBLIC_KEY, LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_execution_engine::engine_state::{ engine_config::DEFAULT_MINIMUM_DELEGATION_AMOUNT, ExecuteRequest, @@ -14,7 +15,7 @@ use casper_types::{ auction::{self, DelegationRate}, mint, standard_payment, }, - AddressableEntity, Gas, PublicKey, SecretKey, U512, + AddressableEntity, FeeHandling, Gas, PublicKey, RefundHandling, SecretKey, U512, }; const BOND_AMOUNT: u64 = 42; @@ -29,7 +30,17 @@ static ACCOUNT_1_ADDR: Lazy = Lazy::new(|| AccountHash::from(&*ACCO fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + let chainspec = builder + .chainspec() + .clone() + .with_refund_handling(RefundHandling::Refund { + refund_ratio: Ratio::new(1, 1), + }) + .with_fee_handling(FeeHandling::PayToProposer); + builder.with_chainspec(chainspec); + + let request = LOCAL_GENESIS_REQUEST.clone(); + builder.run_genesis(request); let id: Option = None; let transfer_args_1 = runtime_args! { mint::ARG_TARGET => *ACCOUNT_1_ADDR, @@ -47,21 +58,26 @@ fn exec_and_assert_costs( exec_request: ExecuteRequest, caller: AddressableEntity, expected_tokens_paid: U512, - expected_payment_charge: U512, + _payment_amount: U512, expected_gas_cost: Gas, ) { let balance_before = builder.get_purse_balance(caller.main_purse()); - let proposer_reward_starting_balance = builder.get_proposer_purse_balance(); + let proposer_balance_before = builder.get_proposer_purse_balance(); builder.exec(exec_request).expect_success().commit(); let balance_after = builder.get_purse_balance(caller.main_purse()); - let transaction_fee = builder.get_proposer_purse_balance() - proposer_reward_starting_balance; - assert_eq!(transaction_fee, expected_payment_charge); + let proposer_fee = builder.get_proposer_purse_balance() - proposer_balance_before; - let expected = balance_before - expected_tokens_paid - transaction_fee; + assert_eq!( + proposer_fee, + expected_gas_cost.value(), + "with PayToProposer && 100% refund of unspent, the fee should equal the gas cost" + ); + + let expected = balance_before - expected_tokens_paid - proposer_fee; assert_eq!( balance_after, @@ -89,7 +105,14 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { let bond_amount = U512::from(BOND_AMOUNT); // This amount should be enough to make first time add_bid call. let add_bid_cost = builder.get_auction_costs().add_bid; - let add_bid_payment_amount = U512::from(add_bid_cost); + + let pay_cost = builder + .chainspec() + .system_costs_config + .standard_payment_costs() + .pay; + + let add_bid_payment_amount = U512::from(add_bid_cost + pay_cost) * 2; let add_bid_request = { let sender = *DEFAULT_ACCOUNT_ADDR; diff --git a/execution_engine_testing/tests/src/test/regression/gh_1931.rs b/execution_engine_testing/tests/src/test/regression/gh_1931.rs index f531a18cf4..a58a25614c 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1931.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1931.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::{RuntimeArgs, StoredValue}; @@ -11,9 +10,7 @@ const CONTRACT_PACKAGE_NAMED_KEY: &str = "do_nothing_package_hash"; #[test] fn should_query_contract_package() { let mut builder = LmdbWasmTestBuilder::default(); - builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) - .commit(); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()).commit(); let install_request = ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CONTRACT_NAME, RuntimeArgs::new()) diff --git a/execution_engine_testing/tests/src/test/regression/gh_2280.rs b/execution_engine_testing/tests/src/test/regression/gh_2280.rs index 3b1f69acf1..9644d76cf2 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_2280.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_2280.rs @@ -2,8 +2,8 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, - DEFAULT_ACCOUNT_ADDR, DEFAULT_PROTOCOL_VERSION, MINIMUM_ACCOUNT_CREATION_BALANCE, - PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_ADDR, DEFAULT_PROTOCOL_VERSION, LOCAL_GENESIS_REQUEST, + MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_types::{ account::AccountHash, runtime_args, system::mint, AddressableEntityHash, EraId, Gas, @@ -695,7 +695,7 @@ struct TestContext { fn setup() -> (LmdbWasmTestBuilder, TestContext) { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let session_args = runtime_args! { mint::ARG_AMOUNT => U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE), diff --git a/execution_engine_testing/tests/src/test/regression/gh_3097.rs b/execution_engine_testing/tests/src/test/regression/gh_3097.rs index ba149277fb..553d73e0ef 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_3097.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_3097.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state::Error, execution::ExecError}; use casper_types::{ @@ -34,7 +33,7 @@ fn should_run_regression() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .expect_success() .commit(); diff --git a/execution_engine_testing/tests/src/test/regression/gh_3710.rs b/execution_engine_testing/tests/src/test/regression/gh_3710.rs index b3f9b073dc..5ceced9732 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_3710.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_3710.rs @@ -2,7 +2,7 @@ use std::{collections::BTreeSet, convert::TryInto, iter::FromIterator}; use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, StepRequestBuilder, WasmTestBuilder, - DEFAULT_ACCOUNT_PUBLIC_KEY, DEFAULT_PROPOSER_PUBLIC_KEY, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_PUBLIC_KEY, DEFAULT_PROPOSER_PUBLIC_KEY, LOCAL_GENESIS_REQUEST, }; use casper_storage::{ data_access_layer::{PruneRequest, PruneResult}, @@ -189,7 +189,7 @@ fn distribute_rewards( #[test] fn gh_3710_should_produce_era_summary_in_a_step() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); add_validator_and_wait_for_rotation(&mut builder, &DEFAULT_ACCOUNT_PUBLIC_KEY); distribute_rewards(&mut builder, 1, &DEFAULT_ACCOUNT_PUBLIC_KEY, 0.into()); @@ -233,7 +233,7 @@ mod fixture { use casper_engine_test_support::{ ExecuteRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, - PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, }; use casper_types::{ runtime_args, @@ -255,7 +255,7 @@ mod fixture { return; } - let genesis_request = PRODUCTION_RUN_GENESIS_REQUEST.clone(); + let genesis_request = LOCAL_GENESIS_REQUEST.clone(); lmdb_fixture::generate_fixture(CALL_STACK_FIXTURE, genesis_request, |builder| { let execute_request = ExecuteRequestBuilder::standard( @@ -281,7 +281,7 @@ mod fixture { return; } - let genesis_request = PRODUCTION_RUN_GENESIS_REQUEST.clone(); + let genesis_request = LOCAL_GENESIS_REQUEST.clone(); lmdb_fixture::generate_fixture(GROUPS_FIXTURE, genesis_request, |builder| { let execute_request = ExecuteRequestBuilder::standard( @@ -304,7 +304,7 @@ mod fixture { return; } // To generate this fixture again you have to re-run this code release-1.4.13. - let genesis_request = PRODUCTION_RUN_GENESIS_REQUEST.clone(); + let genesis_request = LOCAL_GENESIS_REQUEST.clone(); lmdb_fixture::generate_fixture(GH_3710_FIXTURE, genesis_request, |builder| { super::add_validator_and_wait_for_rotation(builder, &DEFAULT_ACCOUNT_PUBLIC_KEY); diff --git a/execution_engine_testing/tests/src/test/regression/gov_42.rs b/execution_engine_testing/tests/src/test/regression/gov_42.rs index 17690c7344..dab13f4e50 100644 --- a/execution_engine_testing/tests/src/test/regression/gov_42.rs +++ b/execution_engine_testing/tests/src/test/regression/gov_42.rs @@ -15,7 +15,7 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::engine_state::MAX_PAYMENT; use casper_types::{runtime_args, Gas, RuntimeArgs}; @@ -76,7 +76,7 @@ fn run_test_case(input_wasm_bytes: &[u8], expected_error: &str, execution_phase: let do_minimum_request = do_minimum_request_builder.build(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) diff --git a/execution_engine_testing/tests/src/test/regression/gov_427.rs b/execution_engine_testing/tests/src/test/regression/gov_427.rs index 9534a91e0b..ac33239243 100644 --- a/execution_engine_testing/tests/src/test/regression/gov_427.rs +++ b/execution_engine_testing/tests/src/test/regression/gov_427.rs @@ -2,7 +2,7 @@ use std::convert::TryInto; use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_WASM_CONFIG, - PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state::Error, execution::ExecError}; use casper_types::{addressable_entity::DEFAULT_ENTRY_POINT_NAME, RuntimeArgs}; @@ -80,7 +80,7 @@ fn too_many_locals_should_exceed_stack_height() { ); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let success_request = ExecuteRequestBuilder::module_bytes( *DEFAULT_ACCOUNT_ADDR, diff --git a/execution_engine_testing/tests/src/test/regression/gov_74.rs b/execution_engine_testing/tests/src/test/regression/gov_74.rs index 0336697292..f009a629c9 100644 --- a/execution_engine_testing/tests/src/test/regression/gov_74.rs +++ b/execution_engine_testing/tests/src/test/regression/gov_74.rs @@ -2,7 +2,7 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PROTOCOL_VERSION, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PROTOCOL_VERSION, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{ engine_state::Error, @@ -29,7 +29,7 @@ static NEW_PROTOCOL_VERSION: Lazy = Lazy::new(|| { fn initialize_builder() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder } diff --git a/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs b/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs index 16d468855e..b23c4a85b6 100644 --- a/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs +++ b/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs @@ -2,7 +2,7 @@ use std::convert::TryInto; use casper_engine_test_support::{ utils, DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_execution_engine::{ engine_state::{self, ExecuteRequest}, @@ -133,7 +133,7 @@ fn host_function_metrics_has_acceptable_gas_cost() { fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(create_account_exec_request(ACCOUNT0_ADDR)) .expect_success() .commit() diff --git a/execution_engine_testing/tests/src/test/regression/regression_20210707.rs b/execution_engine_testing/tests/src/test/regression/regression_20210707.rs index 62f1b0585b..901526e7c4 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20210707.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20210707.rs @@ -1,7 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, EntityWithNamedKeys, ExecuteRequestBuilder, LmdbWasmTestBuilder, - DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, - PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_execution_engine::{ engine_state::{Error as CoreError, ExecuteRequest}, @@ -92,7 +91,7 @@ fn assert_forged_uref_error(error: CoreError, forged_uref: URef) { fn should_transfer_funds_from_contract_to_new_account() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let store_request = setup_regression_contract(); @@ -132,7 +131,7 @@ fn should_transfer_funds_from_contract_to_new_account() { fn should_transfer_funds_from_contract_to_existing_account() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let store_request = setup_regression_contract(); @@ -177,7 +176,7 @@ fn should_transfer_funds_from_contract_to_existing_account() { fn should_not_transfer_funds_from_forged_purse_to_account_native_transfer() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let store_request = setup_regression_contract(); @@ -222,7 +221,7 @@ fn should_not_transfer_funds_from_forged_purse_to_account_native_transfer() { fn should_not_transfer_funds_from_forged_purse_to_owned_purse() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let store_request = setup_regression_contract(); @@ -276,7 +275,7 @@ fn should_not_transfer_funds_from_forged_purse_to_owned_purse() { fn should_not_transfer_funds_into_bob_purse() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let store_request = setup_regression_contract(); @@ -321,7 +320,7 @@ fn should_not_transfer_funds_into_bob_purse() { fn should_not_transfer_from_hardcoded_purse() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let store_request = setup_regression_contract(); @@ -362,7 +361,7 @@ fn should_not_transfer_from_hardcoded_purse() { fn should_not_refund_to_bob_and_charge_alice() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let store_request = setup_regression_contract(); @@ -420,7 +419,7 @@ fn should_not_refund_to_bob_and_charge_alice() { fn should_not_charge_alice_for_execution() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let store_request = setup_regression_contract(); @@ -478,7 +477,7 @@ fn should_not_charge_alice_for_execution() { fn should_not_charge_for_execution_from_hardcoded_purse() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let store_request = setup_regression_contract(); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20210831.rs b/execution_engine_testing/tests/src/test/regression/regression_20210831.rs index 12b9d9d132..16c153c082 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20210831.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20210831.rs @@ -2,7 +2,7 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, - MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_execution_engine::{ engine_state::{engine_config::DEFAULT_MINIMUM_DELEGATION_AMOUNT, Error as CoreError}, @@ -47,7 +47,7 @@ static DELEGATE_AMOUNT: Lazy = Lazy::new(|| U512::from(500_000)); fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let id: Option = None; @@ -75,7 +75,7 @@ fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let id: Option = None; diff --git a/execution_engine_testing/tests/src/test/regression/regression_20210924.rs b/execution_engine_testing/tests/src/test/regression/regression_20210924.rs index 8e90e4d358..fe24025e12 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20210924.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20210924.rs @@ -2,7 +2,7 @@ use num_traits::Zero; use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::engine_state::{Error as CoreError, MAX_PAYMENT}; use casper_types::{runtime_args, Gas, RuntimeArgs, DEFAULT_NOP_COST, U512}; @@ -37,7 +37,7 @@ fn should_charge_minimum_for_do_nothing_session() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -95,7 +95,7 @@ fn should_execute_do_minimum_session() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -152,7 +152,7 @@ fn should_charge_minimum_for_do_nothing_payment() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) diff --git a/execution_engine_testing/tests/src/test/regression/regression_20211110.rs b/execution_engine_testing/tests/src/test/regression/regression_20211110.rs index dcf7721c5c..5e84be70db 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20211110.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20211110.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state::Error as CoreError, execution::ExecError}; use casper_types::{ @@ -25,7 +25,7 @@ fn regression_20211110() { let mut funds: u64 = STARTING_BALANCE; let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let transfer_request = ExecuteRequestBuilder::transfer( *DEFAULT_ACCOUNT_ADDR, diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220119.rs b/execution_engine_testing/tests/src/test/regression/regression_20220119.rs index 2fe3ba41eb..ee48e68bb1 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220119.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220119.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::RuntimeArgs; @@ -10,7 +9,7 @@ const REGRESSION_20220119_CONTRACT: &str = "regression_20220119.wasm"; #[test] fn should_create_purse() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220204.rs b/execution_engine_testing/tests/src/test/regression/regression_20220204.rs index aac76090b1..02cb831d74 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220204.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220204.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state, execution::ExecError}; use casper_types::{runtime_args, AccessRights, RuntimeArgs}; @@ -247,7 +246,7 @@ fn regression_20220204_as_contract_by_hash_attenuated() { fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let install_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, REGRESSION_20220204_CONTRACT, diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220207.rs b/execution_engine_testing/tests/src/test/regression/regression_20220207.rs index 0a943ce6c9..7a1c49ac02 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220207.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220207.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state::Error, execution::ExecError}; use casper_types::{account::AccountHash, runtime_args, system::mint, ApiError, U512}; @@ -17,7 +16,7 @@ const UNAPPROVED_SPENDING_AMOUNT_ERR: Error = Error::Exec(ExecError::Revert(ApiE #[test] fn should_not_transfer_above_approved_limit() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let args = runtime_args! { mint::ARG_AMOUNT => U512::from(1000u64), // What we approved. @@ -38,7 +37,7 @@ fn should_not_transfer_above_approved_limit() { #[test] fn should_transfer_within_approved_limit() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let args = runtime_args! { mint::ARG_AMOUNT => U512::from(1000u64), @@ -57,7 +56,7 @@ fn should_transfer_within_approved_limit() { #[test] fn should_fail_without_amount_arg() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let args = runtime_args! { // If `amount` arg is absent, host assumes that limit is 0. diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220208.rs b/execution_engine_testing/tests/src/test/regression/regression_20220208.rs index f64ab14d10..f919ed508a 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220208.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220208.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state::Error, execution::ExecError}; use casper_types::{account::AccountHash, runtime_args, system::mint, ApiError, U512}; @@ -18,7 +17,7 @@ const UNAPPROVED_SPENDING_AMOUNT_ERR: Error = Error::Exec(ExecError::Revert(ApiE #[test] fn should_transfer_within_approved_limit_multiple_transfers() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let part_1 = U512::from(100u64); let part_2 = U512::from(100u64); @@ -42,7 +41,7 @@ fn should_transfer_within_approved_limit_multiple_transfers() { #[test] fn should_not_transfer_above_approved_limit_multiple_transfers() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let part_1 = U512::from(100u64); let part_2 = U512::from(100u64); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220211.rs b/execution_engine_testing/tests/src/test/regression/regression_20220211.rs index 755fec5bdd..7611764a08 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220211.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220211.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state, execution::ExecError}; use casper_types::{runtime_args, AccessRights, RuntimeArgs, URef}; @@ -33,7 +32,7 @@ fn regression_20220211_ret_as_session() { fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let install_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, REGRESSION_20220211_CONTRACT, diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220217.rs b/execution_engine_testing/tests/src/test/regression/regression_20220217.rs index a089f248dd..ee720e71f6 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220217.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220217.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, + MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_execution_engine::{engine_state, execution::ExecError}; use casper_types::{account::AccountHash, runtime_args, system::mint, AccessRights, URef, U512}; @@ -256,7 +256,7 @@ fn regression_20220217_should_not_transfer_funds_on_unrelated_purses() { fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let fund_account_1_request = ExecuteRequestBuilder::transfer( *DEFAULT_ACCOUNT_ADDR, @@ -399,7 +399,7 @@ fn mint_by_hash_transfer_should_fail_because_lack_of_target_uref_access() { // TODO create two named purses and verify we can pass source and target known non-main purses let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220221.rs b/execution_engine_testing/tests/src/test/regression/regression_20220221.rs index 0faeac8a00..5736890178 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220221.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220221.rs @@ -3,8 +3,8 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, StepRequestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_AUCTION_DELAY, DEFAULT_GENESIS_TIMESTAMP_MILLIS, - DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, DEFAULT_PROTOCOL_VERSION, MINIMUM_ACCOUNT_CREATION_BALANCE, - PRODUCTION_RUN_GENESIS_REQUEST, TIMESTAMP_MILLIS_INCREMENT, + DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, DEFAULT_PROTOCOL_VERSION, LOCAL_GENESIS_REQUEST, + MINIMUM_ACCOUNT_CREATION_BALANCE, TIMESTAMP_MILLIS_INCREMENT, }; use casper_execution_engine::engine_state::DEFAULT_MAX_RUNTIME_CALL_STACK_HEIGHT; use casper_types::{ @@ -61,7 +61,7 @@ fn regression_20220221_should_distribute_to_many_validators() { .build(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let mut upgrade_request = UpgradeRequestBuilder::default() .with_new_validator_slots(DEFAULT_MAX_RUNTIME_CALL_STACK_HEIGHT + 1) diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220222.rs b/execution_engine_testing/tests/src/test/regression/regression_20220222.rs index 9a43b33a29..83480c2911 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220222.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220222.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, + MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_execution_engine::{engine_state, execution::ExecError}; use casper_types::{account::AccountHash, runtime_args, U512}; @@ -11,7 +11,7 @@ const ALICE_ADDR: AccountHash = AccountHash::new([42; 32]); #[test] fn regression_20220222_escalate() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let transfer_request = ExecuteRequestBuilder::transfer( *DEFAULT_ACCOUNT_ADDR, diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220223.rs b/execution_engine_testing/tests/src/test/regression/regression_20220223.rs index 526d217977..9f443ad844 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220223.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220223.rs @@ -3,7 +3,7 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, - MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_execution_engine::{ engine_state, engine_state::engine_config::DEFAULT_MINIMUM_DELEGATION_AMOUNT, @@ -278,7 +278,7 @@ fn should_fail_to_mint_transfer_over_the_limit() { fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let validator_1_fund_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, CONTRACT_TRANSFER_TO_ACCOUNT, diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220224.rs b/execution_engine_testing/tests/src/test/regression/regression_20220224.rs index 599df72360..adad9b450a 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220224.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220224.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state, execution::ExecError}; use casper_types::{runtime_args, system::mint, ApiError, RuntimeArgs}; @@ -12,7 +12,7 @@ const CONTRACT_REVERT: &str = "revert.wasm"; #[test] fn should_not_transfer_above_approved_limit_in_payment_code() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = { let account_hash = *DEFAULT_ACCOUNT_ADDR; diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220727.rs b/execution_engine_testing/tests/src/test/regression/regression_20220727.rs index 211a82c260..283cb6e9c0 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220727.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220727.rs @@ -6,8 +6,7 @@ use casper_wasm::{ }; use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{ engine_state, @@ -56,7 +55,7 @@ fn make_oom_payload(initial: u32, maximum: Option) -> Vec { #[test] fn should_not_oom() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let initial_size_exceeded = vec![OOM_INIT, FAILURE_ONE_ABOVE_LIMIT]; @@ -115,7 +114,7 @@ fn should_not_oom() { #[test] fn should_pass_table_validation() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let passing_test_cases = vec![ALLOWED_NO_MAX, ALLOWED_LIMITS]; @@ -189,7 +188,7 @@ fn test_element_section( // ) let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let mut wat = String::new(); @@ -246,7 +245,7 @@ fn test_element_section( #[test] fn should_not_allow_more_than_one_table() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // wabt::wat2wasm doesn't allow multiple tables so we'll go with a builder @@ -379,7 +378,7 @@ fn should_allow_large_br_table() { .expect("should create module bytes"); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = ExecuteRequestBuilder::module_bytes( *DEFAULT_ACCOUNT_ADDR, @@ -398,7 +397,7 @@ fn should_not_allow_large_br_table() { make_arbitrary_br_table(FAILING_BR_TABLE_SIZE).expect("should create module bytes"); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = ExecuteRequestBuilder::module_bytes( *DEFAULT_ACCOUNT_ADDR, @@ -468,7 +467,7 @@ fn should_allow_multiple_globals() { make_arbitrary_global(DEFAULT_MAX_GLOBALS as usize).expect("should make arbitrary global"); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = ExecuteRequestBuilder::module_bytes( *DEFAULT_ACCOUNT_ADDR, @@ -487,7 +486,7 @@ fn should_not_allow_too_many_globals() { make_arbitrary_global(FAILING_GLOBALS_SIZE).expect("should make arbitrary global"); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = ExecuteRequestBuilder::module_bytes( *DEFAULT_ACCOUNT_ADDR, @@ -519,7 +518,7 @@ fn should_verify_max_param_count() { .expect("should create wasm bytes"); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = ExecuteRequestBuilder::module_bytes( *DEFAULT_ACCOUNT_ADDR, @@ -534,7 +533,7 @@ fn should_verify_max_param_count() { wasm_utils::make_n_arg_call_bytes(100, "i32").expect("should create wasm bytes"); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = ExecuteRequestBuilder::module_bytes( *DEFAULT_ACCOUNT_ADDR, @@ -553,7 +552,7 @@ fn should_not_allow_too_many_params() { .expect("should create wasm bytes"); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = ExecuteRequestBuilder::module_bytes( *DEFAULT_ACCOUNT_ADDR, @@ -589,7 +588,7 @@ fn should_not_allow_to_import_gas_function() { .unwrap(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = ExecuteRequestBuilder::module_bytes( *DEFAULT_ACCOUNT_ADDR, @@ -724,7 +723,7 @@ fn should_not_set_non_existing_global_above_declared_range() { fn test_non_existing_global(module_wat: &str, index: u32) { let module_bytes = wat::parse_str(module_wat).unwrap(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = ExecuteRequestBuilder::module_bytes( *DEFAULT_ACCOUNT_ADDR, module_bytes, diff --git a/execution_engine_testing/tests/src/test/regression/slow_input.rs b/execution_engine_testing/tests/src/test/regression/slow_input.rs index 15fdbff754..e8ef51f76b 100644 --- a/execution_engine_testing/tests/src/test/regression/slow_input.rs +++ b/execution_engine_testing/tests/src/test/regression/slow_input.rs @@ -1,8 +1,7 @@ use std::mem; use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state::Error, execution::ExecError}; use casper_types::{ @@ -65,7 +64,7 @@ const SLOW_INPUT: &str = r#"(module fn should_measure_slow_input() { let module_bytes = wat::parse_str(SLOW_INPUT).unwrap(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = ExecuteRequestBuilder::module_bytes( *DEFAULT_ACCOUNT_ADDR, module_bytes, @@ -83,7 +82,7 @@ fn should_measure_slow_input_with_infinite_br_loop() { let module_bytes = make_cpu_burner_br(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = ExecuteRequestBuilder::module_bytes( *DEFAULT_ACCOUNT_ADDR, module_bytes, @@ -100,7 +99,7 @@ fn should_measure_slow_input_with_infinite_br_loop() { fn should_measure_br_if_cpu_burner_with_br_if_iterations() { let module_bytes = cpu_burner_br_if(u32::MAX as i64); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = ExecuteRequestBuilder::module_bytes( *DEFAULT_ACCOUNT_ADDR, module_bytes, @@ -118,7 +117,7 @@ fn should_measure_br_table_cpu_burner_with_br_table_iterations() { let module_bytes = cpu_burner_br_table(u32::MAX as i64); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = ExecuteRequestBuilder::module_bytes( *DEFAULT_ACCOUNT_ADDR, module_bytes, @@ -134,7 +133,7 @@ fn should_measure_br_table_cpu_burner_with_br_table_iterations() { #[test] fn should_charge_extra_per_amount_of_br_table_elements() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); const FIXED_BLOCK_AMOUNT: usize = 256; const N_ELEMENTS: u32 = 5; diff --git a/execution_engine_testing/tests/src/test/regression/transforms_must_be_ordered.rs b/execution_engine_testing/tests/src/test/regression/transforms_must_be_ordered.rs index 67249a0716..9c9d85df59 100644 --- a/execution_engine_testing/tests/src/test/regression/transforms_must_be_ordered.rs +++ b/execution_engine_testing/tests/src/test/regression/transforms_must_be_ordered.rs @@ -5,7 +5,7 @@ use rand::{rngs::StdRng, Rng, SeedableRng}; use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, }; use casper_types::{ execution::TransformKind, runtime_args, system::standard_payment, AddressableEntityHash, Key, @@ -21,7 +21,7 @@ fn contract_transforms_should_be_ordered_in_the_effects() { const N_OPS: usize = 1000; let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let mut rng = StdRng::seed_from_u64(0); diff --git a/execution_engine_testing/tests/src/test/stack_overflow.rs b/execution_engine_testing/tests/src/test/stack_overflow.rs index e395f5868d..c54979ca19 100644 --- a/execution_engine_testing/tests/src/test/stack_overflow.rs +++ b/execution_engine_testing/tests/src/test/stack_overflow.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state::Error, execution::ExecError}; use casper_types::RuntimeArgs; @@ -26,7 +25,7 @@ fn runtime_stack_overflow_should_cause_unreachable_error() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder .exec(do_stack_overflow_request) .expect_failure() diff --git a/execution_engine_testing/tests/src/test/storage_costs.rs b/execution_engine_testing/tests/src/test/storage_costs.rs index ebf694aa77..60c434cd38 100644 --- a/execution_engine_testing/tests/src/test/storage_costs.rs +++ b/execution_engine_testing/tests/src/test/storage_costs.rs @@ -6,7 +6,7 @@ use once_cell::sync::Lazy; use casper_engine_test_support::DEFAULT_ACCOUNT_PUBLIC_KEY; use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PROTOCOL_VERSION, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PROTOCOL_VERSION, LOCAL_GENESIS_REQUEST, }; #[cfg(not(feature = "use-as-wasm"))] use casper_types::DEFAULT_ADD_BID_COST; @@ -115,7 +115,7 @@ fn initialize_isolated_storage_costs() -> LmdbWasmTestBuilder { // // Isolate storage costs without host function costs, and without opcode costs // - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let mut upgrade_request = UpgradeRequestBuilder::new() .with_current_protocol_version(*DEFAULT_PROTOCOL_VERSION) @@ -356,7 +356,7 @@ fn should_measure_unisolated_gas_cost_for_storage_usage_write() { let cost_per_byte = U512::from(StorageCosts::default().gas_per_byte()); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let install_exec_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -580,7 +580,7 @@ fn should_measure_unisolated_gas_cost_for_storage_usage_add() { let cost_per_byte = U512::from(StorageCosts::default().gas_per_byte()); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let install_exec_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs b/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs index 1db54e6afe..e7c3b4736e 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs @@ -10,8 +10,8 @@ use casper_engine_test_support::{ DEFAULT_ACCOUNTS, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_CHAINSPEC_REGISTRY, DEFAULT_EXEC_CONFIG, DEFAULT_GENESIS_CONFIG_HASH, DEFAULT_GENESIS_TIMESTAMP_MILLIS, DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, DEFAULT_PROTOCOL_VERSION, - DEFAULT_UNBONDING_DELAY, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, - SYSTEM_ADDR, TIMESTAMP_MILLIS_INCREMENT, + DEFAULT_UNBONDING_DELAY, LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, SYSTEM_ADDR, + TIMESTAMP_MILLIS_INCREMENT, }; use casper_execution_engine::{ engine_state::{self, engine_config::DEFAULT_MINIMUM_DELEGATION_AMOUNT, Error}, @@ -1274,7 +1274,7 @@ fn undelegated_funds_should_be_released() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); for request in post_genesis_requests { builder.exec(request).commit().expect_success(); @@ -1400,7 +1400,7 @@ fn fully_undelegated_funds_should_be_released() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); for request in post_genesis_requests { builder.exec(request).commit().expect_success(); @@ -1561,7 +1561,7 @@ fn should_undelegate_delegators_when_validator_unbonds() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); for request in post_genesis_requests { builder.exec(request).commit().expect_success(); @@ -1793,7 +1793,7 @@ fn should_undelegate_delegators_when_validator_fully_unbonds() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); for request in post_genesis_requests { builder.exec(request).commit().expect_success(); @@ -2966,7 +2966,7 @@ fn should_reset_delegators_stake_after_slashing() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); for request in post_genesis_requests { builder.exec(request).expect_success().commit(); @@ -3248,7 +3248,7 @@ fn should_delegate_and_redelegate() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); for request in post_genesis_requests { builder.exec(request).commit().expect_success(); @@ -3436,7 +3436,7 @@ fn should_handle_redelegation_to_inactive_validator() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); for request in post_genesis_requests { builder.exec(request).commit().expect_success(); @@ -3522,7 +3522,7 @@ fn should_handle_redelegation_to_inactive_validator() { fn should_enforce_minimum_delegation_amount() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let transfer_to_validator_1 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -3603,7 +3603,7 @@ fn should_enforce_minimum_delegation_amount() { fn should_allow_delegations_with_minimal_floor_amount() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let transfer_to_validator_1 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -3716,7 +3716,7 @@ fn should_enforce_max_delegators_per_validator_cap() { let data_dir = TempDir::new().expect("should create temp dir"); let mut builder = LmdbWasmTestBuilder::new_with_config(data_dir.path(), chainspec); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let transfer_to_validator_1 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -4002,7 +4002,7 @@ fn should_transfer_to_main_purse_in_case_of_redelegation_past_max_delegation_cap let data_dir = TempDir::new().expect("should create temp dir"); let mut builder = LmdbWasmTestBuilder::new_with_config(data_dir.path(), chainspec); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); for request in post_genesis_requests { builder.exec(request).expect_success().commit(); @@ -4151,7 +4151,7 @@ fn should_delegate_and_redelegate_with_eviction_regression_test() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); for request in post_genesis_requests { builder.exec(request).commit().expect_success(); @@ -4197,7 +4197,7 @@ fn should_increase_existing_delegation_when_limit_exceeded() { let data_dir = TempDir::new().expect("should create temp dir"); let mut builder = LmdbWasmTestBuilder::new_with_config(data_dir.path(), chainspec); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let transfer_to_validator_1 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs b/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs index ed2a0ee4f8..5dddddac78 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs @@ -8,9 +8,10 @@ use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, StepRequestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_GENESIS_TIMESTAMP_MILLIS, DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, DEFAULT_MINIMUM_DELEGATION_AMOUNT, DEFAULT_PROTOCOL_VERSION, DEFAULT_ROUND_SEIGNIORAGE_RATE, - MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_ROUND_SEIGNIORAGE_RATE, - PRODUCTION_RUN_GENESIS_REQUEST, SYSTEM_ADDR, TIMESTAMP_MILLIS_INCREMENT, + LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_ROUND_SEIGNIORAGE_RATE, + SYSTEM_ADDR, TIMESTAMP_MILLIS_INCREMENT, }; +use casper_storage::data_access_layer::AuctionMethod; use casper_types::{ self, account::AccountHash, @@ -21,7 +22,7 @@ use casper_types::{ ARG_DELEGATOR, ARG_PUBLIC_KEY, ARG_REWARDS_MAP, ARG_VALIDATOR, DELEGATION_RATE_DENOMINATOR, METHOD_DISTRIBUTE, SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY, }, - EntityAddr, EraId, Key, ProtocolVersion, PublicKey, SecretKey, U512, + EntityAddr, EraId, Key, ProtocolVersion, PublicKey, SecretKey, Timestamp, U512, }; const ARG_ENTRY_POINT: &str = "entry_point"; @@ -251,11 +252,12 @@ fn should_distribute_delegation_rate_zero() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); + let protocol_version = *DEFAULT_PROTOCOL_VERSION; // initial token supply - let initial_supply = builder.total_supply(None); - let total_payout = builder.base_round_reward(None); + let initial_supply = builder.total_supply(None, protocol_version); + let total_payout = builder.base_round_reward(None, protocol_version); let expected_total_reward = *GENESIS_ROUND_SEIGNIORAGE_RATE * initial_supply; let expected_total_reward_integer = expected_total_reward.to_integer(); assert_eq!(total_payout, expected_total_reward_integer); @@ -516,13 +518,18 @@ fn should_withdraw_bids_after_distribute() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); + + let protocol_version = *DEFAULT_PROTOCOL_VERSION; + let total_payout = builder.base_round_reward(None, protocol_version); // initial token supply - let initial_supply = builder.total_supply(None); - let total_payout = builder.base_round_reward(None); - let expected_total_reward = *GENESIS_ROUND_SEIGNIORAGE_RATE * initial_supply; + let initial_supply = builder.total_supply(None, protocol_version); + let rate = builder.round_seigniorage_rate(None, protocol_version); + + let expected_total_reward = rate * initial_supply; let expected_total_reward_integer = expected_total_reward.to_integer(); + assert_eq!(total_payout, expected_total_reward_integer); for request in post_genesis_requests { @@ -532,7 +539,7 @@ fn should_withdraw_bids_after_distribute() { for _ in 0..=builder.get_auction_delay() { let step_request = StepRequestBuilder::new() .with_parent_state_hash(builder.get_post_state_hash()) - .with_protocol_version(ProtocolVersion::V1_0_0) + .with_protocol_version(protocol_version) .with_next_era_id(builder.get_era().successor()) .with_run_auction(true) .build(); @@ -640,6 +647,7 @@ fn should_withdraw_bids_after_distribute() { "delegator 1 should have a stake" ); let undelegate_amount = U512::from(DELEGATOR_1_STAKE) + delegator_1_actual_payout; + undelegate( &mut builder, *DELEGATOR_1_ADDR, @@ -725,11 +733,10 @@ fn should_withdraw_bids_after_distribute() { #[ignore] #[test] fn should_distribute_rewards_after_restaking_delegated_funds() { - const VALIDATOR_1_STAKE: u64 = 1_000_000_000_000; - const DELEGATOR_1_STAKE: u64 = 1_000_000_000_000; - const DELEGATOR_2_STAKE: u64 = 1_000_000_000_000; + const VALIDATOR_1_STAKE: u64 = 7_000_000_000_000_000; + const DELEGATOR_1_STAKE: u64 = 5_000_000_000_000_000; + const DELEGATOR_2_STAKE: u64 = 5_000_000_000_000_000; const TOTAL_DELEGATOR_STAKE: u64 = DELEGATOR_1_STAKE + DELEGATOR_2_STAKE; - const TOTAL_STAKE: u64 = TOTAL_DELEGATOR_STAKE + VALIDATOR_1_STAKE; const VALIDATOR_1_DELEGATION_RATE: DelegationRate = 0; @@ -818,322 +825,231 @@ fn should_distribute_rewards_after_restaking_delegated_funds() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); + let protocol_version = *DEFAULT_PROTOCOL_VERSION; // initial token supply - let initial_supply = builder.total_supply(None); - let total_payout = builder.base_round_reward(None); - let expected_total_reward_1 = *GENESIS_ROUND_SEIGNIORAGE_RATE * initial_supply; - let expected_total_reward_1_integer = expected_total_reward_1.to_integer(); - assert_eq!(total_payout, expected_total_reward_1_integer); + let initial_supply = builder.total_supply(None, protocol_version); + let initial_rate = builder.round_seigniorage_rate(None, protocol_version); + let initial_round_reward = builder.base_round_reward(None, protocol_version); + + let initial_expected_reward_rate = initial_rate * initial_supply; + assert_eq!( + initial_round_reward, + initial_expected_reward_rate.to_integer() + ); for request in post_genesis_requests { builder.exec(request).commit().expect_success(); } - for _ in 0..=builder.get_auction_delay() { - let step_request = StepRequestBuilder::new() - .with_parent_state_hash(builder.get_post_state_hash()) - .with_protocol_version(ProtocolVersion::V1_0_0) - .with_next_era_id(builder.get_era().successor()) - .with_run_auction(true) - .build(); + // we need to crank forward because our validator is not a genesis validator + builder.advance_eras_by_default_auction_delay(); - assert!( - builder.step(step_request).is_success(), - "must execute step successfully" + let mut era = builder.get_era(); + let mut round_reward = initial_round_reward; + let mut total_supply = initial_supply; + let mut expected_reward_rate = initial_expected_reward_rate; + let mut validator_stake = U512::from(VALIDATOR_1_STAKE); + let mut delegator_1_stake = U512::from(DELEGATOR_1_STAKE); + let mut delegator_2_stake = U512::from(DELEGATOR_2_STAKE); + let mut total_delegator_stake = U512::from(TOTAL_DELEGATOR_STAKE); + let mut total_stake = U512::from(VALIDATOR_1_STAKE + TOTAL_DELEGATOR_STAKE); + for idx in 0..10 { + let rewards = { + let mut rewards = BTreeMap::new(); + rewards.insert(VALIDATOR_1.clone(), round_reward); + rewards + }; + + let result = builder.distribute(None, protocol_version, rewards, Timestamp::now().millis()); + assert!(result.is_success(), "failed to distribute {:?}", result); + builder.advance_era(); + let current_era = builder.get_era(); + assert_eq!( + era.successor(), + current_era, + "unexpected era {:?}", + current_era ); - } + era = current_era; - let mut rewards = BTreeMap::new(); - rewards.insert(VALIDATOR_1.clone(), total_payout); + let updated_round_reward = builder.base_round_reward(None, protocol_version); + round_reward = updated_round_reward; - let distribute_request = ExecuteRequestBuilder::contract_call_by_hash( - *SYSTEM_ADDR, - builder.get_auction_contract_hash(), - METHOD_DISTRIBUTE, - runtime_args! { - ARG_ENTRY_POINT => METHOD_DISTRIBUTE, - ARG_REWARDS_MAP => rewards - }, - ) - .build(); - - builder.exec(distribute_request).commit().expect_success(); - - let validator_1_staked_amount_1 = get_validator_bid(&mut builder, VALIDATOR_1.clone()) - .expect("should have validator bid") - .staked_amount(); - let delegator_1_staked_amount_1 = - get_delegator_staked_amount(&mut builder, VALIDATOR_1.clone(), DELEGATOR_1.clone()); - let delegator_2_staked_amount_1 = - get_delegator_staked_amount(&mut builder, VALIDATOR_1.clone(), DELEGATOR_2.clone()); - - let delegators_share = { - let commission_rate = Ratio::new( - U512::from(VALIDATOR_1_DELEGATION_RATE), - U512::from(DELEGATION_RATE_DENOMINATOR), + let updated_validator_stake = get_validator_bid(&mut builder, VALIDATOR_1.clone()) + .expect("should have validator bid") + .staked_amount(); + assert!( + updated_validator_stake > validator_stake, + "validator stake should go up" ); - let reward_multiplier = - Ratio::new(U512::from(TOTAL_DELEGATOR_STAKE), U512::from(TOTAL_STAKE)); - let delegator_reward = expected_total_reward_1 - .checked_mul(&reward_multiplier) - .expect("should get delegator reward ratio"); - let commission = delegator_reward - .checked_mul(&commission_rate) - .expect("must get delegator reward"); - delegator_reward.checked_sub(&commission).unwrap() - }; - - let delegator_1_expected_payout_1 = { - let reward_multiplier = Ratio::new( - U512::from(DELEGATOR_1_STAKE), - U512::from(TOTAL_DELEGATOR_STAKE), + let updated_delegator_1_stake = + get_delegator_staked_amount(&mut builder, VALIDATOR_1.clone(), DELEGATOR_1.clone()); + assert!( + updated_delegator_1_stake > delegator_1_stake, + "delegator 1 stake should go up" ); - delegators_share - .checked_mul(&reward_multiplier) - .map(|ratio| ratio.to_integer()) - .expect("must get delegator 1 reward") - }; - - let delegator_2_expected_payout_1 = { - let reward_multiplier = Ratio::new( - U512::from(DELEGATOR_2_STAKE), - U512::from(TOTAL_DELEGATOR_STAKE), + let updated_delegator_2_stake = + get_delegator_staked_amount(&mut builder, VALIDATOR_1.clone(), DELEGATOR_2.clone()); + assert!( + updated_delegator_2_stake > delegator_2_stake, + "delegator 2 stake should go up was: {:?} is: {:?}", + delegator_2_stake, + updated_delegator_2_stake, ); - delegators_share - .checked_mul(&reward_multiplier) - .map(|ratio| ratio.to_integer()) - .expect("must get delegator 2 reward") - }; - - let validator_1_actual_payout_1 = { - let validator_stake_before = U512::from(VALIDATOR_1_STAKE); - let validator_stake_after = validator_1_staked_amount_1; - - validator_stake_after - validator_stake_before - }; - - let validator_1_expected_payout_1 = { - let total_delegator_payout = delegator_1_expected_payout_1 + delegator_2_expected_payout_1; - let validator_share = expected_total_reward_1 - Ratio::from(total_delegator_payout); - validator_share.to_integer() - }; - assert_eq!(validator_1_actual_payout_1, validator_1_expected_payout_1); - - let delegator_1_actual_payout_1 = { - let delegator_stake_before = U512::from(DELEGATOR_1_STAKE); - let delegator_stake_after = delegator_1_staked_amount_1; - - delegator_stake_after - delegator_stake_before - }; - - assert_eq!(delegator_1_actual_payout_1, delegator_1_expected_payout_1); - - let delegator_2_actual_payout_1 = { - let delegator_stake_before = U512::from(DELEGATOR_2_STAKE); - let delegator_stake_after = delegator_2_staked_amount_1; - delegator_stake_after - delegator_stake_before - }; - - assert_eq!(delegator_2_actual_payout_1, delegator_2_expected_payout_1); - - let era_info_1 = get_era_info(&mut builder); - - assert!(matches!( - era_info_1.select(VALIDATOR_1.clone()).next(), - Some(SeigniorageAllocation::Validator { validator_public_key, amount }) - if *validator_public_key == *VALIDATOR_1 && *amount == validator_1_expected_payout_1 - )); - - assert!(matches!( - era_info_1.select(DELEGATOR_1.clone()).next(), - Some(SeigniorageAllocation::Delegator { delegator_public_key, amount, .. }) - if *delegator_public_key == *DELEGATOR_1 && *amount == delegator_1_expected_payout_1 - )); - - assert!(matches!( - era_info_1.select(DELEGATOR_2.clone()).next(), - Some(SeigniorageAllocation::Delegator { delegator_public_key, amount, .. }) - if *delegator_public_key == *DELEGATOR_2 && *amount == delegator_2_expected_payout_1 - )); - - // Next round of rewards - let total_supply_2 = builder.total_supply(None); - let total_payout_2 = builder.base_round_reward(None); - assert!(total_supply_2 > initial_supply); - - let expected_total_reward_2 = *GENESIS_ROUND_SEIGNIORAGE_RATE * total_supply_2; - - let expected_total_reward_2_integer = expected_total_reward_2.to_integer(); - assert_eq!(total_payout_2, expected_total_reward_2_integer); - - let mut rewards = BTreeMap::new(); - rewards.insert(VALIDATOR_1.clone(), total_payout_2); - - let distribute_request = ExecuteRequestBuilder::contract_call_by_hash( - *SYSTEM_ADDR, - builder.get_auction_contract_hash(), - METHOD_DISTRIBUTE, - runtime_args! { - ARG_ENTRY_POINT => METHOD_DISTRIBUTE, - ARG_REWARDS_MAP => rewards - }, - ) - .build(); - - builder.exec(distribute_request).commit().expect_success(); - - let validator_1_staked_amount_2 = get_validator_bid(&mut builder, VALIDATOR_1.clone()) - .expect("should have validator bid") - .staked_amount(); - let delegator_1_staked_amount_2 = - get_delegator_staked_amount(&mut builder, VALIDATOR_1.clone(), DELEGATOR_1.clone()); - let delegator_2_staked_amount_2 = - get_delegator_staked_amount(&mut builder, VALIDATOR_1.clone(), DELEGATOR_2.clone()); - - let delegators_share_2 = { - let commission_rate = Ratio::new( - U512::from(VALIDATOR_1_DELEGATION_RATE), - U512::from(DELEGATION_RATE_DENOMINATOR), + let updated_total_delegator_stake = updated_delegator_1_stake + updated_delegator_2_stake; + assert!( + updated_total_delegator_stake > total_delegator_stake, + "total delegator stake should go up" ); - let reward_multiplier = - Ratio::new(U512::from(TOTAL_DELEGATOR_STAKE), U512::from(TOTAL_STAKE)); - let delegator_reward = expected_total_reward_2 - .checked_mul(&reward_multiplier) - .expect("should get delegator reward ratio"); - let commission = delegator_reward - .checked_mul(&commission_rate) - .expect("must get delegator reward"); - delegator_reward.checked_sub(&commission).unwrap() - }; - - let delegator_1_expected_payout_2 = { - let reward_multiplier = Ratio::new( - U512::from(DELEGATOR_1_STAKE), - U512::from(TOTAL_DELEGATOR_STAKE), + total_delegator_stake = updated_total_delegator_stake; + let updated_total_stake = updated_validator_stake + updated_total_delegator_stake; + assert!( + updated_total_stake > total_stake, + "total stake should go up" ); - delegators_share_2 - .checked_mul(&reward_multiplier) - .map(|ratio| ratio.to_integer()) - .expect("must get delegator 1 reward") - }; - let delegator_2_expected_payout_2 = { - let reward_multiplier = Ratio::new( - U512::from(DELEGATOR_2_STAKE), - U512::from(TOTAL_DELEGATOR_STAKE), + let delegators_share = { + let commission_rate = Ratio::new( + U512::from(VALIDATOR_1_DELEGATION_RATE), + U512::from(DELEGATION_RATE_DENOMINATOR), + ); + let reward_multiplier = Ratio::new(updated_total_delegator_stake, updated_total_stake); + let delegator_reward = expected_reward_rate + .checked_mul(&reward_multiplier) + .expect("should get delegator reward ratio"); + let commission = delegator_reward + .checked_mul(&commission_rate) + .expect("must get delegator reward"); + delegator_reward.checked_sub(&commission).unwrap() + }; + + let delegator_1_expected_payout = { + let reward_multiplier = + Ratio::new(updated_delegator_1_stake, updated_total_delegator_stake); + delegators_share + .checked_mul(&reward_multiplier) + .map(|ratio| ratio.to_integer()) + .expect("must get delegator 1 reward") + }; + + let delegator_2_expected_payout = { + let reward_multiplier = + Ratio::new(updated_delegator_2_stake, updated_total_delegator_stake); + delegators_share + .checked_mul(&reward_multiplier) + .map(|ratio| ratio.to_integer()) + .expect("must get delegator 2 reward") + }; + + let validator_1_actual_payout = updated_validator_stake - validator_stake; + + let validator_1_expected_payout = (expected_reward_rate + - Ratio::from(delegator_1_expected_payout + delegator_2_expected_payout)) + .to_integer(); + assert_eq!(validator_1_actual_payout, validator_1_expected_payout); + + let delegator_1_actual_payout = updated_delegator_1_stake - delegator_1_stake; + assert_eq!(delegator_1_actual_payout, delegator_1_expected_payout); + + let delegator_2_actual_payout = updated_delegator_2_stake - delegator_2_stake; + assert_eq!(delegator_2_actual_payout, delegator_2_expected_payout); + + let updated_era_info = get_era_info(&mut builder); + + assert!(matches!( + updated_era_info.select(VALIDATOR_1.clone()).next(), + Some(SeigniorageAllocation::Validator { validator_public_key, amount }) + if *validator_public_key == *VALIDATOR_1 && *amount == validator_1_expected_payout + )); + + assert!(matches!( + updated_era_info.select(DELEGATOR_1.clone()).next(), + Some(SeigniorageAllocation::Delegator { delegator_public_key, amount, .. }) + if *delegator_public_key == *DELEGATOR_1 && *amount == delegator_1_expected_payout + )); + + assert!(matches!( + updated_era_info.select(DELEGATOR_2.clone()).next(), + Some(SeigniorageAllocation::Delegator { delegator_public_key, amount, .. }) + if *delegator_public_key == *DELEGATOR_2 && *amount == delegator_2_expected_payout + )); + + // Next round of rewards + let updated_supply = builder.total_supply(None, protocol_version); + assert!(updated_supply > total_supply); + total_supply = updated_supply; + + let updated_rate = builder.round_seigniorage_rate(None, protocol_version); + expected_reward_rate = updated_rate * total_supply; + + // lets churn the bids just to have some fun + let undelegate_amount = delegator_1_expected_payout - 1; + let undelegate_result = builder.bidding( + None, + None, + protocol_version, + *DELEGATOR_1_ADDR, + AuctionMethod::Undelegate { + validator_public_key: VALIDATOR_1.clone(), + delegator_public_key: DELEGATOR_1.clone(), + amount: undelegate_amount, + }, ); - delegators_share_2 - .checked_mul(&reward_multiplier) - .map(|ratio| ratio.to_integer()) - .expect("must get delegator 2 reward") - }; - - let validator_1_expected_payout_2 = { - let total_delegator_payout = delegator_1_expected_payout_2 + delegator_2_expected_payout_2; - let validator_share = expected_total_reward_2 - Ratio::from(total_delegator_payout); - validator_share.to_integer() - }; - - let validator_1_actual_payout_2 = { - let validator_stake_before = validator_1_staked_amount_1; - let validator_stake_after = validator_1_staked_amount_2; - validator_stake_after - validator_stake_before - }; - assert_eq!(validator_1_actual_payout_2, validator_1_expected_payout_2); - - let delegator_1_actual_payout_2 = { - let delegator_stake_before = delegator_1_staked_amount_1; - let delegator_stake_after = delegator_1_staked_amount_2; - - delegator_stake_after - delegator_stake_before - }; - - assert_eq!(delegator_1_actual_payout_2, delegator_1_expected_payout_2); - - let delegator_2_actual_payout_2 = { - let delegator_stake_before = delegator_2_staked_amount_1; - let delegator_stake_after = delegator_2_staked_amount_2; - delegator_stake_after - delegator_stake_before - }; - - assert_eq!(delegator_2_actual_payout_2, delegator_2_expected_payout_2); - - // Ensure that paying out next set of rewards gives higher payouts than previous time. - assert!(validator_1_actual_payout_2 > validator_1_actual_payout_1); - assert!(delegator_1_actual_payout_2 > delegator_1_actual_payout_1); - assert!(delegator_2_actual_payout_2 > delegator_2_actual_payout_1); - - let era_info_2 = get_era_info(&mut builder); - - assert_ne!(era_info_2, era_info_1); - - assert!(matches!( - era_info_2.select(VALIDATOR_1.clone()).next(), - Some(SeigniorageAllocation::Validator { validator_public_key, amount, .. }) - if *validator_public_key == *VALIDATOR_1 && *amount == validator_1_expected_payout_2 - )); - - assert!(matches!( - era_info_2.select(DELEGATOR_1.clone()).next(), - Some(SeigniorageAllocation::Delegator { delegator_public_key, amount, .. }) - if *delegator_public_key == *DELEGATOR_1 && *amount == delegator_1_expected_payout_2 - )); - - assert!(matches!( - era_info_2.select(DELEGATOR_2.clone()).next(), - Some(SeigniorageAllocation::Delegator { delegator_public_key, amount, .. }) - if *delegator_public_key == *DELEGATOR_2 && *amount == delegator_2_expected_payout_2 - )); + assert!(undelegate_result.is_success(), "{:?}", undelegate_result); + delegator_1_stake = + get_delegator_staked_amount(&mut builder, VALIDATOR_1.clone(), DELEGATOR_1.clone()); - // Withdraw delegator rewards - let delegator_1_rewards = delegator_1_actual_payout_1 + delegator_1_actual_payout_2; - undelegate( - &mut builder, - *DELEGATOR_1_ADDR, - DELEGATOR_1.clone(), - VALIDATOR_1.clone(), - delegator_1_rewards, - ); - let remaining_delegator_1_bid = - get_delegator_bid(&mut builder, VALIDATOR_1.clone(), DELEGATOR_1.clone()) - .expect("should have delegator bid"); - assert_eq!( - remaining_delegator_1_bid.staked_amount(), - U512::from(DELEGATOR_1_STAKE) - ); + let updelegate_amount = U512::from(1_000_000); + let updelegate_result = builder.bidding( + None, + None, + protocol_version, + *DELEGATOR_2_ADDR, + AuctionMethod::Delegate { + max_delegators_per_validator: u32::MAX, + minimum_delegation_amount: updelegate_amount.as_u64(), + validator_public_key: VALIDATOR_1.clone(), + delegator_public_key: DELEGATOR_2.clone(), + amount: updelegate_amount, + holds_epoch: None, + }, + ); + assert!(updelegate_result.is_success(), "{:?}", updelegate_result); + delegator_2_stake = + get_delegator_staked_amount(&mut builder, VALIDATOR_1.clone(), DELEGATOR_2.clone()); - let delegator_2_rewards = delegator_2_actual_payout_1 + delegator_2_actual_payout_2; - undelegate( - &mut builder, - *DELEGATOR_2_ADDR, - DELEGATOR_2.clone(), - VALIDATOR_1.clone(), - delegator_2_rewards, - ); - let remaining_delegator_2_bid = - get_delegator_bid(&mut builder, VALIDATOR_1.clone(), DELEGATOR_2.clone()) - .expect("should have delegator bid"); - assert_eq!( - remaining_delegator_2_bid.staked_amount(), - U512::from(DELEGATOR_2_STAKE) - ); + let auction_method = { + let amount = U512::from(10_000_000); + if idx % 2 == 0 { + AuctionMethod::AddBid { + public_key: VALIDATOR_1.clone(), + amount, + delegation_rate: 0, + holds_epoch: None, + } + } else { + AuctionMethod::WithdrawBid { + public_key: VALIDATOR_1.clone(), + amount, + } + } + }; + let bid_flip_result = builder.bidding( + None, + None, + protocol_version, + *VALIDATOR_1_ADDR, + auction_method, + ); + assert!(bid_flip_result.is_success(), "{:?}", bid_flip_result); + validator_stake = get_validator_bid(&mut builder, VALIDATOR_1.clone()) + .expect("should have validator bid") + .staked_amount(); - // Withdraw validator rewards - let validator_1_rewards = validator_1_actual_payout_1 + validator_1_actual_payout_2; - withdraw_bid( - &mut builder, - *VALIDATOR_1_ADDR, - VALIDATOR_1.clone(), - validator_1_rewards, - ); - let remaining_validator_1_bid = - get_validator_bid(&mut builder, VALIDATOR_1.clone()).expect("should have validator bid"); - assert_eq!( - remaining_validator_1_bid.staked_amount(), - U512::from(VALIDATOR_1_STAKE) - ); + total_stake = validator_stake + delegator_1_stake + delegator_2_stake; + } } #[ignore] @@ -1232,11 +1148,12 @@ fn should_distribute_delegation_rate_half() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); + let protocol_version = *DEFAULT_PROTOCOL_VERSION; // initial token supply - let initial_supply = builder.total_supply(None); - let total_payout = builder.base_round_reward(None); + let initial_supply = builder.total_supply(None, protocol_version); + let total_payout = builder.base_round_reward(None, protocol_version); let expected_total_reward = *GENESIS_ROUND_SEIGNIORAGE_RATE * initial_supply; let expected_total_reward_integer = expected_total_reward.to_integer(); assert_eq!(total_payout, expected_total_reward_integer); @@ -1463,10 +1380,11 @@ fn should_distribute_delegation_rate_full() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); + let protocol_version = *DEFAULT_PROTOCOL_VERSION; // initial token supply - let initial_supply = builder.total_supply(None); + let initial_supply = builder.total_supply(None, protocol_version); let expected_total_reward = *GENESIS_ROUND_SEIGNIORAGE_RATE * initial_supply; let expected_total_reward_integer = expected_total_reward.to_integer(); @@ -1644,11 +1562,12 @@ fn should_distribute_uneven_delegation_rate_zero() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); + let protocol_version = *DEFAULT_PROTOCOL_VERSION; // initial token supply - let initial_supply = builder.total_supply(None); - let total_payout = builder.base_round_reward(None); + let initial_supply = builder.total_supply(None, protocol_version); + let total_payout = builder.base_round_reward(None, protocol_version); let expected_total_reward = *GENESIS_ROUND_SEIGNIORAGE_RATE * initial_supply; let expected_total_reward_integer = expected_total_reward.to_integer(); assert_eq!(total_payout, expected_total_reward_integer); @@ -1946,11 +1865,12 @@ fn should_distribute_with_multiple_validators_and_delegators() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); + let protocol_version = *DEFAULT_PROTOCOL_VERSION; // initial token supply - let initial_supply = builder.total_supply(None); - let total_payout = builder.base_round_reward(None); + let initial_supply = builder.total_supply(None, protocol_version); + let total_payout = builder.base_round_reward(None, protocol_version); let expected_total_reward = *GENESIS_ROUND_SEIGNIORAGE_RATE * initial_supply; let expected_total_reward_integer = expected_total_reward.to_integer(); assert_eq!(total_payout, expected_total_reward_integer); @@ -2277,11 +2197,12 @@ fn should_distribute_with_multiple_validators_and_shared_delegator() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); + let protocol_version = *DEFAULT_PROTOCOL_VERSION; // initial token supply - let initial_supply = builder.total_supply(None); - let total_payout = builder.base_round_reward(None); + let initial_supply = builder.total_supply(None, protocol_version); + let total_payout = builder.base_round_reward(None, protocol_version); let expected_total_reward = *GENESIS_ROUND_SEIGNIORAGE_RATE * initial_supply; let expected_total_reward_integer = expected_total_reward.to_integer(); assert_eq!(total_payout, expected_total_reward_integer); @@ -2633,16 +2554,17 @@ fn should_increase_total_supply_after_distribute() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); + let protocol_version = *DEFAULT_PROTOCOL_VERSION; // initial token supply - let initial_supply = builder.total_supply(None); + let initial_supply = builder.total_supply(None, protocol_version); for request in post_genesis_requests { builder.exec(request).commit().expect_success(); } - let post_genesis_supply = builder.total_supply(None); + let post_genesis_supply = builder.total_supply(None, protocol_version); assert_eq!( initial_supply, post_genesis_supply, @@ -2655,7 +2577,7 @@ fn should_increase_total_supply_after_distribute() { timestamp_millis += TIMESTAMP_MILLIS_INCREMENT; } - let post_auction_supply = builder.total_supply(None); + let post_auction_supply = builder.total_supply(None, protocol_version); assert_eq!( initial_supply, post_auction_supply, "total supply should remain unchanged regardless of auction" @@ -2668,26 +2590,28 @@ fn should_increase_total_supply_after_distribute() { rewards.insert(VALIDATOR_2.clone(), total_payout); rewards.insert(VALIDATOR_3.clone(), total_payout); - let distribute_request = ExecuteRequestBuilder::contract_call_by_hash( - *SYSTEM_ADDR, - builder.get_auction_contract_hash(), - METHOD_DISTRIBUTE, - runtime_args! { - ARG_ENTRY_POINT => METHOD_DISTRIBUTE, - ARG_REWARDS_MAP => rewards - }, - ) - .build(); - - builder.exec(distribute_request).commit().expect_success(); - - let post_distribute_supply = builder.total_supply(None); - assert!( - initial_supply < post_distribute_supply, - "total supply should increase after distribute ({} >= {})", - initial_supply, - post_distribute_supply - ); + for _ in 0..5 { + let distribute_request = ExecuteRequestBuilder::contract_call_by_hash( + *SYSTEM_ADDR, + builder.get_auction_contract_hash(), + METHOD_DISTRIBUTE, + runtime_args! { + ARG_ENTRY_POINT => METHOD_DISTRIBUTE, + ARG_REWARDS_MAP => rewards.clone() + }, + ) + .build(); + + builder.exec(distribute_request).expect_success().commit(); + + let post_distribute_supply = builder.total_supply(None, protocol_version); + assert!( + initial_supply < post_distribute_supply, + "total supply should increase after distribute ({} >= {})", + initial_supply, + post_distribute_supply + ); + } } #[ignore] @@ -2810,16 +2734,17 @@ fn should_not_create_purses_during_distribute() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); + let protocol_version = *DEFAULT_PROTOCOL_VERSION; // initial token supply - let initial_supply = builder.total_supply(None); + let initial_supply = builder.total_supply(None, protocol_version); for request in post_genesis_requests { builder.exec(request).commit().expect_success(); } - let post_genesis_supply = builder.total_supply(None); + let post_genesis_supply = builder.total_supply(None, protocol_version); assert_eq!( initial_supply, post_genesis_supply, @@ -2832,7 +2757,7 @@ fn should_not_create_purses_during_distribute() { timestamp_millis += TIMESTAMP_MILLIS_INCREMENT; } - let post_auction_supply = builder.total_supply(None); + let post_auction_supply = builder.total_supply(None, protocol_version); assert_eq!( initial_supply, post_auction_supply, "total supply should remain unchanged regardless of auction" @@ -2865,7 +2790,7 @@ fn should_not_create_purses_during_distribute() { number_of_purses_before_distribute ); - let post_distribute_supply = builder.total_supply(None); + let post_distribute_supply = builder.total_supply(None, protocol_version); assert!( initial_supply < post_distribute_supply, "total supply should increase after distribute ({} >= {})", @@ -2971,10 +2896,11 @@ fn should_distribute_delegation_rate_full_after_upgrading() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); + let protocol_version = *DEFAULT_PROTOCOL_VERSION; // initial token supply - let initial_supply = builder.total_supply(None); + let initial_supply = builder.total_supply(None, protocol_version); let expected_total_reward_before = *GENESIS_ROUND_SEIGNIORAGE_RATE * initial_supply; let expected_total_reward_integer = expected_total_reward_before.to_integer(); @@ -3040,7 +2966,7 @@ fn should_distribute_delegation_rate_full_after_upgrading() { // // Update round seigniorage rate into 50% of default value // - let new_seigniorage_multiplier = Ratio::new_raw(1, 10); + let new_seigniorage_multiplier = Ratio::new_raw(1, 2); let new_round_seigniorage_rate = DEFAULT_ROUND_SEIGNIORAGE_RATE * new_seigniorage_multiplier; let old_protocol_version = *DEFAULT_PROTOCOL_VERSION; @@ -3060,7 +2986,7 @@ fn should_distribute_delegation_rate_full_after_upgrading() { builder.upgrade(&mut upgrade_request); - let initial_supply = builder.total_supply(None); + let initial_supply = builder.total_supply(None, protocol_version); for _ in 0..5 { builder.advance_era(); @@ -3089,22 +3015,6 @@ fn should_distribute_delegation_rate_full_after_upgrading() { let mut rewards = BTreeMap::new(); rewards.insert(VALIDATOR_1.clone(), expected_total_reward_integer); - /* - let distribute_request = ExecuteRequestBuilder::contract_call_by_hash( - *SYSTEM_ADDR, - builder.get_auction_contract_hash(), - METHOD_DISTRIBUTE, - runtime_args! { - ARG_ENTRY_POINT => METHOD_DISTRIBUTE, - ARG_REWARDS_MAP => rewards - }, - ) - .with_protocol_version(new_protocol_version) - .build(); - - builder.exec(distribute_request).commit().expect_success(); - */ - let validator_1_balance_after = { let validator_staked_amount = get_validator_bid(&mut builder, VALIDATOR_1.clone()) .expect("should have validator bid") @@ -3146,9 +3056,9 @@ fn should_distribute_delegation_rate_full_after_upgrading() { validator_1_balance_after + delegator_1_balance_after + delegator_2_balance_after; assert_eq!(total_payout_after, expected_total_reward_after); - assert!(expected_validator_1_payout_before > expected_validator_1_balance_after); // expected amount after decreasing seigniorage rate is lower than the first amount - assert!(total_payout_before > total_payout_after); // expected total payout after decreasing - // rate is lower than the first payout + // expected amount after reducing the seigniorage rate is lower than the first amount + assert!(expected_validator_1_payout_before > expected_validator_1_balance_after); + assert!(total_payout_before > total_payout_after); } // In this test, we set up a validator and a delegator, then the delegator delegates to the @@ -3164,7 +3074,7 @@ fn should_not_restake_after_full_unbond() { const VALIDATOR_1_DELEGATION_RATE: DelegationRate = 0; let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // advance past the initial auction delay due to special condition of post-genesis behavior. @@ -3295,7 +3205,7 @@ fn delegator_full_unbond_during_first_reward_era() { const VALIDATOR_1_DELEGATION_RATE: DelegationRate = 0; let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // advance past the initial auction delay due to special condition of post-genesis behavior. builder.advance_eras_by_default_auction_delay(); diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs b/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs index f99b7bbbaf..9085b41282 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs @@ -4,8 +4,8 @@ use casper_engine_test_support::{ utils, ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNTS, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, DEFAULT_GENESIS_TIMESTAMP_MILLIS, DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, DEFAULT_PAYMENT, DEFAULT_PROPOSER_PUBLIC_KEY, - DEFAULT_PROTOCOL_VERSION, DEFAULT_UNBONDING_DELAY, MINIMUM_ACCOUNT_CREATION_BALANCE, - PRODUCTION_RUN_GENESIS_REQUEST, SYSTEM_ADDR, TIMESTAMP_MILLIS_INCREMENT, + DEFAULT_PROTOCOL_VERSION, DEFAULT_UNBONDING_DELAY, LOCAL_GENESIS_REQUEST, + MINIMUM_ACCOUNT_CREATION_BALANCE, SYSTEM_ADDR, TIMESTAMP_MILLIS_INCREMENT, }; use casper_execution_engine::{engine_state::Error as EngineError, execution::ExecError}; @@ -48,7 +48,7 @@ const DELEGATION_RATE: DelegationRate = 42; fn should_run_successful_bond_and_unbond_and_slashing() { let default_public_key_arg = DEFAULT_ACCOUNT_PUBLIC_KEY.clone(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -198,7 +198,7 @@ fn should_fail_bonding_with_insufficient_funds_directly() { let transfer_amount = U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE); let delegation_rate: DelegationRate = 10; - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let transfer_args = runtime_args! { mint::ARG_TARGET => new_validator_hash, @@ -275,7 +275,7 @@ fn should_fail_bonding_with_insufficient_funds() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request_1) .commit(); @@ -371,7 +371,7 @@ fn should_fail_unbonding_validator_without_bonding_first() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request).commit(); @@ -400,7 +400,7 @@ fn should_run_successful_bond_and_unbond_with_release() { DEFAULT_GENESIS_TIMESTAMP_MILLIS + DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS; let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -556,7 +556,7 @@ fn should_run_successful_unbond_funds_after_changing_unbonding_delay() { DEFAULT_GENESIS_TIMESTAMP_MILLIS + DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS; let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let new_unbonding_delay = DEFAULT_UNBONDING_DELAY + 5; diff --git a/execution_engine_testing/tests/src/test/system_contracts/genesis.rs b/execution_engine_testing/tests/src/test/system_contracts/genesis.rs index 3776e4c698..787ba0da38 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/genesis.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/genesis.rs @@ -3,7 +3,7 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ ChainspecConfig, LmdbWasmTestBuilder, DEFAULT_AUCTION_DELAY, DEFAULT_CHAINSPEC_REGISTRY, - DEFAULT_GENESIS_TIMESTAMP_MILLIS, DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, + DEFAULT_GENESIS_TIMESTAMP_MILLIS, DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, DEFAULT_PROTOCOL_VERSION, DEFAULT_ROUND_SEIGNIORAGE_RATE, DEFAULT_SYSTEM_CONFIG, DEFAULT_UNBONDING_DELAY, DEFAULT_VALIDATOR_SLOTS, DEFAULT_WASM_CONFIG, }; @@ -11,7 +11,7 @@ use casper_storage::data_access_layer::GenesisRequest; use casper_types::{ account::AccountHash, addressable_entity::EntityKindTag, system::auction::DelegationRate, GenesisAccount, GenesisConfigBuilder, GenesisValidator, Key, Motes, ProtocolVersion, PublicKey, - SecretKey, StoredValue, DEFAULT_FEE_HANDLING, DEFAULT_REFUND_HANDLING, U512, + SecretKey, StoredValue, U512, }; const GENESIS_CONFIG_HASH: [u8; 32] = [127; 32]; @@ -64,7 +64,7 @@ static GENESIS_CUSTOM_ACCOUNTS: Lazy> = Lazy::new(|| { fn should_run_genesis() { let protocol_version = ProtocolVersion::V1_0_0; - let run_genesis_request = ChainspecConfig::create_genesis_request_from_production_chainspec( + let run_genesis_request = ChainspecConfig::create_genesis_request_from_local_chainspec( GENESIS_CUSTOM_ACCOUNTS.clone(), protocol_version, ) @@ -121,15 +121,13 @@ fn should_track_total_token_supply_in_mint() { let accounts = GENESIS_CUSTOM_ACCOUNTS.clone(); let wasm_config = *DEFAULT_WASM_CONFIG; let system_config = *DEFAULT_SYSTEM_CONFIG; - let protocol_version = ProtocolVersion::V1_0_0; + let protocol_version = *DEFAULT_PROTOCOL_VERSION; let validator_slots = DEFAULT_VALIDATOR_SLOTS; let auction_delay = DEFAULT_AUCTION_DELAY; let locked_funds_period = DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS; let round_seigniorage_rate = DEFAULT_ROUND_SEIGNIORAGE_RATE; let unbonding_delay = DEFAULT_UNBONDING_DELAY; let genesis_timestamp = DEFAULT_GENESIS_TIMESTAMP_MILLIS; - let refund_handling = DEFAULT_REFUND_HANDLING; - let fee_handling = DEFAULT_FEE_HANDLING; let config = GenesisConfigBuilder::default() .with_accounts(accounts.clone()) .with_wasm_config(wasm_config) @@ -140,8 +138,6 @@ fn should_track_total_token_supply_in_mint() { .with_round_seigniorage_rate(round_seigniorage_rate) .with_unbonding_delay(unbonding_delay) .with_genesis_timestamp_millis(genesis_timestamp) - .with_refund_handling(refund_handling) - .with_fee_handling(fee_handling) .build(); let genesis_request = GenesisRequest::new( @@ -155,7 +151,7 @@ fn should_track_total_token_supply_in_mint() { builder.run_genesis(genesis_request); - let total_supply = builder.total_supply(None); + let total_supply = builder.total_supply(None, protocol_version); let expected_balance: U512 = accounts.iter().map(|item| item.balance().value()).sum(); let expected_staked_amount: U512 = accounts diff --git a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/finalize_payment.rs b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/finalize_payment.rs index ba3ca5cd22..dcd1550913 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/finalize_payment.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/finalize_payment.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, SYSTEM_ADDR, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, SYSTEM_ADDR, }; use casper_types::{ account::AccountHash, runtime_args, system::handle_payment, Key, RuntimeArgs, URef, U512, @@ -41,7 +41,7 @@ fn initialize() -> LmdbWasmTestBuilder { ) .build(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder.exec(exec_request_1).expect_success().commit(); @@ -94,7 +94,7 @@ fn finalize_payment_should_refund_to_specified_purse() { ARG_PURSE_NAME => LOCAL_REFUND_PURSE, }; - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let create_purse_request = { ExecuteRequestBuilder::standard( diff --git a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/get_payment_purse.rs b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/get_payment_purse.rs index fe5b143ca9..9f1bee804a 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/get_payment_purse.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/get_payment_purse.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, - MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_types::{account::AccountHash, runtime_args, U512}; @@ -23,7 +23,7 @@ fn should_run_get_payment_purse_contract_default_account() { ) .build(); LmdbWasmTestBuilder::default() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .expect_success() .commit(); @@ -47,7 +47,7 @@ fn should_run_get_payment_purse_contract_account_1() { ) .build(); LmdbWasmTestBuilder::default() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request_1) .expect_success() .commit() diff --git a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/refund_purse.rs b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/refund_purse.rs index a1b6844725..9c8e67234e 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/refund_purse.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/refund_purse.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_types::{account::AccountHash, runtime_args, system::mint, RuntimeArgs, U512}; @@ -36,7 +36,7 @@ fn should_run_refund_purse_contract_account_1() { fn initialize() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); builder } diff --git a/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs b/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs index a4b9987bc6..daa9b60b2a 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs @@ -5,7 +5,7 @@ use assert_matches::assert_matches; use casper_engine_test_support::{ utils, DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_ACCOUNT_KEY, DEFAULT_GAS_PRICE, DEFAULT_PAYMENT, - MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_execution_engine::{ engine_state::{Error, MAX_PAYMENT}, @@ -39,7 +39,7 @@ fn should_raise_insufficient_payment_when_caller_lacks_minimum_balance() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .expect_success() .commit() @@ -97,7 +97,7 @@ fn should_forward_payment_execution_runtime_error() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let proposer_reward_starting_balance = builder.get_proposer_purse_balance(); @@ -148,7 +148,7 @@ fn should_forward_payment_execution_gas_limit_error() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = { let deploy = DeployItemBuilder::new() @@ -238,7 +238,7 @@ fn should_run_out_of_gas_when_session_code_exceeds_gas_limit() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .commit(); @@ -278,7 +278,7 @@ fn should_correctly_charge_when_session_code_runs_out_of_gas() { let mut builder = LmdbWasmTestBuilder::default(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request) .commit(); @@ -344,7 +344,7 @@ fn should_correctly_charge_when_session_code_fails() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let proposer_reward_starting_balance = builder.get_proposer_purse_balance(); @@ -394,7 +394,7 @@ fn should_correctly_charge_when_session_code_succeeds() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let proposer_reward_starting_balance_1 = builder.get_proposer_purse_balance(); @@ -451,7 +451,7 @@ fn should_finalize_to_rewards_purse() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let proposer_reward_starting_balance = builder.get_proposer_purse_balance(); @@ -491,7 +491,7 @@ fn independent_standard_payments_should_not_write_the_same_keys() { // create another account via transfer builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(setup_exec_request) .expect_success() .commit(); diff --git a/execution_engine_testing/tests/src/test/system_contracts/upgrade.rs b/execution_engine_testing/tests/src/test/system_contracts/upgrade.rs index 71f35eac68..bafe24deb4 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/upgrade.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/upgrade.rs @@ -5,7 +5,7 @@ use num_rational::Ratio; use casper_engine_test_support::{ ChainspecConfig, ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_MAX_ASSOCIATED_KEYS, DEFAULT_UNBONDING_DELAY, - PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, }; use crate::{lmdb_fixture, lmdb_fixture::CONTRACT_REGISTRY_SPECIAL_ADDRESS}; @@ -80,7 +80,7 @@ const ARG_ACCOUNT: &str = "account"; fn should_upgrade_only_protocol_version() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // let old_wasm_config = *builder.get_engine_state().config().wasm_config(); @@ -114,7 +114,7 @@ fn should_upgrade_only_protocol_version() { fn should_allow_only_wasm_costs_patch_version() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let sem_ver = PROTOCOL_VERSION.value(); let new_protocol_version = @@ -148,7 +148,7 @@ fn should_allow_only_wasm_costs_patch_version() { fn should_allow_only_wasm_costs_minor_version() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let sem_ver = PROTOCOL_VERSION.value(); let new_protocol_version = @@ -186,7 +186,7 @@ fn should_allow_only_wasm_costs_minor_version() { fn should_not_downgrade() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // let old_wasm_config = *builder.get_engine_state().config().wasm_config(); @@ -228,7 +228,7 @@ fn should_not_downgrade() { fn should_not_skip_major_versions() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let sem_ver = PROTOCOL_VERSION.value(); @@ -255,7 +255,7 @@ fn should_not_skip_major_versions() { fn should_allow_skip_minor_versions() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let sem_ver = PROTOCOL_VERSION.value(); @@ -283,7 +283,7 @@ fn should_allow_skip_minor_versions() { fn should_upgrade_only_validator_slots() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let sem_ver = PROTOCOL_VERSION.value(); let new_protocol_version = @@ -340,7 +340,7 @@ fn should_upgrade_only_validator_slots() { fn should_upgrade_only_auction_delay() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let sem_ver = PROTOCOL_VERSION.value(); let new_protocol_version = @@ -397,7 +397,7 @@ fn should_upgrade_only_auction_delay() { fn should_upgrade_only_locked_funds_period() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let sem_ver = PROTOCOL_VERSION.value(); let new_protocol_version = @@ -454,7 +454,7 @@ fn should_upgrade_only_locked_funds_period() { fn should_upgrade_only_round_seigniorage_rate() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let sem_ver = PROTOCOL_VERSION.value(); let new_protocol_version = @@ -515,7 +515,7 @@ fn should_upgrade_only_round_seigniorage_rate() { fn should_upgrade_only_unbonding_delay() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let sem_ver = PROTOCOL_VERSION.value(); let new_protocol_version = @@ -574,7 +574,7 @@ fn should_upgrade_only_unbonding_delay() { fn should_apply_global_state_upgrade() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let sem_ver = PROTOCOL_VERSION.value(); let new_protocol_version = @@ -640,7 +640,7 @@ fn should_apply_global_state_upgrade() { fn should_increase_max_associated_keys_after_upgrade() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let sem_ver = PROTOCOL_VERSION.value(); let new_protocol_version = diff --git a/execution_engine_testing/tests/src/test/system_costs.rs b/execution_engine_testing/tests/src/test/system_costs.rs index c60246a496..1b973c7f7a 100644 --- a/execution_engine_testing/tests/src/test/system_costs.rs +++ b/execution_engine_testing/tests/src/test/system_costs.rs @@ -5,8 +5,8 @@ use casper_engine_test_support::{ utils, ChainspecConfig, DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNTS, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_ACCOUNT_PUBLIC_KEY, DEFAULT_MAX_ASSOCIATED_KEYS, DEFAULT_MINIMUM_DELEGATION_AMOUNT, - DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, MINIMUM_ACCOUNT_CREATION_BALANCE, - PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, LOCAL_GENESIS_REQUEST, + MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_types::{ runtime_args, @@ -42,8 +42,8 @@ const UPDATED_CALL_CONTRACT_COST: HostFunctionCost = 12_345; const NEW_ADD_BID_COST: u32 = 2_500_000_000; const NEW_WITHDRAW_BID_COST: u32 = 2_500_000_000; const NEW_DELEGATE_COST: u32 = 2_500_000_000; -const NEW_UNDELEGATE_COST: u32 = 2_500_000_000; -const NEW_REDELEGATE_COST: u32 = 2_500_000_000; +const NEW_UNDELEGATE_COST: u32 = NEW_DELEGATE_COST; +const NEW_REDELEGATE_COST: u32 = NEW_DELEGATE_COST; const DEFAULT_ACTIVATION_POINT: EraId = EraId::new(1); static OLD_PROTOCOL_VERSION: Lazy = Lazy::new(|| *DEFAULT_PROTOCOL_VERSION); @@ -64,7 +64,7 @@ const ARG_AMOUNT: &str = "amount"; fn add_bid_and_withdraw_bid_have_expected_costs() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let system_contract_hashes_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -181,7 +181,7 @@ fn upgraded_add_bid_and_withdraw_bid_have_expected_costs() { // .build(); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let mut upgrade_request = { UpgradeRequestBuilder::new() @@ -515,6 +515,7 @@ fn upgraded_delegate_and_undelegate_have_expected_costs() { balance_after, balance_before - U512::from(BID_AMOUNT) - transaction_fee_1, ); + assert_eq!(builder.last_exec_gas_cost().value(), call_cost); // Redelegate bid @@ -583,7 +584,7 @@ fn upgraded_delegate_and_undelegate_have_expected_costs() { fn mint_transfer_has_expected_costs() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let transfer_request_1 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -653,7 +654,7 @@ fn mint_transfer_has_expected_costs() { fn should_charge_for_erroneous_system_contract_calls() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let auction_hash = builder.get_auction_contract_hash(); let mint_hash = builder.get_mint_contract_hash(); @@ -775,7 +776,12 @@ fn should_charge_for_erroneous_system_contract_calls() { entrypoint, expected_cost, ); - assert_eq!(builder.last_exec_gas_cost().value(), call_cost); + assert_eq!( + builder.last_exec_gas_cost().value(), + call_cost, + "{:?}", + entrypoint + ); } } @@ -784,7 +790,7 @@ fn should_charge_for_erroneous_system_contract_calls() { fn should_verify_do_nothing_charges_only_for_standard_payment() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -824,7 +830,7 @@ fn should_verify_do_nothing_charges_only_for_standard_payment() { fn should_verify_wasm_add_bid_wasm_cost_is_not_recursive() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let new_opcode_costs = OpcodeCosts { bit: 0, diff --git a/execution_engine_testing/tests/src/test/tutorial/counter.rs b/execution_engine_testing/tests/src/test/tutorial/counter.rs index fdcb3d7364..b7ac5c1ea7 100644 --- a/execution_engine_testing/tests/src/test/tutorial/counter.rs +++ b/execution_engine_testing/tests/src/test/tutorial/counter.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::{Key, RuntimeArgs, StoredValue}; @@ -13,7 +12,7 @@ const COUNTER_KEY: &str = "counter"; #[test] fn should_run_counter_example() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let install_request_1 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, diff --git a/execution_engine_testing/tests/src/test/tutorial/hello_world.rs b/execution_engine_testing/tests/src/test/tutorial/hello_world.rs index 6b81358c1d..a25c7ed62a 100644 --- a/execution_engine_testing/tests/src/test/tutorial/hello_world.rs +++ b/execution_engine_testing/tests/src/test/tutorial/hello_world.rs @@ -1,6 +1,5 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, LOCAL_GENESIS_REQUEST, }; use casper_types::{runtime_args, Key, StoredValue}; @@ -13,7 +12,7 @@ const MESSAGE_VALUE: &str = "Hello, world!"; #[test] fn should_run_hello_world() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let exec_request = { let session_args = runtime_args! { diff --git a/execution_engine_testing/tests/src/test/upgrade.rs b/execution_engine_testing/tests/src/test/upgrade.rs index c77122cf40..1f86047fa8 100644 --- a/execution_engine_testing/tests/src/test/upgrade.rs +++ b/execution_engine_testing/tests/src/test/upgrade.rs @@ -1,6 +1,6 @@ use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, - MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_execution_engine::{engine_state, execution::ExecError}; @@ -50,7 +50,7 @@ const ARG_IS_LOCKED: &str = "is_locked"; fn should_upgrade_do_nothing_to_do_something_version_hash_call() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // Create contract package and store contract ver: 1.0.0 with "delegate" entry function { @@ -164,7 +164,7 @@ fn should_upgrade_do_nothing_to_do_something_version_hash_call() { fn should_upgrade_do_nothing_to_do_something_contract_call() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // Create contract package and store contract ver: 1.0.0 { @@ -298,7 +298,7 @@ fn should_upgrade_do_nothing_to_do_something_contract_call() { fn should_be_able_to_observe_state_transition_across_upgrade() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // store do-nothing-stored { @@ -397,7 +397,7 @@ fn should_be_able_to_observe_state_transition_across_upgrade() { fn should_support_extending_functionality() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // store do-nothing-stored { @@ -540,7 +540,7 @@ fn should_support_extending_functionality() { fn should_maintain_named_keys_across_upgrade() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // store contract { @@ -644,7 +644,7 @@ fn should_maintain_named_keys_across_upgrade() { fn should_fail_upgrade_for_locked_contract() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); // store contract { @@ -715,7 +715,7 @@ fn should_only_upgrade_if_threshold_is_met() { let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let install_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, diff --git a/execution_engine_testing/tests/src/test/wasmless_transfer.rs b/execution_engine_testing/tests/src/test/wasmless_transfer.rs index d7953ef31a..864654dcd1 100644 --- a/execution_engine_testing/tests/src/test/wasmless_transfer.rs +++ b/execution_engine_testing/tests/src/test/wasmless_transfer.rs @@ -2,8 +2,7 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, - DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, - PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, LOCAL_GENESIS_REQUEST, }; use casper_execution_engine::engine_state::{ Error as CoreError, WASMLESS_TRANSFER_FIXED_GAS_PRICE, @@ -651,7 +650,7 @@ fn init_wasmless_transform_builder(create_account_2: bool) -> LmdbWasmTestBuilde .build(); builder - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()) + .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(create_account_1_request) .expect_success() .commit(); @@ -967,7 +966,7 @@ fn transfer_wasmless_should_observe_upgraded_cost() { ); let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 0a9c346ad2..b6910dcb03 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -30,7 +30,6 @@ use casper_types::{ bytesrepr::{self, ToBytes, U32_SERIALIZED_LENGTH}, contract_messages::Messages, execution::{Effects, ExecutionResult, ExecutionResultV2, Transform, TransformKind}, - system::mint::ARG_HOLDS_EPOCH, BlockV2, CLValue, Chainspec, ChecksumRegistry, DeployHash, Digest, EraEndV2, EraId, Key, ProtocolVersion, PublicKey, Transaction, TransactionApprovalsHash, U512, }; @@ -81,8 +80,7 @@ pub fn execute_finalized_block( let mut execution_artifacts: Vec = Vec::with_capacity(executable_block.transactions.len()); let block_time = executable_block.timestamp.millis(); - let holds_epoch = - block_time.saturating_sub(chainspec.core_config.balance_hold_interval.millis()); + let holds_epoch = Some(chainspec.balance_holds_epoch(executable_block.timestamp)); let start = Instant::now(); let txn_ids = executable_block @@ -100,14 +98,8 @@ pub fn execute_finalized_block( for transaction in executable_block.transactions { let transaction_hash = transaction.hash(); - let mut runtime_args = transaction.session_args().clone(); + let runtime_args = transaction.session_args().clone(); let entry_point = transaction.entry_point(); - if entry_point.requires_holds_epoch() { - if let Err(cve) = runtime_args.insert(ARG_HOLDS_EPOCH, Some(holds_epoch)) { - error!(%transaction_hash, ?cve, "failed to extend args with holds epoch"); - continue; // skip to next record - } - } // handle payment per the chainspec determined fee setting // match chainspec.core_config.fee_handling { @@ -116,11 +108,11 @@ pub fn execute_finalized_block( // // amount is placed on the paying purse(s). // let hold_amount = transaction.gas_limit(); // let hold_purse = get_purse_from_transaction_initiator(); - // let hold_req = HoldRequest::new(hold_purse, hold_amount); + // let hold_req = BalanceHoldRequest::new(hold_purse, hold_amount); // match scratch_state.hold(hold_req) { - // HoldResult::RootNotFound => {} - // HoldResult::Failure(tce) => {} - // HoldResult::Success{ effects } => {} + // BalanceHoldRequest::RootNotFound => {} + // BalanceHoldRequest::Failure(tce) => {} + // BalanceHoldRequest::Success{ effects } => {} // } // } // FeeHandling::PayToProposer => { @@ -145,7 +137,7 @@ pub fn execute_finalized_block( let transfer_req = TransferRequest::with_runtime_args( native_runtime_config.clone(), state_root_hash, - block_time, + holds_epoch, protocol_version, transaction_hash, transaction.initiator_addr().account_hash(), @@ -203,14 +195,19 @@ pub fn execute_finalized_block( continue; } if transaction.is_native_auction() { - let auction_method = - match AuctionMethod::from_parts(entry_point, &runtime_args, chainspec) { - Ok(auction_method) => auction_method, - Err(_) => { - error!(%transaction_hash, "failed to resolve auction method"); - continue; // skip to next record - } - }; + let runtime_args = transaction.session_args(); + let auction_method = match AuctionMethod::from_parts( + entry_point, + runtime_args, + holds_epoch, + chainspec, + ) { + Ok(auction_method) => auction_method, + Err(_) => { + error!(%transaction_hash, "failed to resolve auction method"); + continue; // skip to next record + } + }; let authorization_keys = transaction.authorization_keys(); let bidding_req = BiddingRequest::new( native_runtime_config.clone(), @@ -291,7 +288,7 @@ pub fn execute_finalized_block( native_runtime_config.clone(), state_root_hash, protocol_version, - block_time, + holds_epoch, ); match scratch_state.distribute_fees(fee_req) { FeeResult::RootNotFound => { diff --git a/node/src/components/contract_runtime/tests.rs b/node/src/components/contract_runtime/tests.rs index c907294edf..902a0c7899 100644 --- a/node/src/components/contract_runtime/tests.rs +++ b/node/src/components/contract_runtime/tests.rs @@ -408,7 +408,8 @@ mod trie_chunking_tests { global_state::Pointer, testing::TestRng, ActivationPoint, CLValue, Chainspec, ChunkWithProof, CoreConfig, Digest, EraId, Key, - ProtocolConfig, StoredValue, TimeDiff, DEFAULT_FEE_HANDLING, DEFAULT_REFUND_HANDLING, + ProtocolConfig, StoredValue, TimeDiff, DEFAULT_BALANCE_HOLD_INTERVAL, DEFAULT_FEE_HANDLING, + DEFAULT_REFUND_HANDLING, }; use prometheus::Registry; use tempfile::tempdir; @@ -487,6 +488,7 @@ mod trie_chunking_tests { allow_unrestricted_transfers: true, fee_handling: DEFAULT_FEE_HANDLING, refund_handling: DEFAULT_REFUND_HANDLING, + balance_hold_interval: DEFAULT_BALANCE_HOLD_INTERVAL, ..CoreConfig::random(rng) }, wasm_config: Default::default(), diff --git a/storage/src/data_access_layer/bidding.rs b/storage/src/data_access_layer/bidding.rs index 499fb67978..85b6e604c3 100644 --- a/storage/src/data_access_layer/bidding.rs +++ b/storage/src/data_access_layer/bidding.rs @@ -5,7 +5,7 @@ use casper_types::{ account::AccountHash, bytesrepr::FromBytes, execution::Effects, - system::{auction, auction::DelegationRate, mint}, + system::{auction, auction::DelegationRate}, CLTyped, CLValue, Chainspec, Digest, ProtocolVersion, PublicKey, RuntimeArgs, TransactionEntryPoint, TransactionHash, U512, }; @@ -54,6 +54,7 @@ impl AuctionMethod { pub fn from_parts( entry_point: TransactionEntryPoint, runtime_args: &RuntimeArgs, + holds_epoch: Option, chainspec: &Chainspec, ) -> Result { match entry_point { @@ -67,11 +68,15 @@ impl AuctionMethod { TransactionEntryPoint::ActivateBid => { Self::activate_bid_from_args(runtime_args, chainspec) } - TransactionEntryPoint::AddBid => Self::add_bid_from_args(runtime_args, chainspec), + TransactionEntryPoint::AddBid => { + Self::add_bid_from_args(runtime_args, holds_epoch, chainspec) + } TransactionEntryPoint::WithdrawBid => { Self::withdraw_bid_from_args(runtime_args, chainspec) } - TransactionEntryPoint::Delegate => Self::delegate_from_args(runtime_args, chainspec), + TransactionEntryPoint::Delegate => { + Self::delegate_from_args(runtime_args, holds_epoch, chainspec) + } TransactionEntryPoint::Undelegate => { Self::undelegate_from_args(runtime_args, chainspec) } @@ -94,12 +99,12 @@ impl AuctionMethod { pub fn add_bid_from_args( runtime_args: &RuntimeArgs, + holds_epoch: Option, _chainspec: &Chainspec, ) -> Result { let public_key = Self::get_named_argument(runtime_args, auction::ARG_PUBLIC_KEY)?; let delegation_rate = Self::get_named_argument(runtime_args, auction::ARG_DELEGATION_RATE)?; let amount = Self::get_named_argument(runtime_args, auction::ARG_AMOUNT)?; - let holds_epoch = Self::get_named_argument(runtime_args, mint::ARG_HOLDS_EPOCH)?; Ok(Self::AddBid { public_key, delegation_rate, @@ -119,6 +124,7 @@ impl AuctionMethod { pub fn delegate_from_args( runtime_args: &RuntimeArgs, + holds_epoch: Option, chainspec: &Chainspec, ) -> Result { let delegator_public_key = Self::get_named_argument(runtime_args, auction::ARG_DELEGATOR)?; @@ -127,7 +133,6 @@ impl AuctionMethod { let max_delegators_per_validator = chainspec.core_config.max_delegators_per_validator; let minimum_delegation_amount = chainspec.core_config.minimum_delegation_amount; - let holds_epoch = Self::get_named_argument(runtime_args, mint::ARG_HOLDS_EPOCH)?; Ok(Self::Delegate { delegator_public_key, @@ -282,3 +287,10 @@ pub enum BiddingResult { /// Bidding request failed Failure(TrackingCopyError), } + +impl BiddingResult { + /// Is this a success. + pub fn is_success(&self) -> bool { + matches!(self, BiddingResult::Success { .. }) + } +} diff --git a/storage/src/data_access_layer/fee.rs b/storage/src/data_access_layer/fee.rs index 6d7a158357..723cb4cafb 100644 --- a/storage/src/data_access_layer/fee.rs +++ b/storage/src/data_access_layer/fee.rs @@ -16,7 +16,7 @@ pub struct FeeRequest { config: NativeRuntimeConfig, state_hash: Digest, protocol_version: ProtocolVersion, - block_time: u64, + holds_epoch: Option, } impl FeeRequest { @@ -24,13 +24,13 @@ impl FeeRequest { config: NativeRuntimeConfig, state_hash: Digest, protocol_version: ProtocolVersion, - block_time: u64, + holds_epoch: Option, ) -> Self { FeeRequest { config, state_hash, protocol_version, - block_time, + holds_epoch, } } @@ -54,9 +54,9 @@ impl FeeRequest { self.config.fee_handling() } - /// Returns block time. - pub fn block_time(&self) -> u64 { - self.block_time + /// Returns holds epoch. + pub fn holds_epoch(&self) -> Option { + self.holds_epoch } /// Returns administrative accounts, if any. diff --git a/storage/src/data_access_layer/transfer.rs b/storage/src/data_access_layer/transfer.rs index b20ca9a55b..9469b5345c 100644 --- a/storage/src/data_access_layer/transfer.rs +++ b/storage/src/data_access_layer/transfer.rs @@ -22,8 +22,8 @@ pub struct TransferRequest { config: NativeRuntimeConfig, /// State root hash. state_hash: Digest, - /// Block time represented as a unix timestamp. - block_time: u64, + /// Balance holds epoch. + holds_epoch: Option, /// Protocol version. protocol_version: ProtocolVersion, /// Transaction hash. @@ -44,7 +44,7 @@ impl TransferRequest { pub fn new( config: NativeRuntimeConfig, state_hash: Digest, - block_time: u64, + holds_epoch: Option, protocol_version: ProtocolVersion, transaction_hash: TransactionHash, address: AccountHash, @@ -56,7 +56,7 @@ impl TransferRequest { Self { config, state_hash, - block_time, + holds_epoch, protocol_version, transaction_hash, address, @@ -71,7 +71,7 @@ impl TransferRequest { pub fn with_runtime_args( config: NativeRuntimeConfig, state_hash: Digest, - block_time: u64, + holds_epoch: Option, protocol_version: ProtocolVersion, transaction_hash: TransactionHash, address: AccountHash, @@ -83,7 +83,7 @@ impl TransferRequest { Self { config, state_hash, - block_time, + holds_epoch, protocol_version, transaction_hash, address, @@ -122,8 +122,8 @@ impl TransferRequest { } /// Returns block time. - pub fn block_time(&self) -> u64 { - self.block_time + pub fn holds_epoch(&self) -> Option { + self.holds_epoch } /// Returns transaction hash. diff --git a/storage/src/global_state/state/mod.rs b/storage/src/global_state/state/mod.rs index 7d47af9a23..5147728719 100644 --- a/storage/src/global_state/state/mod.rs +++ b/storage/src/global_state/state/mod.rs @@ -73,7 +73,7 @@ use crate::{ genesis::{GenesisError, GenesisInstaller}, mint::Mint, protocol_upgrade::{ProtocolUpgradeError, ProtocolUpgrader}, - runtime_native::RuntimeNative, + runtime_native::{Id, RuntimeNative}, transfer::{ NewTransferTargetMode, TransferArgs, TransferError, TransferRuntimeArgsBuilder, }, @@ -520,9 +520,10 @@ pub trait CommitProvider: StateProvider { }; } + let holds_epoch = request.holds_epoch(); let system_account_key = PublicKey::System; let id = { - let mut bytes = match request.block_time().into_bytes() { + let mut bytes = match holds_epoch.into_bytes() { Ok(bytes) => bytes, Err(bre) => { return FeeResult::Failure(FeeError::TrackingCopy( @@ -543,7 +544,6 @@ pub trait CommitProvider: StateProvider { }; let config = request.config(); - let block_time = request.block_time(); let authorization_keys = { let mut auth_keys = BTreeSet::new(); auth_keys.insert(system_account_key.to_account_hash()); @@ -561,8 +561,6 @@ pub trait CommitProvider: StateProvider { } }; - let holds_epoch = block_time.saturating_sub(request.config().balance_hold_interval()); - for target in administrative_accounts { let target_purse = match tc .borrow_mut() @@ -577,13 +575,12 @@ pub trait CommitProvider: StateProvider { target_purse, fee_portion, None, - Some(holds_epoch), ); let transfer_req = TransferRequest::new( config.clone(), current_state_hash, - block_time, + holds_epoch, protocol_version, tmp_hash, system_account_key.to_account_hash(), @@ -634,38 +631,19 @@ pub trait CommitProvider: StateProvider { let protocol_version = request.protocol_version(); let config = request.config(); - let id = crate::system::runtime_native::Id::Transaction(request.transaction_hash()); - let initiating_address = request.address(); - let authorization_keys = request.authorization_keys(); - let transfer_config = config.transfer_config(); - let administrative_accounts = transfer_config.administrative_accounts(); - let (entity, entity_named_keys, entity_access_rights) = - match tc.borrow_mut().resolved_entity( - protocol_version, - initiating_address, - authorization_keys, - &administrative_accounts, - ) { - Ok(ret) => ret, - Err(tce) => { - return BiddingResult::Failure(tce); - } - }; - - // IMPORTANT: this runtime _must_ use the initiator's context. - let mut runtime = RuntimeNative::new( - protocol_version, + let mut runtime = match RuntimeNative::new_system_runtime( config.clone(), - id, + protocol_version, + Id::Transaction(request.transaction_hash()), Rc::clone(&tc), - initiating_address, - entity, - entity_named_keys, - entity_access_rights, - U512::MAX, Phase::Session, - ); + ) { + Ok(rt) => rt, + Err(tce) => { + return BiddingResult::Failure(tce); + } + }; let auction_method = request.auction_method(); @@ -1442,16 +1420,14 @@ pub trait StateProvider { } } - let transfer_args = { - match runtime_args_builder.build( - &entity, - entity_named_keys, - protocol_version, - Rc::clone(&tc), - ) { - Ok(transfer_args) => transfer_args, - Err(error) => return TransferResult::Failure(error), - } + let transfer_args = match runtime_args_builder.build( + &entity, + entity_named_keys, + protocol_version, + Rc::clone(&tc), + ) { + Ok(transfer_args) => transfer_args, + Err(error) => return TransferResult::Failure(error), }; if let Err(mint_error) = runtime.transfer( transfer_args.to(), @@ -1459,7 +1435,7 @@ pub trait StateProvider { transfer_args.target(), transfer_args.amount(), transfer_args.arg_id(), - transfer_args.holds_epoch(), + request.holds_epoch(), ) { return TransferResult::Failure(TransferError::Mint(mint_error)); } diff --git a/storage/src/system/auction.rs b/storage/src/system/auction.rs index 5a37a70406..780661af65 100644 --- a/storage/src/system/auction.rs +++ b/storage/src/system/auction.rs @@ -72,13 +72,11 @@ pub trait Auction: holds_epoch: Option, ) -> Result { if !self.allow_auction_bids() { - // Validation set rotation might be disabled on some private chains and we should not - // allow new bids to come in. + // The validator set may be closed on some side chains, + // which is configured by disabling bids. return Err(Error::AuctionBidsDisabled.into()); } - let provided_account_hash = AccountHash::from_public_key(&public_key, |x| self.blake2b(x)); - if amount.is_zero() { return Err(Error::BondTooSmall.into()); } @@ -87,6 +85,8 @@ pub trait Auction: return Err(Error::DelegationRateTooLarge.into()); } + let provided_account_hash = AccountHash::from_public_key(&public_key, |x| self.blake2b(x)); + if !self.is_allowed_session_caller(&provided_account_hash) { return Err(Error::InvalidContext.into()); } diff --git a/storage/src/system/auction/detail.rs b/storage/src/system/auction/detail.rs index e30135f481..1e8debd151 100644 --- a/storage/src/system/auction/detail.rs +++ b/storage/src/system/auction/detail.rs @@ -24,7 +24,13 @@ where P: StorageProvider + RuntimeProvider + ?Sized, T: FromBytes + CLTyped, { - let key = provider.named_keys_get(name).ok_or(Error::MissingKey)?; + let key = match provider.named_keys_get(name) { + None => { + error!("auction missing named key {:?}", name); + return Err(Error::MissingKey); + } + Some(key) => key, + }; let uref = key.into_uref().ok_or(Error::InvalidKeyVariant)?; let value: T = provider.read(uref)?.ok_or(Error::MissingValue)?; Ok(value) diff --git a/storage/src/system/transfer.rs b/storage/src/system/transfer.rs index b985615c7e..93b80985f1 100644 --- a/storage/src/system/transfer.rs +++ b/storage/src/system/transfer.rs @@ -137,7 +137,6 @@ pub struct TransferArgs { target: URef, amount: U512, arg_id: Option, - holds_epoch: Option, } impl TransferArgs { @@ -148,7 +147,6 @@ impl TransferArgs { target: URef, amount: U512, arg_id: Option, - holds_epoch: Option, ) -> Self { Self { to, @@ -156,7 +154,6 @@ impl TransferArgs { target, amount, arg_id, - holds_epoch, } } @@ -184,11 +181,6 @@ impl TransferArgs { pub fn arg_id(&self) -> Option { self.arg_id } - - /// Returns `holds_epoch` field. - pub fn holds_epoch(&self) -> Option { - self.holds_epoch - } } impl TryFrom for RuntimeArgs { @@ -202,7 +194,6 @@ impl TryFrom for RuntimeArgs { runtime_args.insert(mint::ARG_TARGET, transfer_args.target)?; runtime_args.insert(mint::ARG_AMOUNT, transfer_args.amount)?; runtime_args.insert(mint::ARG_ID, transfer_args.arg_id)?; - runtime_args.insert(mint::ARG_HOLDS_EPOCH, transfer_args.holds_epoch)?; Ok(runtime_args) } @@ -418,15 +409,6 @@ impl TransferRuntimeArgsBuilder { Ok(id) } - fn resolve_holds_epoch(&self) -> Result, TransferError> { - let id_value = self - .inner - .get(mint::ARG_HOLDS_EPOCH) - .ok_or_else(|| TransferError::MissingArgument)?; - let id: Option = self.map_cl_value(id_value)?; - Ok(id) - } - /// Creates new [`TransferArgs`] instance. pub fn build( mut self, @@ -468,15 +450,12 @@ impl TransferRuntimeArgsBuilder { let arg_id = self.resolve_id()?; - let holds_epoch = self.resolve_holds_epoch()?; - Ok(TransferArgs { to, source, target, amount, arg_id, - holds_epoch, }) } diff --git a/types/src/chainspec.rs b/types/src/chainspec.rs index e021c44f52..93a6bf76b8 100644 --- a/types/src/chainspec.rs +++ b/types/src/chainspec.rs @@ -30,7 +30,7 @@ use tracing::error; use crate::testing::TestRng; use crate::{ bytesrepr::{self, FromBytes, ToBytes}, - ChainNameDigest, Digest, EraId, ProtocolVersion, + ChainNameDigest, Digest, EraId, ProtocolVersion, Timestamp, }; pub use accounts_config::{ AccountConfig, AccountsConfig, AdministratorAccount, DelegatorConfig, GenesisAccount, @@ -38,12 +38,15 @@ pub use accounts_config::{ }; pub use activation_point::ActivationPoint; pub use chainspec_raw_bytes::ChainspecRawBytes; -pub use core_config::{ConsensusProtocolName, CoreConfig, LegacyRequiredFinality}; +pub use core_config::{ + ConsensusProtocolName, CoreConfig, LegacyRequiredFinality, DEFAULT_BALANCE_HOLD_INTERVAL, + DEFAULT_FEE_HANDLING, DEFAULT_REFUND_HANDLING, +}; pub use fee_handling::FeeHandling; +#[cfg(any(feature = "testing", test))] +pub use genesis_config::DEFAULT_AUCTION_DELAY; #[cfg(any(feature = "std", test))] pub use genesis_config::{GenesisConfig, GenesisConfigBuilder}; -#[cfg(any(feature = "testing", test))] -pub use genesis_config::{DEFAULT_AUCTION_DELAY, DEFAULT_FEE_HANDLING, DEFAULT_REFUND_HANDLING}; pub use global_state_update::{GlobalStateUpdate, GlobalStateUpdateConfig, GlobalStateUpdateError}; pub use highway_config::HighwayConfig; pub use network_config::NetworkConfig; @@ -183,6 +186,14 @@ impl Chainspec { fee_handling, )) } + + /// Returns balance hold epoch based upon configured hold interval, calculated from the imputed + /// timestamp. + pub fn balance_holds_epoch(&self, timestamp: Timestamp) -> u64 { + timestamp + .millis() + .saturating_sub(self.core_config.balance_hold_interval.millis()) + } } #[cfg(any(feature = "testing", test))] diff --git a/types/src/chainspec/core_config.rs b/types/src/chainspec/core_config.rs index 7cad2b2e16..e48d57f55f 100644 --- a/types/src/chainspec/core_config.rs +++ b/types/src/chainspec/core_config.rs @@ -28,6 +28,17 @@ pub const DEFAULT_MAX_ASSOCIATED_KEYS: u32 = 100; /// Default value for maximum runtime call stack height configuration option. pub const DEFAULT_MAX_RUNTIME_CALL_STACK_HEIGHT: u32 = 12; +/// Default refund handling. +pub const DEFAULT_REFUND_HANDLING: RefundHandling = RefundHandling::Refund { + refund_ratio: Ratio::new_raw(99, 100), +}; + +/// Default fee handling. +pub const DEFAULT_FEE_HANDLING: FeeHandling = FeeHandling::PayToProposer; + +/// Default balance hold interval. +pub const DEFAULT_BALANCE_HOLD_INTERVAL: TimeDiff = TimeDiff::from_seconds(24 * 60 * 60); + /// Configuration values associated with the core protocol. #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] #[cfg_attr(feature = "datasize", derive(DataSize))] @@ -272,11 +283,9 @@ impl Default for CoreConfig { allow_unrestricted_transfers: true, compute_rewards: true, administrators: Default::default(), - refund_handling: RefundHandling::Refund { - refund_ratio: Ratio::new_raw(99, 100), - }, - fee_handling: FeeHandling::PayToProposer, - balance_hold_interval: TimeDiff::from_seconds(24 * 60 * 60), + refund_handling: DEFAULT_REFUND_HANDLING, + fee_handling: DEFAULT_FEE_HANDLING, + balance_hold_interval: DEFAULT_BALANCE_HOLD_INTERVAL, } } } diff --git a/types/src/chainspec/genesis_config.rs b/types/src/chainspec/genesis_config.rs index 9890474faa..1a1dcd71ea 100644 --- a/types/src/chainspec/genesis_config.rs +++ b/types/src/chainspec/genesis_config.rs @@ -10,8 +10,7 @@ use rand::{ use serde::{Deserialize, Serialize}; use crate::{ - AdministratorAccount, Chainspec, FeeHandling, GenesisAccount, Motes, PublicKey, RefundHandling, - SystemConfig, WasmConfig, + AdministratorAccount, Chainspec, GenesisAccount, Motes, PublicKey, SystemConfig, WasmConfig, }; /// Default number of validator slots. @@ -32,12 +31,6 @@ pub const DEFAULT_UNBONDING_DELAY: u64 = 7; pub const DEFAULT_ROUND_SEIGNIORAGE_RATE: Ratio = Ratio::new_raw(7, 175070816); /// Default genesis timestamp in milliseconds. pub const DEFAULT_GENESIS_TIMESTAMP_MILLIS: u64 = 0; -/// Default fee handling. -pub const DEFAULT_FEE_HANDLING: FeeHandling = FeeHandling::PayToProposer; -/// Default gas cost refund ratio. -pub const DEFAULT_REFUND_HANDLING: RefundHandling = RefundHandling::Refund { - refund_ratio: Ratio::new_raw(99, 100), -}; /// Represents the details of a genesis process. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] @@ -51,8 +44,6 @@ pub struct GenesisConfig { round_seigniorage_rate: Ratio, unbonding_delay: u64, genesis_timestamp_millis: u64, - refund_handling: RefundHandling, - fee_handling: FeeHandling, } impl GenesisConfig { @@ -86,8 +77,6 @@ impl GenesisConfig { round_seigniorage_rate, unbonding_delay, genesis_timestamp_millis, - refund_handling: DEFAULT_REFUND_HANDLING, - fee_handling: DEFAULT_FEE_HANDLING, } } @@ -195,16 +184,6 @@ impl Distribution for Standard { let genesis_timestamp_millis = rng.gen(); - let refund_handling = RefundHandling::Refund { - refund_ratio: Ratio::new_raw(rng.gen_range(0..=100), 100), - }; - - let fee_handling = if rng.gen() { - FeeHandling::Accumulate - } else { - FeeHandling::PayToProposer - }; - GenesisConfig { accounts, wasm_config, @@ -215,8 +194,6 @@ impl Distribution for Standard { round_seigniorage_rate, unbonding_delay, genesis_timestamp_millis, - refund_handling, - fee_handling, } } } @@ -236,8 +213,6 @@ pub struct GenesisConfigBuilder { round_seigniorage_rate: Option>, unbonding_delay: Option, genesis_timestamp_millis: Option, - refund_handling: Option, - fee_handling: Option, } impl GenesisConfigBuilder { @@ -300,18 +275,6 @@ impl GenesisConfigBuilder { self } - /// Sets the refund handling config option. - pub fn with_refund_handling(mut self, refund_handling: RefundHandling) -> Self { - self.refund_handling = Some(refund_handling); - self - } - - /// Sets the fee handling config option. - pub fn with_fee_handling(mut self, fee_handling: FeeHandling) -> Self { - self.fee_handling = Some(fee_handling); - self - } - /// Builds a new [`GenesisConfig`] object. pub fn build(self) -> GenesisConfig { GenesisConfig { @@ -330,8 +293,6 @@ impl GenesisConfigBuilder { genesis_timestamp_millis: self .genesis_timestamp_millis .unwrap_or(DEFAULT_GENESIS_TIMESTAMP_MILLIS), - refund_handling: self.refund_handling.unwrap_or(DEFAULT_REFUND_HANDLING), - fee_handling: self.fee_handling.unwrap_or(DEFAULT_FEE_HANDLING), } } } @@ -354,8 +315,6 @@ impl From<&Chainspec> for GenesisConfig { .with_round_seigniorage_rate(chainspec.core_config.round_seigniorage_rate) .with_unbonding_delay(chainspec.core_config.unbonding_delay) .with_genesis_timestamp_millis(genesis_timestamp_millis) - .with_refund_handling(chainspec.core_config.refund_handling) - .with_fee_handling(chainspec.core_config.fee_handling) .build() } } diff --git a/types/src/chainspec/vm_config/auction_costs.rs b/types/src/chainspec/vm_config/auction_costs.rs index 03b2199fc0..2a9aebf103 100644 --- a/types/src/chainspec/vm_config/auction_costs.rs +++ b/types/src/chainspec/vm_config/auction_costs.rs @@ -17,13 +17,13 @@ pub const DEFAULT_READ_SEIGNIORAGE_RECIPIENTS_COST: u32 = 10_000; /// Default cost of the `add_bid` auction entry point. pub const DEFAULT_ADD_BID_COST: u32 = 2_500_000_000; /// Default cost of the `withdraw_bid` auction entry point. -pub const DEFAULT_WITHDRAW_BID_COST: u32 = 2_500_000_000; +pub const DEFAULT_WITHDRAW_BID_COST: u32 = DEFAULT_ADD_BID_COST; /// Default cost of the `delegate` auction entry point. -pub const DEFAULT_DELEGATE_COST: u32 = 2_500_000_000; +pub const DEFAULT_DELEGATE_COST: u32 = DEFAULT_ADD_BID_COST; /// Default cost of the `redelegate` auction entry point. -pub const DEFAULT_REDELEGATE_COST: u32 = 2_500_000_000; +pub const DEFAULT_REDELEGATE_COST: u32 = DEFAULT_ADD_BID_COST; /// Default cost of the `undelegate` auction entry point. -pub const DEFAULT_UNDELEGATE_COST: u32 = 2_500_000_000; +pub const DEFAULT_UNDELEGATE_COST: u32 = DEFAULT_ADD_BID_COST; /// Default cost of the `run_auction` auction entry point. pub const DEFAULT_RUN_AUCTION_COST: u32 = 10_000; /// Default cost of the `slash` auction entry point. diff --git a/types/src/gas.rs b/types/src/gas.rs index 7689849e5f..0d0d1a401c 100644 --- a/types/src/gas.rs +++ b/types/src/gas.rs @@ -29,14 +29,6 @@ impl Gas { self.0 } - /// Returns the cost to be charged. - pub fn cost(&self, is_system: bool) -> Self { - if is_system { - return Gas::new(U512::zero()); - } - *self - } - /// Converts the given `motes` to `Gas` by dividing them by `conv_rate`. /// /// Returns `None` if `conv_rate == 0`. diff --git a/types/src/key.rs b/types/src/key.rs index 215e5bf7db..3c1e675920 100644 --- a/types/src/key.rs +++ b/types/src/key.rs @@ -577,7 +577,8 @@ impl Key { format!("{}", named_key) } Key::BalanceHold(balance_hold_addr) => { - format!("{}{}", BALANCE_HOLD_PREFIX, balance_hold_addr) + let tail = BalanceHoldAddr::to_formatted_string(&balance_hold_addr); + format!("{}{}", BALANCE_HOLD_PREFIX, tail) } } } @@ -633,6 +634,12 @@ impl Key { return Ok(Key::EraInfo(era_id)); } + // note: BALANCE_HOLD must come before BALANCE due to overlapping head (balance-) + if let Some(hex) = input.strip_prefix(BALANCE_HOLD_PREFIX) { + let balance_hold_addr = BalanceHoldAddr::from_formatted_string(hex)?; + return Ok(Key::BalanceHold(balance_hold_addr)); + } + if let Some(hex) = input.strip_prefix(BALANCE_PREFIX) { let addr = checksummed_hex::decode(hex) .map_err(|error| FromStrError::Balance(error.to_string()))?; @@ -1021,7 +1028,7 @@ impl Key { } } - /// Returns if they inner Key is for a system contract entity. + /// Returns if the inner address is for a system contract entity. pub fn is_system_key(&self) -> bool { if let Self::AddressableEntity(entity_addr) = self { return match entity_addr.tag() { @@ -1075,12 +1082,7 @@ impl Key { // the system entities and all packages are public info true } - Key::AddressableEntity(addr_entity_addr) => { - // smart contracts and system contracts are public - // and an entity can read its own entity record - addr_entity_addr.tag() != EntityKindTag::Account || entity_addr == addr_entity_addr - } - Key::Account(account_hash) | Key::Unbond(account_hash) => { + Key::Unbond(account_hash) => { // and an account holder can read their own account record entity_addr.tag() == EntityKindTag::Account && entity_addr.value() == account_hash.value() @@ -1089,6 +1091,14 @@ impl Key { // an entity can read its own named keys &named_key_addr.entity_addr() == entity_addr } + Key::ByteCode(_) + | Key::Account(_) + | Key::Hash(_) + | Key::AddressableEntity(_) + | Key::Balance(_) + | Key::BalanceHold(_) + | Key::Dictionary(_) + | Key::Message(_) => true, _ => false, }; if !ret { diff --git a/types/src/lib.rs b/types/src/lib.rs index f90844e85b..a23356131c 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -119,7 +119,8 @@ pub use chainspec::{ HostFunction, HostFunctionCost, HostFunctionCosts, LegacyRequiredFinality, MessageLimits, MintCosts, NetworkConfig, NextUpgrade, OpcodeCosts, ProtocolConfig, ProtocolUpgradeConfig, RefundHandling, StandardPaymentCosts, StorageCosts, SystemConfig, TransactionConfig, - TransactionV1Config, ValidatorConfig, WasmConfig, DEFAULT_HOST_FUNCTION_NEW_DICTIONARY, + TransactionV1Config, ValidatorConfig, WasmConfig, DEFAULT_BALANCE_HOLD_INTERVAL, + DEFAULT_FEE_HANDLING, DEFAULT_HOST_FUNCTION_NEW_DICTIONARY, DEFAULT_REFUND_HANDLING, }; #[cfg(any(all(feature = "std", feature = "testing"), test))] pub use chainspec::{ @@ -132,10 +133,9 @@ pub use chainspec::{ DEFAULT_CONTROL_FLOW_IF_OPCODE, DEFAULT_CONTROL_FLOW_LOOP_OPCODE, DEFAULT_CONTROL_FLOW_RETURN_OPCODE, DEFAULT_CONTROL_FLOW_SELECT_OPCODE, DEFAULT_CONVERSION_COST, DEFAULT_CURRENT_MEMORY_COST, DEFAULT_DELEGATE_COST, DEFAULT_DIV_COST, - DEFAULT_FEE_HANDLING, DEFAULT_GLOBAL_COST, DEFAULT_GROW_MEMORY_COST, - DEFAULT_INTEGER_COMPARISON_COST, DEFAULT_LOAD_COST, DEFAULT_LOCAL_COST, - DEFAULT_MAX_PAYMENT_MOTES, DEFAULT_MAX_STACK_HEIGHT, DEFAULT_MIN_TRANSFER_MOTES, - DEFAULT_MUL_COST, DEFAULT_NEW_DICTIONARY_COST, DEFAULT_NOP_COST, DEFAULT_REFUND_HANDLING, + DEFAULT_GLOBAL_COST, DEFAULT_GROW_MEMORY_COST, DEFAULT_INTEGER_COMPARISON_COST, + DEFAULT_LOAD_COST, DEFAULT_LOCAL_COST, DEFAULT_MAX_PAYMENT_MOTES, DEFAULT_MAX_STACK_HEIGHT, + DEFAULT_MIN_TRANSFER_MOTES, DEFAULT_MUL_COST, DEFAULT_NEW_DICTIONARY_COST, DEFAULT_NOP_COST, DEFAULT_STORE_COST, DEFAULT_TRANSFER_COST, DEFAULT_UNREACHABLE_COST, DEFAULT_WASMLESS_TRANSFER_COST, DEFAULT_WASM_MAX_MEMORY, }; diff --git a/types/src/system/auction/error.rs b/types/src/system/auction/error.rs index dc3f3d88fa..1fb8bff3e0 100644 --- a/types/src/system/auction/error.rs +++ b/types/src/system/auction/error.rs @@ -333,6 +333,12 @@ pub enum Error { /// assert_eq!(50, Error::ForgedReference as u8); /// ``` ForgedReference = 50, + /// Unable to find purse. + /// ``` + /// # use casper_types::system::auction::Error; + /// assert_eq!(51, Error::MissingPurse as u8); + /// ``` + MissingPurse = 51, } impl Display for Error { @@ -389,6 +395,7 @@ impl Display for Error { Error::GetAccumulationPurse => formatter.write_str("Get accumulation purse error"), Error::TransferToAdministrator => formatter.write_str("Transfer to administrator error"), Error::ForgedReference => formatter.write_str("Forged reference"), + Error::MissingPurse => formatter.write_str("Missing purse"), } } } @@ -471,6 +478,7 @@ impl TryFrom for Error { d if d == Error::GetAccumulationPurse as u8 => Ok(Error::GetAccumulationPurse), d if d == Error::TransferToAdministrator as u8 => Ok(Error::TransferToAdministrator), d if d == Error::ForgedReference as u8 => Ok(Error::ForgedReference), + d if d == Error::MissingPurse as u8 => Ok(Error::MissingPurse), _ => Err(TryFromU8ForError(())), } } @@ -515,7 +523,7 @@ pub enum PurseLookupError { impl From for Error { fn from(error: PurseLookupError) -> Self { match error { - PurseLookupError::KeyNotFound => Error::MissingKey, + PurseLookupError::KeyNotFound => Error::MissingPurse, PurseLookupError::KeyUnexpectedType => Error::InvalidKeyVariant, } } diff --git a/types/src/system/mint/balance_hold.rs b/types/src/system/mint/balance_hold.rs index 3e812da239..4902867e5b 100644 --- a/types/src/system/mint/balance_hold.rs +++ b/types/src/system/mint/balance_hold.rs @@ -1,8 +1,13 @@ -use core::fmt::{Debug, Display, Formatter}; +use alloc::{ + format, + string::{String, ToString}, + vec::Vec, +}; -use alloc::vec::Vec; -#[cfg(any(feature = "std", test))] -use std::convert::TryFrom; +use core::{ + convert::TryFrom, + fmt::{Debug, Display, Formatter}, +}; #[cfg(feature = "datasize")] use datasize::DataSize; @@ -17,12 +22,12 @@ use serde::{Deserialize, Serialize}; use crate::{ bytesrepr, bytesrepr::{FromBytes, ToBytes}, + checksummed_hex, + key::FromStrError, system::auction::Error, - BlockTime, Key, KeyTag, Timestamp, URefAddr, UREF_ADDR_LENGTH, + BlockTime, Key, KeyTag, Timestamp, URefAddr, BLOCKTIME_SERIALIZED_LENGTH, UREF_ADDR_LENGTH, }; -const BALANCE_HOLD_ADDR_TAG_LENGTH: u8 = 1; - const GAS_TAG: u8 = 0; /// Serialization tag for BalanceHold variants. @@ -87,11 +92,11 @@ pub enum BalanceHoldAddr { impl BalanceHoldAddr { /// The length in bytes of a [`BalanceHoldAddr`] for a gas hold address. - pub const GAS_HOLD_ADDR_LENGTH: usize = - UREF_ADDR_LENGTH + BalanceHoldAddrTag::BALANCE_HOLD_ADDR_TAG_LENGTH; + pub const GAS_HOLD_ADDR_LENGTH: usize = UREF_ADDR_LENGTH + + BalanceHoldAddrTag::BALANCE_HOLD_ADDR_TAG_LENGTH + + BLOCKTIME_SERIALIZED_LENGTH; /// Creates a Gas variant instance of [`BalanceHoldAddr`]. - #[cfg(any(feature = "testing", test))] pub(crate) const fn new_gas(purse_addr: URefAddr, block_time: BlockTime) -> BalanceHoldAddr { BalanceHoldAddr::Gas { purse_addr, @@ -106,7 +111,7 @@ impl BalanceHoldAddr { purse_addr, block_time, } => { - BALANCE_HOLD_ADDR_TAG_LENGTH as usize + BalanceHoldAddrTag::BALANCE_HOLD_ADDR_TAG_LENGTH + ToBytes::serialized_length(purse_addr) + ToBytes::serialized_length(block_time) } @@ -143,6 +148,68 @@ impl BalanceHoldAddr { ret.extend(purse_addr_bytes); Ok(ret) } + + /// To formatted string. + pub fn to_formatted_string(&self) -> String { + match self { + BalanceHoldAddr::Gas { + purse_addr, + block_time, + } => { + format!( + "{}{}{}", + // also, put the tag in readable form + base16::encode_lower(&GAS_TAG.to_le_bytes()), + base16::encode_lower(purse_addr), + // TODO: we could conceivably stringify the u64 millis instead of bytes-ing + // which would allow visual / human determination of the timestamp + // but on the other hand, how many humans casually do from UNIX EPOCH + // time calculation with their eyeballs? Something to discuss prior to + // shipping. + // BlockTime.value as string instead + base16::encode_lower(&block_time.value().to_le_bytes()) + ) + } + } + } + + /// From formatted string. + pub fn from_formatted_string(hex: &str) -> Result { + let bytes = checksummed_hex::decode(hex) + .map_err(|error| FromStrError::BalanceHold(error.to_string()))?; + if bytes.is_empty() { + return Err(FromStrError::BalanceHold( + "bytes should not be 0 len".to_string(), + )); + } + let tag_bytes = <[u8; BalanceHoldAddrTag::BALANCE_HOLD_ADDR_TAG_LENGTH]>::try_from( + bytes[0..BalanceHoldAddrTag::BALANCE_HOLD_ADDR_TAG_LENGTH].as_ref(), + ) + .map_err(|err| FromStrError::BalanceHold(err.to_string()))?; + let tag = ::from_le_bytes(tag_bytes); + let tag = BalanceHoldAddrTag::try_from_u8(tag).ok_or_else(|| { + FromStrError::BalanceHold("failed to parse balance hold addr tag".to_string()) + })?; + + let uref_addr = URefAddr::try_from(bytes[1..=UREF_ADDR_LENGTH].as_ref()) + .map_err(|err| FromStrError::BalanceHold(err.to_string()))?; + + // if more tags are added, extend the below logic to handle every case. + // it is possible that it will turn out that all further tags include blocktime + // in which case it can be pulled up out of the tag guard condition. + // however, im erring on the side of future tolerance and guarding it for now. + if tag == BalanceHoldAddrTag::Gas { + let block_time_bytes = + <[u8; BLOCKTIME_SERIALIZED_LENGTH]>::try_from(bytes[33..].as_ref()) + .map_err(|err| FromStrError::BalanceHold(err.to_string()))?; + + let block_time_millis = ::from_le_bytes(block_time_bytes); + let block_time = BlockTime::new(block_time_millis); + Ok(BalanceHoldAddr::new_gas(uref_addr, block_time)) + } else { + Err(FromStrError::BalanceHold("invalid tag".to_string())) + } + } } impl ToBytes for BalanceHoldAddr { diff --git a/types/src/system/mint/constants.rs b/types/src/system/mint/constants.rs index b5d73f7fab..cffada448e 100644 --- a/types/src/system/mint/constants.rs +++ b/types/src/system/mint/constants.rs @@ -4,8 +4,6 @@ pub const ARG_PURSE: &str = "purse"; pub const ARG_AMOUNT: &str = "amount"; /// Named constant for `id`. pub const ARG_ID: &str = "id"; -/// Named constant for `holds_epoch`. -pub const ARG_HOLDS_EPOCH: &str = "holds_epoch"; /// Named constant for `to`. pub const ARG_TO: &str = "to"; /// Named constant for `source`. diff --git a/utils/global-state-update-gen/src/admins.rs b/utils/global-state-update-gen/src/admins.rs index 23b5e0c4e0..85f95244ab 100644 --- a/utils/global-state-update-gen/src/admins.rs +++ b/utils/global-state-update-gen/src/admins.rs @@ -1,4 +1,4 @@ -use casper_engine_test_support::LmdbWasmTestBuilder; +use casper_engine_test_support::{LmdbWasmTestBuilder, DEFAULT_PROTOCOL_VERSION}; use casper_types::{ account::Account, addressable_entity::NamedKeys, bytesrepr::ToBytes, system::mint, AccessRights, AsymmetricType, CLTyped, CLValue, Key, PublicKey, StoredValue, URef, U512, @@ -28,8 +28,8 @@ pub(crate) fn generate_admins(matches: &ArgMatches<'_>) { let test_builder = LmdbWasmTestBuilder::open_raw(data_dir, Default::default(), post_state_hash); let admin_values = matches.values_of("admin").expect("at least one argument"); - - let mut total_supply = test_builder.total_supply(Some(post_state_hash)); + let protocol_version = *DEFAULT_PROTOCOL_VERSION; + let mut total_supply = test_builder.total_supply(Some(post_state_hash), protocol_version); let total_supply_before = total_supply; for value in admin_values { diff --git a/utils/validation/src/generators.rs b/utils/validation/src/generators.rs index 0fc5971332..def5ef9304 100644 --- a/utils/validation/src/generators.rs +++ b/utils/validation/src/generators.rs @@ -12,12 +12,15 @@ use casper_types::{ ActionThresholds, AddressableEntity, AssociatedKeys, EntityKind, MessageTopics, NamedKeys, }, package::{EntityVersions, Groups, Package, PackageStatus}, - system::auction::{ - Bid, BidAddr, BidKind, Delegator, EraInfo, SeigniorageAllocation, UnbondingPurse, - ValidatorBid, WithdrawPurse, + system::{ + auction::{ + Bid, BidAddr, BidKind, Delegator, EraInfo, SeigniorageAllocation, UnbondingPurse, + ValidatorBid, WithdrawPurse, + }, + mint::BalanceHoldAddr, }, - AccessRights, AddressableEntityHash, ByteCode, ByteCodeHash, ByteCodeKind, CLType, CLTyped, - CLValue, DeployHash, DeployInfo, EntityVersionKey, EntryPoint, EntryPointAccess, + AccessRights, AddressableEntityHash, BlockTime, ByteCode, ByteCodeHash, ByteCodeKind, CLType, + CLTyped, CLValue, DeployHash, DeployInfo, EntityVersionKey, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, EraId, Group, Key, PackageHash, Parameter, ProtocolVersion, PublicKey, SecretKey, StoredValue, Transfer, TransferAddr, URef, U512, }; @@ -206,6 +209,10 @@ pub fn make_abi_test_fixtures() -> Result { const DEPLOY_INFO_KEY: Key = Key::DeployInfo(DeployHash::from_raw([42; 32])); const ERA_INFO_KEY: Key = Key::EraInfo(EraId::new(42)); const BALANCE_KEY: Key = Key::Balance([42; 32]); + const BALANCE_HOLD_KEY: Key = Key::BalanceHold(BalanceHoldAddr::Gas { + purse_addr: [42; 32], + block_time: BlockTime::new(0), + }); const WITHDRAW_KEY: Key = Key::Withdraw(AccountHash::new([42; 32])); const DICTIONARY_KEY: Key = Key::Dictionary([42; 32]); const SYSTEM_CONTRACT_REGISTRY_KEY: Key = Key::SystemEntityRegistry; @@ -243,6 +250,10 @@ pub fn make_abi_test_fixtures() -> Result { "Balance".to_string(), ABITestCase::from_inputs(vec![BALANCE_KEY.into()])?, ); + keys.insert( + "BalanceHold".to_string(), + ABITestCase::from_inputs(vec![BALANCE_HOLD_KEY.into()])?, + ); keys.insert( "WriteBid".to_string(), ABITestCase::from_inputs(vec![original_bid_key.into()])?, diff --git a/utils/validation/tests/fixtures/ABI/key.json b/utils/validation/tests/fixtures/ABI/key.json index 6315c07f33..a2d9662210 100644 --- a/utils/validation/tests/fixtures/ABI/key.json +++ b/utils/validation/tests/fixtures/ABI/key.json @@ -17,6 +17,15 @@ ], "output": "062a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a" }, + "BalanceHold": { + "input": [ + { + "type": "Key", + "value": "balance-hold-002a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0000000000000000" + } + ], + "output": "15002a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0000000000000000" + }, "ChainspecRegistry": { "input": [ { diff --git a/utils/validation/tests/fixtures/ABI/stored_value.json b/utils/validation/tests/fixtures/ABI/stored_value.json index 3e50ac4403..f382f4a279 100644 --- a/utils/validation/tests/fixtures/ABI/stored_value.json +++ b/utils/validation/tests/fixtures/ABI/stored_value.json @@ -39,8 +39,11 @@ "type": "StoredValue", "value": { "AddressableEntity": { + "protocol_version": "1.0.0", + "entity_kind": "SmartContract", "package_hash": "contract-package-6464646464646464646464646464646464646464646464646464646464646464", "byte_code_hash": "byte-code-6565656565656565656565656565656565656565656565656565656565656565", + "main_purse": "uref-0000000000000000000000000000000000000000000000000000000000000000-000", "entry_points": [ { "name": "public_entry_point_func", @@ -58,20 +61,17 @@ ], "ret": "Unit", "access": "Public", - "entry_point_type": "AddressableEntity" + "entry_point_type": "Called" } } ], - "protocol_version": "1.0.0", - "main_purse": "uref-0000000000000000000000000000000000000000000000000000000000000000-000", "associated_keys": [], "action_thresholds": { "deployment": 1, "upgrade_management": 1, "key_management": 1 }, - "message_topics": [], - "entity_kind": "SmartContract" + "message_topics": [] } } } From 8c72a76526755d6422c616a0308c6c16f2596c85 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Thu, 14 Mar 2024 00:04:32 -0700 Subject: [PATCH 17/70] merge conflicts --- .../tests/src/test/contract_messages.rs | 2 +- .../tests/src/test/explorer/faucet.rs | 8 +- .../components/contract_runtime/operations.rs | 5 +- resources/test/sse_data_schema.json | 2 +- types/src/chainspec/protocol_config.rs | 2 +- types/src/key.rs | 161 +----------------- types/src/lib.rs | 11 +- 7 files changed, 23 insertions(+), 168 deletions(-) diff --git a/execution_engine_testing/tests/src/test/contract_messages.rs b/execution_engine_testing/tests/src/test/contract_messages.rs index d3ae6f89e0..bf96828ae3 100644 --- a/execution_engine_testing/tests/src/test/contract_messages.rs +++ b/execution_engine_testing/tests/src/test/contract_messages.rs @@ -937,7 +937,7 @@ fn should_produce_per_block_message_ordering() { let builder = RefCell::new(LmdbWasmTestBuilder::default()); builder .borrow_mut() - .run_genesis(PRODUCTION_RUN_GENESIS_REQUEST.clone()); + .run_genesis(LOCAL_GENESIS_REQUEST.clone()); let emitter_contract_hash = install_messages_emitter_contract(&builder, true); let query_view = ContractQueryView::new(&builder, emitter_contract_hash); diff --git a/execution_engine_testing/tests/src/test/explorer/faucet.rs b/execution_engine_testing/tests/src/test/explorer/faucet.rs index a11848be4a..5fe896bbe8 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet.rs @@ -935,10 +935,10 @@ fn faucet_costs() { // This test will fail if execution costs vary. The expected costs should not be updated // without understanding why the cost has changed. If the costs do change, it should be // reflected in the "Costs by Entry Point" section of the faucet crate's README.md. - const EXPECTED_FAUCET_INSTALL_COST: u64 = 92_469_652_420; - const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_731_720; - const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_304_280; - const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_809_400; + const EXPECTED_FAUCET_INSTALL_COST: u64 = 92_506_829_880; + const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_742_240; + const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_318_380; + const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_830_980; let installer_account = AccountHash::new([1u8; 32]); let user_account: AccountHash = AccountHash::new([2u8; 32]); diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 90ad5ca443..58dd299bc2 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -122,7 +122,9 @@ pub fn execute_finalized_block( // FeeHandling::Accumulate => { // // this is a variation on PayToProposer that was added for // // for some private networks...the fees are all accumulated - // // and distributed to administrative accounts. + // // and distributed to administrative accounts as part of fee + // // distribution. So, we just send the payment to the accumulator + // // purse and move on. // } // FeeHandling::Burn => { // // this is a new variation that is not currently supported. @@ -220,7 +222,6 @@ pub fn execute_finalized_block( auction_method, ); - //NOTE: native mint interactions auto-commit let bidding_result = scratch_state.bidding(bidding_req); trace!(?transaction_hash, ?bidding_result, "native auction result"); match bidding_result { diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index 21d3cf3231..5c28a0544c 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -4720,7 +4720,7 @@ "type": "object", "required": [ "block_index", - "entity_addr", + "entity_hash", "message", "topic_index", "topic_name", diff --git a/types/src/chainspec/protocol_config.rs b/types/src/chainspec/protocol_config.rs index a7a56493d3..5d4aecf719 100644 --- a/types/src/chainspec/protocol_config.rs +++ b/types/src/chainspec/protocol_config.rs @@ -15,7 +15,7 @@ use crate::{ use crate::{ActivationPoint, GlobalStateUpdate}; /// Configuration values associated with the protocol. -#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug, Default)] +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] #[cfg_attr(feature = "datasize", derive(DataSize))] pub struct ProtocolConfig { /// Protocol version. diff --git a/types/src/key.rs b/types/src/key.rs index 7c08f80c16..52c2d4146c 100644 --- a/types/src/key.rs +++ b/types/src/key.rs @@ -127,141 +127,6 @@ pub type PackageAddr = [u8; ADDR_LENGTH]; /// An alias for [`Key`]s dictionary variant. pub type DictionaryAddr = [u8; KEY_DICTIONARY_LENGTH]; -/// Errors produced when converting a `String` into a `Key`. -#[derive(Debug)] -#[non_exhaustive] -pub enum FromStrError { - /// Account parse error. - Account(addressable_entity::FromStrError), - /// Hash parse error. - Hash(String), - /// URef parse error. - URef(uref::FromStrError), - /// Transfer parse error. - Transfer(TransferFromStrError), - /// DeployInfo parse error. - DeployInfo(String), - /// EraInfo parse error. - EraInfo(String), - /// Balance parse error. - Balance(String), - /// Bid parse error. - Bid(String), - /// Withdraw parse error. - Withdraw(String), - /// Dictionary parse error. - Dictionary(String), - /// System contract registry parse error. - SystemContractRegistry(String), - /// Era summary parse error. - EraSummary(String), - /// Unbond parse error. - Unbond(String), - /// Chainspec registry error. - ChainspecRegistry(String), - /// Checksum registry error. - ChecksumRegistry(String), - /// Bid parse error. - BidAddr(String), - /// Package parse error. - Package(String), - /// Entity parse error. - AddressableEntity(String), - /// Byte code parse error. - ByteCode(String), - /// Message parse error. - Message(contract_messages::FromStrError), - /// Named key parse error. - NamedKey(String), - /// Balance hold parse error. - BalanceHold(String), - /// Unknown prefix. - UnknownPrefix, -} - -impl From for FromStrError { - fn from(error: addressable_entity::FromStrError) -> Self { - FromStrError::Account(error) - } -} - -impl From for FromStrError { - fn from(error: TransferFromStrError) -> Self { - FromStrError::Transfer(error) - } -} - -impl From for FromStrError { - fn from(error: uref::FromStrError) -> Self { - FromStrError::URef(error) - } -} - -impl From for FromStrError { - fn from(error: contract_messages::FromStrError) -> Self { - FromStrError::Message(error) - } -} - -impl Display for FromStrError { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match self { - FromStrError::Account(error) => write!(f, "account-key from string error: {}", error), - FromStrError::Hash(error) => write!(f, "hash-key from string error: {}", error), - FromStrError::URef(error) => write!(f, "uref-key from string error: {}", error), - FromStrError::Transfer(error) => write!(f, "transfer-key from string error: {}", error), - FromStrError::DeployInfo(error) => { - write!(f, "deploy-info-key from string error: {}", error) - } - FromStrError::EraInfo(error) => write!(f, "era-info-key from string error: {}", error), - FromStrError::Balance(error) => write!(f, "balance-key from string error: {}", error), - FromStrError::Bid(error) => write!(f, "bid-key from string error: {}", error), - FromStrError::Withdraw(error) => write!(f, "withdraw-key from string error: {}", error), - FromStrError::Dictionary(error) => { - write!(f, "dictionary-key from string error: {}", error) - } - FromStrError::SystemContractRegistry(error) => { - write!( - f, - "system-contract-registry-key from string error: {}", - error - ) - } - FromStrError::EraSummary(error) => { - write!(f, "era-summary-key from string error: {}", error) - } - FromStrError::Unbond(error) => { - write!(f, "unbond-key from string error: {}", error) - } - FromStrError::ChainspecRegistry(error) => { - write!(f, "chainspec-registry-key from string error: {}", error) - } - FromStrError::ChecksumRegistry(error) => { - write!(f, "checksum-registry-key from string error: {}", error) - } - FromStrError::BidAddr(error) => write!(f, "bid-addr-key from string error: {}", error), - FromStrError::Package(error) => write!(f, "package-key from string error: {}", error), - FromStrError::AddressableEntity(error) => { - write!(f, "addressable-entity-key from string error: {}", error) - } - FromStrError::ByteCode(error) => { - write!(f, "byte-code-key from string error: {}", error) - } - FromStrError::Message(error) => { - write!(f, "message-key from string error: {}", error) - } - FromStrError::NamedKey(error) => { - write!(f, "named-key from string error: {}", error) - } - FromStrError::BalanceHold(error) => { - write!(f, "balance-hold from string error: {}", error) - } - - FromStrError::UnknownPrefix => write!(f, "unknown prefix for key"), - } - } -} - #[allow(missing_docs)] #[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] #[repr(u8)] @@ -525,6 +390,8 @@ pub enum FromStrError { NamedKey(String), /// BlockMessageCount key parse error. BlockMessageCount(String), + /// Balance hold parse error. + BalanceHold(String), /// Unknown prefix. UnknownPrefix, } @@ -606,6 +473,9 @@ impl Display for FromStrError { FromStrError::BlockMessageCount(error) => { write!(f, "block-message-count-key form string error: {}", error) } + FromStrError::BalanceHold(error) => { + write!(f, "balance-hold from string error: {}", error) + } FromStrError::UnknownPrefix => write!(f, "unknown prefix for key"), } } @@ -1278,7 +1148,8 @@ impl Key { | Key::Balance(_) | Key::BalanceHold(_) | Key::Dictionary(_) - | Key::Message(_) => true, + | Key::Message(_) + | Key::BlockMessageCount => true, _ => false, }; if !ret { @@ -1341,24 +1212,6 @@ impl Key { } } -#[cfg(feature = "json-schema")] -impl JsonSchema for Key { - fn schema_name() -> String { - String::from("Key") - } - - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema = gen.subschema_for::(); - let mut schema_object = schema.into_object(); - schema_object.metadata().description = Some( - "The key as a formatted string, under which data (e.g. `CLValue`s, smart contracts, \ - user accounts) are stored in global state." - .to_string(), - ); - schema_object.into() - } -} - impl Display for Key { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { diff --git a/types/src/lib.rs b/types/src/lib.rs index 1dca6b7250..9c2dae93c8 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -134,11 +134,12 @@ pub use chainspec::{ DEFAULT_CONTROL_FLOW_IF_OPCODE, DEFAULT_CONTROL_FLOW_LOOP_OPCODE, DEFAULT_CONTROL_FLOW_RETURN_OPCODE, DEFAULT_CONTROL_FLOW_SELECT_OPCODE, DEFAULT_CONVERSION_COST, DEFAULT_CURRENT_MEMORY_COST, DEFAULT_DELEGATE_COST, DEFAULT_DIV_COST, - DEFAULT_GLOBAL_COST, DEFAULT_GROW_MEMORY_COST,DEFAULT_INSTALL_UPGRADE_GAS_LIMIT, DEFAULT_INTEGER_COMPARISON_COST, - DEFAULT_LOAD_COST, DEFAULT_LOCAL_COST, DEFAULT_MAX_PAYMENT_MOTES, DEFAULT_MAX_STACK_HEIGHT, - DEFAULT_MIN_TRANSFER_MOTES, DEFAULT_MUL_COST, DEFAULT_NEW_DICTIONARY_COST, DEFAULT_NOP_COST, - DEFAULT_REFUND_HANDLING, DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT, DEFAULT_STORE_COST, - DEFAULT_TRANSFER_COST, DEFAULT_UNREACHABLE_COST, DEFAULT_WASM_MAX_MEMORY, + DEFAULT_GLOBAL_COST, DEFAULT_GROW_MEMORY_COST, DEFAULT_INSTALL_UPGRADE_GAS_LIMIT, + DEFAULT_INTEGER_COMPARISON_COST, DEFAULT_LOAD_COST, DEFAULT_LOCAL_COST, + DEFAULT_MAX_PAYMENT_MOTES, DEFAULT_MAX_STACK_HEIGHT, DEFAULT_MIN_TRANSFER_MOTES, + DEFAULT_MUL_COST, DEFAULT_NEW_DICTIONARY_COST, DEFAULT_NOP_COST, + DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT, DEFAULT_STORE_COST, DEFAULT_TRANSFER_COST, + DEFAULT_UNREACHABLE_COST, DEFAULT_WASM_MAX_MEMORY, }; pub use cl_type::{named_key_type, CLType, CLTyped}; From 67ad52e58a828b70f73b317e11040008bc918216 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Thu, 14 Mar 2024 20:13:58 -0700 Subject: [PATCH 18/70] nofee wireup --- execution_engine/src/engine_state/mod.rs | 2 +- .../private_chain/burn_fees_and_refund.rs | 2 +- node/src/components/block_validator.rs | 11 +- node/src/components/block_validator/state.rs | 9 +- .../components/contract_runtime/operations.rs | 134 +++++++--- .../fetcher_impls/transaction_fetcher.rs | 4 +- node/src/components/transaction_acceptor.rs | 20 +- .../components/transaction_acceptor/error.rs | 17 +- .../components/transaction_acceptor/tests.rs | 118 ++++----- node/src/components/transaction_buffer.rs | 14 +- node/src/types.rs | 2 +- node/src/types/transaction.rs | 2 +- .../types/transaction/deploy/legacy_deploy.rs | 4 +- .../transaction/transaction_footprint.rs | 136 +++------- resources/test/sse_data_schema.json | 2 +- storage/src/data_access_layer/balance.rs | 13 +- storage/src/data_access_layer/balance_hold.rs | 79 +++++- storage/src/global_state/state/mod.rs | 20 +- storage/src/system/handle_payment/internal.rs | 4 +- storage/src/system/protocol_upgrade.rs | 2 +- types/src/chainspec.rs | 1 + types/src/chainspec/fee_handling.rs | 6 +- types/src/chainspec/genesis_config.rs | 2 + types/src/execution/transform_kind.rs | 2 +- types/src/lib.rs | 22 +- types/src/transaction.rs | 170 +++++++----- types/src/transaction/deploy.rs | 162 ++++++------ types/src/transaction/deploy/deploy_header.rs | 10 +- types/src/transaction/deploy/error.rs | 82 +++--- types/src/transaction/error.rs | 54 ++++ types/src/transaction/transaction_v1.rs | 242 ++++++++++-------- .../transaction/transaction_v1/errors_v1.rs | 94 ++++--- .../transaction_v1/transaction_v1_body.rs | 42 +-- .../transaction_v1_body/arg_handling.rs | 81 +++--- .../transaction_v1/transaction_v1_header.rs | 26 +- utils/validation/tests/fixtures/ABI/key.json | 2 +- 36 files changed, 914 insertions(+), 679 deletions(-) create mode 100644 types/src/transaction/error.rs diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index a7911e4f9a..b1a6fccc6a 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -376,7 +376,7 @@ impl ExecutionEngineV1 { FeeHandling::PayToProposer => { FeesPurseHandling::ToProposer(proposer.to_account_hash()) } - FeeHandling::None => FeesPurseHandling::None(payment_purse_uref), + FeeHandling::NoFee => FeesPurseHandling::None(payment_purse_uref), FeeHandling::Accumulate => FeesPurseHandling::Accumulate, FeeHandling::Burn => FeesPurseHandling::Burn, }; diff --git a/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs b/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs index 402cc863bd..cab6632749 100644 --- a/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs +++ b/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs @@ -153,7 +153,7 @@ fn test_burning_fees( let total_supply_after = builder.total_supply(None, protocol_version); match fee_handling { - FeeHandling::PayToProposer | FeeHandling::Accumulate | FeeHandling::None => { + FeeHandling::PayToProposer | FeeHandling::Accumulate | FeeHandling::NoFee => { assert_eq!(total_supply_before, total_supply_after); } FeeHandling::Burn => { diff --git a/node/src/components/block_validator.rs b/node/src/components/block_validator.rs index 3ad7b88b53..a511132576 100644 --- a/node/src/components/block_validator.rs +++ b/node/src/components/block_validator.rs @@ -39,7 +39,7 @@ use crate::{ EffectBuilder, EffectExt, Effects, Responder, }, fatal, - types::{BlockWithMetadata, NodeId, TransactionExt, ValidatorMatrix}, + types::{BlockWithMetadata, NodeId, TransactionFootprint, ValidatorMatrix}, NodeRng, }; pub use config::Config; @@ -553,11 +553,12 @@ impl BlockValidator { .flat_map(|state| state.try_mark_invalid(&transaction_hash)); return respond(false, responders); } - let transaction_footprint = match item.footprint(&self.chainspec) { - Some(footprint) => footprint, - None => { + let transaction_footprint = match TransactionFootprint::new(&self.chainspec, &item) + { + Ok(footprint) => footprint, + Err(invalid_transaction_error) => { warn!( - %transaction_hash, + %transaction_hash, ?invalid_transaction_error, "could not convert transaction", ); // Hard failure - change state to Invalid. diff --git a/node/src/components/block_validator/state.rs b/node/src/components/block_validator/state.rs index d1bb5c8f40..ddd275ec2d 100644 --- a/node/src/components/block_validator/state.rs +++ b/node/src/components/block_validator/state.rs @@ -550,7 +550,7 @@ mod tests { }; use super::{super::tests::*, *}; - use crate::{types::TransactionExt, utils::Loadable}; + use crate::utils::Loadable; struct Fixture<'a> { rng: &'a mut TestRng, @@ -574,8 +574,7 @@ mod tests { .map(|transaction| { ( transaction.hash(), - transaction - .footprint(&self.chainspec) + TransactionFootprint::new(&self.chainspec, transaction) .expect("must create footprint"), ) }) @@ -1197,7 +1196,7 @@ mod tests { Transaction::V1(v1) => TransactionHash::V1(*v1.hash()), }; let chainspec = Chainspec::default(); - let footprint = transaction.footprint(&chainspec).unwrap(); + let footprint = TransactionFootprint::new(&chainspec, &transaction).unwrap(); // Ensure trying to add it doesn't change the state. let responders = state.try_add_transaction_footprint(&transaction_hash, &footprint); @@ -1257,7 +1256,7 @@ mod tests { // The invalid transaction should cause the state to go to `Invalid` and the responders to // be returned. let chainspec = Chainspec::default(); - let footprint = invalid_transaction.footprint(&chainspec).unwrap(); + let footprint = TransactionFootprint::new(&chainspec, &invalid_transaction).unwrap(); let responders = state.try_add_transaction_footprint(&transaction_hash, &footprint); assert_eq!(responders.len(), 1); assert!(matches!(state, BlockValidationState::Invalid(_))); diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 58dd299bc2..3a664a48da 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -11,10 +11,10 @@ use casper_execution_engine::engine_state::{ use casper_storage::{ block_store::types::ApprovalsHashes, data_access_layer::{ - AuctionMethod, BiddingRequest, BiddingResult, BlockRewardsRequest, BlockRewardsResult, - DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, EvictItem, FeeRequest, - FeeResult, FlushRequest, PruneRequest, PruneResult, StepRequest, StepResult, - TransferRequest, TransferResult, + AuctionMethod, BalanceHoldRequest, BiddingRequest, BiddingResult, BlockRewardsRequest, + BlockRewardsResult, DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, EvictItem, + FeeRequest, FeeResult, FlushRequest, InsufficientBalanceHandling, PruneRequest, + PruneResult, StepRequest, StepResult, TransferRequest, TransferResult, }, global_state::{ error::Error as GlobalStateError, @@ -30,8 +30,9 @@ use casper_types::{ bytesrepr::{self, ToBytes, U32_SERIALIZED_LENGTH}, contract_messages::Messages, execution::{Effects, ExecutionResult, ExecutionResultV2, TransformKindV2, TransformV2}, - ApprovalsHash, BlockV2, CLValue, Chainspec, ChecksumRegistry, DeployHash, Digest, EraEndV2, - EraId, Key, ProtocolVersion, PublicKey, Transaction, U512, + system::mint::BalanceHoldAddrTag, + ApprovalsHash, BlockTime, BlockV2, CLValue, Chainspec, ChecksumRegistry, DeployHash, Digest, + EraEndV2, EraId, FeeHandling, GasLimited, Key, ProtocolVersion, PublicKey, Transaction, U512, }; use crate::{ @@ -96,42 +97,103 @@ pub fn execute_finalized_block( let scratch_state = data_access_layer.get_scratch_global_state(); let mut effects = Effects::new(); + let system_costs = chainspec.system_costs_config; + let insufficient_balance_handling = InsufficientBalanceHandling::HoldRemaining; + let gas_price = Some(1); // < --TODO: this is where Karan's calculated gas price needs to be used + for transaction in executable_block.transactions { let transaction_hash = transaction.hash(); let runtime_args = transaction.session_args().clone(); let entry_point = transaction.entry_point(); + // NOTE: this is the actual adjusted cost (gas limit * gas price) + // NOT the allowed computation limit (gas limit) + let cost = match transaction.gas_limit(&system_costs, gas_price) { + Ok(gas) => gas.value(), + Err(ite) => { + execution_artifacts.push(ExecutionArtifact::new( + transaction_hash, + transaction.header(), + ExecutionResult::V2(ExecutionResultV2::Failure { + effects: Effects::new(), + cost: U512::zero(), + transfers: vec![], + error_message: format!("{:?}", ite), + }), + Messages::default(), + )); + debug!(%ite, "invalid transaction"); + continue; + } + }; + // handle payment per the chainspec determined fee setting - // match chainspec.core_config.fee_handling { - // FeeHandling::None => { - // // this is the "fee elimination" model...a BalanceHold for the - // // amount is placed on the paying purse(s). - // let hold_amount = transaction.gas_limit(); - // let hold_purse = get_purse_from_transaction_initiator(); - // let hold_req = BalanceHoldRequest::new(hold_purse, hold_amount); - // match scratch_state.hold(hold_req) { - // BalanceHoldRequest::RootNotFound => {} - // BalanceHoldRequest::Failure(tce) => {} - // BalanceHoldRequest::Success{ effects } => {} - // } - // } - // FeeHandling::PayToProposer => { - // // this is the current mainnet mechanism...pay up front - // // finalize at the end - // } - // FeeHandling::Accumulate => { - // // this is a variation on PayToProposer that was added for - // // for some private networks...the fees are all accumulated - // // and distributed to administrative accounts as part of fee - // // distribution. So, we just send the payment to the accumulator - // // purse and move on. - // } - // FeeHandling::Burn => { - // // this is a new variation that is not currently supported. - // // this is for future use...but it is very simple...the - // // fees are simply burned, lowering total supply. - // } - // } + match chainspec.core_config.fee_handling { + FeeHandling::NoFee => { + // this is the "fee elimination" model...a BalanceHold for the full cost is placed + // on the initiator's purse. + let hold_amount = cost; + let hold_result = scratch_state.balance_hold(BalanceHoldRequest::new( + state_root_hash, + protocol_version, + transaction.initiator_addr().into(), + BalanceHoldAddrTag::Gas, + hold_amount, + BlockTime::new(block_time), + chainspec.core_config.balance_hold_interval, + insufficient_balance_handling, + )); + if hold_result.is_root_not_found() { + return Err(BlockExecutionError::RootNotFound(state_root_hash)); + } + let execution_result = { + let hold_cost = U512::zero(); // we don't charge for the hold itself. + let hold_effects = hold_result.effects(); + if hold_result.is_fully_covered() { + ExecutionResultV2::Success { + effects: hold_effects, + transfers: vec![], + cost: hold_cost, + } + } else { + let error_message = hold_result.error_message(); + debug!(%error_message); + ExecutionResultV2::Failure { + effects: hold_effects, + transfers: vec![], + error_message, + cost: hold_cost, + } + } + }; + execution_artifacts.push(ExecutionArtifact::new( + transaction_hash, + transaction.header(), + ExecutionResult::V2(execution_result), + Messages::default(), + )); + if !hold_result.is_fully_covered() { + continue; + } + } + FeeHandling::PayToProposer => { + // this is the current mainnet mechanism...pay up front + // finalize at the end + // we have the proposer of this block...just deposit to them + } + FeeHandling::Accumulate => { + // this is a variation on PayToProposer that was added for + // for some private networks...the fees are all accumulated + // and distributed to administrative accounts as part of fee + // distribution. So, we just send the payment to the accumulator + // purse and move on. + } + FeeHandling::Burn => { + // this is a new variation that is not currently supported. + // this is for future use...but it is very simple...the + // fees are simply burned, lowering total supply. + } + } if transaction.is_native_mint() { // native transfers are routed to the data provider diff --git a/node/src/components/fetcher/fetcher_impls/transaction_fetcher.rs b/node/src/components/fetcher/fetcher_impls/transaction_fetcher.rs index 7f64ef5a2c..2b1bdc8e91 100644 --- a/node/src/components/fetcher/fetcher_impls/transaction_fetcher.rs +++ b/node/src/components/fetcher/fetcher_impls/transaction_fetcher.rs @@ -3,7 +3,7 @@ use std::{collections::HashMap, time::Duration}; use async_trait::async_trait; use futures::FutureExt; -use casper_types::{Transaction, TransactionConfigFailure, TransactionId}; +use casper_types::{InvalidTransaction, Transaction, TransactionId}; use crate::{ components::fetcher::{ @@ -16,7 +16,7 @@ use crate::{ impl FetchItem for Transaction { type Id = TransactionId; - type ValidationError = TransactionConfigFailure; + type ValidationError = InvalidTransaction; type ValidationMetadata = EmptyValidationMetadata; const TAG: Tag = Tag::Transaction; diff --git a/node/src/components/transaction_acceptor.rs b/node/src/components/transaction_acceptor.rs index bf4b7516fd..eb5505dc91 100644 --- a/node/src/components/transaction_acceptor.rs +++ b/node/src/components/transaction_acceptor.rs @@ -129,7 +129,7 @@ impl TransactionAcceptor { self.acceptor_config.timestamp_leeway, event_metadata.verification_start_timestamp, ) - .map_err(Error::from), + .map_err(|err| Error::InvalidTransaction(err.into())), Transaction::V1(txn) => txn .is_config_compliant( &self.chain_name, @@ -139,7 +139,7 @@ impl TransactionAcceptor { self.acceptor_config.timestamp_leeway, event_metadata.verification_start_timestamp, ) - .map_err(Error::from), + .map_err(|err| Error::InvalidTransaction(err.into())), }; if let Err(error) = is_config_compliant { @@ -696,8 +696,12 @@ impl TransactionAcceptor { event_metadata: Box, ) -> Effects { let is_valid = match &event_metadata.transaction { - Transaction::Deploy(deploy) => deploy.is_valid().map_err(Error::from), - Transaction::V1(txn) => txn.verify().map_err(Error::from), + Transaction::Deploy(deploy) => deploy + .is_valid() + .map_err(|err| Error::InvalidTransaction(err.into())), + Transaction::V1(txn) => txn + .verify() + .map_err(|err| Error::InvalidTransaction(err.into())), }; if let Err(error) = is_valid { return self.reject_transaction(effect_builder, *event_metadata, error); @@ -832,6 +836,10 @@ impl TransactionAcceptor { impl Component for TransactionAcceptor { type Event = Event; + fn name(&self) -> &str { + COMPONENT_NAME + } + fn handle_event( &mut self, effect_builder: EffectBuilder, @@ -913,10 +921,6 @@ impl Component for TransactionAcceptor { } => self.handle_stored_finalized_approvals(effect_builder, event_metadata, is_new), } } - - fn name(&self) -> &str { - COMPONENT_NAME - } } // `allow` can be removed once https://github.com/casper-network/casper-node/issues/3063 is fixed. diff --git a/node/src/components/transaction_acceptor/error.rs b/node/src/components/transaction_acceptor/error.rs index 08c88dfe7d..c4fc8eb6fd 100644 --- a/node/src/components/transaction_acceptor/error.rs +++ b/node/src/components/transaction_acceptor/error.rs @@ -3,8 +3,8 @@ use serde::Serialize; use thiserror::Error; use casper_types::{ - binary_port, AddressableEntityHash, BlockHash, BlockHeader, DeployConfigFailure, Digest, - EntityVersion, InitiatorAddr, PackageHash, Timestamp, TransactionV1ConfigFailure, + binary_port, AddressableEntityHash, BlockHash, BlockHeader, Digest, EntityVersion, + InitiatorAddr, InvalidTransaction, PackageHash, Timestamp, }; // `allow` can be removed once https://github.com/casper-network/casper-node/issues/3063 is fixed. @@ -15,13 +15,9 @@ pub(crate) enum Error { #[error("block chain has no blocks")] EmptyBlockchain, - /// The deploy has an invalid configuration. - #[error("invalid deploy: {0}")] - InvalidDeployConfiguration(#[from] DeployConfigFailure), - - /// The v1 transaction has an invalid configuration. - #[error("invalid v1 transaction: {0}")] - InvalidV1Configuration(#[from] TransactionV1ConfigFailure), + /// The deploy has an invalid transaction. + #[error("invalid transaction: {0}")] + InvalidTransaction(#[from] InvalidTransaction), /// The transaction is invalid due to missing or otherwise invalid parameters. #[error( @@ -72,8 +68,7 @@ impl From for binary_port::ErrorCode { fn from(err: Error) -> Self { match err { Error::EmptyBlockchain - | Error::InvalidDeployConfiguration(_) - | Error::InvalidV1Configuration(_) + | Error::InvalidTransaction(_) | Error::Parameters { .. } | Error::Expired { .. } | Error::ExpectedDeploy diff --git a/node/src/components/transaction_acceptor/tests.rs b/node/src/components/transaction_acceptor/tests.rs index 343a48b8eb..29522b35db 100644 --- a/node/src/components/transaction_acceptor/tests.rs +++ b/node/src/components/transaction_acceptor/tests.rs @@ -28,10 +28,10 @@ use casper_types::{ bytesrepr::Bytes, global_state::TrieMerkleProof, testing::TestRng, - Block, BlockV2, CLValue, Chainspec, ChainspecRawBytes, Contract, Deploy, DeployConfigFailure, - EraId, HashAddr, Package, PublicKey, SecretKey, StoredValue, TestBlockBuilder, TimeDiff, - Timestamp, Transaction, TransactionSessionKind, TransactionV1, TransactionV1Builder, - TransactionV1ConfigFailure, URef, URefAddr, U512, + Block, BlockV2, CLValue, Chainspec, ChainspecRawBytes, Contract, Deploy, EraId, HashAddr, + InvalidDeploy, InvalidTransaction, InvalidTransactionV1, Package, PublicKey, SecretKey, + StoredValue, TestBlockBuilder, TimeDiff, Timestamp, Transaction, TransactionSessionKind, + TransactionV1, TransactionV1Builder, URef, URefAddr, U512, }; use super::*; @@ -650,46 +650,6 @@ impl reactor::Reactor for Reactor { type Config = TestScenario; type Error = Error; - fn new( - config: Self::Config, - chainspec: Arc, - _chainspec_raw_bytes: Arc, - _network_identity: NetworkIdentity, - registry: &Registry, - _event_queue: EventQueueHandle, - _rng: &mut NodeRng, - ) -> Result<(Self, Effects), Self::Error> { - let (storage_config, storage_tempdir) = storage::Config::new_for_tests(1); - let storage_withdir = WithDir::new(storage_tempdir.path(), storage_config); - - let transaction_acceptor = - TransactionAcceptor::new(Config::default(), chainspec.as_ref(), registry).unwrap(); - - let storage = Storage::new( - &storage_withdir, - None, - ProtocolVersion::from_parts(1, 0, 0), - EraId::default(), - "test", - chainspec.transaction_config.max_ttl.into(), - chainspec.core_config.recent_era_count(), - Some(registry), - false, - ) - .unwrap(); - - let reactor = Reactor { - storage, - transaction_acceptor, - _storage_tempdir: storage_tempdir, - test_scenario: config, - }; - - let effects = Effects::new(); - - Ok((reactor, effects)) - } - fn dispatch_event( &mut self, effect_builder: EffectBuilder, @@ -871,6 +831,46 @@ impl reactor::Reactor for Reactor { Event::NetworkRequest(_) => panic!("test does not handle network requests"), } } + + fn new( + config: Self::Config, + chainspec: Arc, + _chainspec_raw_bytes: Arc, + _network_identity: NetworkIdentity, + registry: &Registry, + _event_queue: EventQueueHandle, + _rng: &mut NodeRng, + ) -> Result<(Self, Effects), Self::Error> { + let (storage_config, storage_tempdir) = storage::Config::new_for_tests(1); + let storage_withdir = WithDir::new(storage_tempdir.path(), storage_config); + + let transaction_acceptor = + TransactionAcceptor::new(Config::default(), chainspec.as_ref(), registry).unwrap(); + + let storage = Storage::new( + &storage_withdir, + None, + ProtocolVersion::from_parts(1, 0, 0), + EraId::default(), + "test", + chainspec.transaction_config.max_ttl.into(), + chainspec.core_config.recent_era_count(), + Some(registry), + false, + ) + .unwrap(); + + let reactor = Reactor { + storage, + transaction_acceptor, + _storage_tempdir: storage_tempdir, + test_scenario: config, + }; + + let effects = Effects::new(); + + Ok((reactor, effects)) + } } fn put_block_to_storage_and_mark_complete( @@ -1251,7 +1251,9 @@ async fn should_reject_invalid_deploy_from_peer() { run_transaction_acceptor(TestScenario::FromPeerInvalidTransaction(TxnType::Deploy)).await; assert!(matches!( result, - Err(super::Error::InvalidDeployConfiguration(_)) + Err(super::Error::InvalidTransaction( + InvalidTransaction::Deploy(_) + )) )) } @@ -1261,7 +1263,7 @@ async fn should_reject_invalid_transaction_v1_from_peer() { run_transaction_acceptor(TestScenario::FromPeerInvalidTransaction(TxnType::V1)).await; assert!(matches!( result, - Err(super::Error::InvalidV1Configuration(_)) + Err(super::Error::InvalidTransaction(InvalidTransaction::V1(_))) )) } @@ -1334,7 +1336,9 @@ async fn should_reject_invalid_deploy_from_client() { run_transaction_acceptor(TestScenario::FromClientInvalidTransaction(TxnType::Deploy)).await; assert!(matches!( result, - Err(super::Error::InvalidDeployConfiguration(_)) + Err(super::Error::InvalidTransaction( + InvalidTransaction::Deploy(_) + )) )) } @@ -1344,7 +1348,7 @@ async fn should_reject_invalid_transaction_v1_from_client() { run_transaction_acceptor(TestScenario::FromClientInvalidTransaction(TxnType::V1)).await; assert!(matches!( result, - Err(super::Error::InvalidV1Configuration(_)) + Err(super::Error::InvalidTransaction(InvalidTransaction::V1(_))) )) } @@ -1374,8 +1378,8 @@ async fn should_reject_future_dated_deploy_from_client() { .await; assert!(matches!( result, - Err(super::Error::InvalidDeployConfiguration( - DeployConfigFailure::TimestampInFuture { .. } + Err(super::Error::InvalidTransaction( + InvalidTransaction::Deploy(InvalidDeploy::TimestampInFuture { .. }) )) )) } @@ -1386,9 +1390,9 @@ async fn should_reject_future_dated_transaction_v1_from_client() { run_transaction_acceptor(TestScenario::FromClientFutureDatedTransaction(TxnType::V1)).await; assert!(matches!( result, - Err(super::Error::InvalidV1Configuration( - TransactionV1ConfigFailure::TimestampInFuture { .. } - )) + Err(super::Error::InvalidTransaction(InvalidTransaction::V1( + InvalidTransactionV1::TimestampInFuture { .. } + ))) )) } @@ -2183,8 +2187,8 @@ async fn should_reject_deploy_without_transfer_amount() { let result = run_transaction_acceptor(test_scenario).await; assert!(matches!( result, - Err(super::Error::InvalidDeployConfiguration( - DeployConfigFailure::MissingTransferAmount + Err(super::Error::InvalidTransaction( + InvalidTransaction::Deploy(InvalidDeploy::MissingTransferAmount) )) )) } @@ -2208,8 +2212,8 @@ async fn should_reject_deploy_with_mangled_transfer_amount() { let result = run_transaction_acceptor(test_scenario).await; assert!(matches!( result, - Err(super::Error::InvalidDeployConfiguration( - DeployConfigFailure::FailedToParseTransferAmount + Err(super::Error::InvalidTransaction( + InvalidTransaction::Deploy(InvalidDeploy::FailedToParseTransferAmount) )) )) } diff --git a/node/src/components/transaction_buffer.rs b/node/src/components/transaction_buffer.rs index a361ee74ed..6a3486cb84 100644 --- a/node/src/components/transaction_buffer.rs +++ b/node/src/components/transaction_buffer.rs @@ -39,7 +39,7 @@ use crate::{ storage::Storage, types::{ appendable_block::{AddError, AppendableBlock}, - FinalizedBlock, TransactionExt, TransactionFootprint, + FinalizedBlock, TransactionFootprint, }, NodeRng, }; @@ -216,10 +216,6 @@ impl TransactionBuffer { error!(%transaction_hash, "TransactionBuffer: invalid transaction must not be buffered"); return; } - if self.dead.contains(&transaction_hash) { - info!(%transaction_hash, "TransactionBuffer: attempt to register already dead transaction"); - return; - } if self .hold .values() @@ -228,10 +224,10 @@ impl TransactionBuffer { info!(%transaction_hash, "TransactionBuffer: attempt to register already held transaction"); return; } - let footprint = match transaction.footprint(&self.chainspec) { - Some(footprint) => footprint, - None => { - error!(%transaction_hash, "TransactionBuffer: unable to created transaction footprint"); + let footprint = match TransactionFootprint::new(&self.chainspec, &transaction) { + Ok(footprint) => footprint, + Err(invalid_transaction_error) => { + error!(%transaction_hash, ?invalid_transaction_error, "TransactionBuffer: unable to created transaction footprint"); return; } }; diff --git a/node/src/types.rs b/node/src/types.rs index 4f1b71d939..95a836b2c0 100644 --- a/node/src/types.rs +++ b/node/src/types.rs @@ -36,7 +36,7 @@ pub use node_config::{NodeConfig, SyncHandling}; pub(crate) use node_id::NodeId; pub use status_feed::{ChainspecInfo, GetStatusResult, StatusFeed}; pub(crate) use sync_leap::{GlobalStatesMetadata, SyncLeap, SyncLeapIdentifier}; -pub(crate) use transaction::{LegacyDeploy, TransactionExt, TransactionFootprint}; +pub(crate) use transaction::{LegacyDeploy, TransactionFootprint}; pub(crate) use validator_matrix::{EraValidatorWeights, SignatureWeight, ValidatorMatrix}; pub use value_or_chunk::{ ChunkingError, TrieOrChunk, TrieOrChunkId, TrieOrChunkIdDisplay, ValueOrChunk, diff --git a/node/src/types/transaction.rs b/node/src/types/transaction.rs index 5ae855dafe..3fa0faaa3b 100644 --- a/node/src/types/transaction.rs +++ b/node/src/types/transaction.rs @@ -2,4 +2,4 @@ mod deploy; mod transaction_footprint; pub(crate) use deploy::LegacyDeploy; -pub(crate) use transaction_footprint::{TransactionExt, TransactionFootprint}; +pub(crate) use transaction_footprint::TransactionFootprint; diff --git a/node/src/types/transaction/deploy/legacy_deploy.rs b/node/src/types/transaction/deploy/legacy_deploy.rs index ad2afe97f9..90adc1086c 100644 --- a/node/src/types/transaction/deploy/legacy_deploy.rs +++ b/node/src/types/transaction/deploy/legacy_deploy.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use casper_types::{ bytesrepr::{self, FromBytes, ToBytes}, - Deploy, DeployConfigFailure, DeployHash, Transaction, + Deploy, DeployHash, InvalidDeploy, Transaction, }; use crate::components::fetcher::{EmptyValidationMetadata, FetchItem, Tag}; @@ -15,7 +15,7 @@ pub(crate) struct LegacyDeploy(Deploy); impl FetchItem for LegacyDeploy { type Id = DeployHash; - type ValidationError = DeployConfigFailure; + type ValidationError = InvalidDeploy; type ValidationMetadata = EmptyValidationMetadata; const TAG: Tag = Tag::LegacyDeploy; diff --git a/node/src/types/transaction/transaction_footprint.rs b/node/src/types/transaction/transaction_footprint.rs index 0de9ae9b09..0d72584097 100644 --- a/node/src/types/transaction/transaction_footprint.rs +++ b/node/src/types/transaction/transaction_footprint.rs @@ -1,11 +1,10 @@ use casper_types::{ - bytesrepr::ToBytes, Approval, Chainspec, Digest, Gas, TimeDiff, Timestamp, Transaction, - TransactionCategory, TransactionHash, + Approval, CategorizedTransaction, Chainspec, Digest, Gas, GasLimited, InvalidTransaction, + TimeDiff, Timestamp, Transaction, TransactionCategory, TransactionHash, }; use datasize::DataSize; use serde::{Deserialize, Serialize}; use std::collections::BTreeSet; -use tracing::error; #[derive(Clone, Debug, DataSize, Eq, PartialEq, Serialize, Deserialize)] #[serde(deny_unknown_fields)] @@ -30,6 +29,34 @@ pub(crate) struct TransactionFootprint { } impl TransactionFootprint { + pub(crate) fn new( + chainspec: &Chainspec, + transaction: &Transaction, + ) -> Result { + let cost_table = &chainspec.system_costs_config; + // IMPORTANT: block inclusion is always calculated based upon gas price multiple = 1 + // Do not confuse actual cost with retail cost. + let gas_price: Option = None; + let gas_limit = transaction.gas_limit(cost_table, gas_price)?; + let category = transaction.category(); + let transaction_hash = transaction.hash(); + let body_hash = transaction.body_hash(); + let size_estimate = transaction.size_estimate(); + let timestamp = transaction.timestamp(); + let ttl = transaction.ttl(); + let approvals = transaction.approvals(); + Ok(TransactionFootprint { + transaction_hash, + body_hash, + gas_limit, + size_estimate, + category, + timestamp, + ttl, + approvals, + }) + } + /// Sets approvals. pub(crate) fn with_approvals(mut self, approvals: BTreeSet) -> Self { self.approvals = approvals; @@ -61,106 +88,3 @@ impl TransactionFootprint { matches!(self.category, TransactionCategory::InstallUpgrade) } } - -pub(crate) trait TransactionExt { - fn footprint(&self, chainspec: &Chainspec) -> Option; -} - -impl TransactionExt for Transaction { - /// Returns the `TransactionFootprint`, if able. - fn footprint(&self, chainspec: &Chainspec) -> Option { - let cost_table = &chainspec.system_costs_config; - - // IMPORTANT: block inclusion is always calculated based upon gas price multiple = 1 - // Do not confuse actual cost with retail cost. - let gas_price: Option = None; - let ( - transaction_hash, - body_hash, - gas_limit, - size_estimate, - category, - timestamp, - ttl, - approvals, - ) = match self { - Transaction::Deploy(deploy) => { - let transaction_hash = TransactionHash::Deploy(*deploy.hash()); - let body_hash = *deploy.header().body_hash(); - let gas_limit = match deploy.gas_limit(cost_table, gas_price) { - Ok(amount) => amount, - Err(err) => { - error!("{:?}", err); - return None; - } - }; - let size_estimate = deploy.serialized_length(); - let category = if deploy.is_transfer() { - TransactionCategory::Mint - } else { - TransactionCategory::Standard - }; - let timestamp = deploy.header().timestamp(); - let ttl = deploy.header().ttl(); - let approvals = self.approvals(); - ( - transaction_hash, - body_hash, - gas_limit, - size_estimate, - category, - timestamp, - ttl, - approvals, - ) - } - Transaction::V1(transaction) => { - let transaction_hash = TransactionHash::V1(*transaction.hash()); - let body_hash = *transaction.header().body_hash(); - let gas_limit = match transaction.gas_limit(cost_table, gas_price) { - Some(amount) => amount, - None => { - error!( - "failed to determine gas limit for transaction {:?}", - transaction_hash - ); - return None; - } - }; - let size_estimate = transaction.serialized_length(); - let category = if transaction.is_native_mint() { - TransactionCategory::Mint - } else if transaction.is_native_auction() { - TransactionCategory::Auction - } else if transaction.is_install_or_upgrade() { - TransactionCategory::InstallUpgrade - } else { - TransactionCategory::Standard - }; - let timestamp = transaction.header().timestamp(); - let ttl = transaction.header().ttl(); - let approvals = self.approvals(); - ( - transaction_hash, - body_hash, - gas_limit, - size_estimate, - category, - timestamp, - ttl, - approvals, - ) - } - }; - Some(TransactionFootprint { - transaction_hash, - body_hash, - gas_limit, - size_estimate, - category, - timestamp, - ttl, - approvals, - }) - } -} diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index 5c28a0544c..9bc284f571 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -3406,7 +3406,7 @@ "additionalProperties": false }, "TransformKindV2": { - "description": "Representation of a single transformation occurring during execution.\n\nNote that all arithmetic variants of [`TransformKind`] are commutative which means that a given collection of them can be executed in any order to produce the same end result.", + "description": "Representation of a single transformation occurring during execution.\n\nNote that all arithmetic variants of TransformKind are commutative which means that a given collection of them can be executed in any order to produce the same end result.", "oneOf": [ { "description": "An identity transformation that does not modify a value in the global state.\n\nCreated as a result of reading from the global state.", diff --git a/storage/src/data_access_layer/balance.rs b/storage/src/data_access_layer/balance.rs index 21decbdd23..8311a8fed9 100644 --- a/storage/src/data_access_layer/balance.rs +++ b/storage/src/data_access_layer/balance.rs @@ -2,8 +2,8 @@ use crate::data_access_layer::BalanceHoldRequest; use casper_types::{ account::AccountHash, global_state::TrieMerkleProof, system::mint::BalanceHoldAddrTag, - AccessRights, BlockTime, Digest, EntityAddr, Key, ProtocolVersion, PublicKey, StoredValue, - URef, URefAddr, U512, + AccessRights, BlockTime, Digest, EntityAddr, InitiatorAddr, Key, ProtocolVersion, PublicKey, + StoredValue, URef, URefAddr, U512, }; use std::collections::BTreeMap; @@ -98,6 +98,15 @@ impl Default for BalanceIdentifier { } } +impl From for BalanceIdentifier { + fn from(value: InitiatorAddr) -> Self { + match value { + InitiatorAddr::PublicKey(public_key) => BalanceIdentifier::Public(public_key), + InitiatorAddr::AccountHash(account_hash) => BalanceIdentifier::Account(account_hash), + } + } +} + /// Represents a balance request. #[derive(Debug, Clone, PartialEq, Eq)] pub struct BalanceRequest { diff --git a/storage/src/data_access_layer/balance_hold.rs b/storage/src/data_access_layer/balance_hold.rs index 387f0f1d9f..794015eb2e 100644 --- a/storage/src/data_access_layer/balance_hold.rs +++ b/storage/src/data_access_layer/balance_hold.rs @@ -1,7 +1,7 @@ use crate::{data_access_layer::BalanceIdentifier, tracking_copy::TrackingCopyError}; use casper_types::{ - account::AccountHash, system::mint::BalanceHoldAddrTag, BlockTime, Digest, EntityAddr, - ProtocolVersion, PublicKey, TimeDiff, URef, URefAddr, U512, + account::AccountHash, execution::Effects, system::mint::BalanceHoldAddrTag, BlockTime, Digest, + EntityAddr, ProtocolVersion, PublicKey, TimeDiff, URef, URefAddr, U512, }; use std::fmt::{Display, Formatter}; use thiserror::Error; @@ -242,12 +242,79 @@ pub enum BalanceHoldResult { /// Balance hold successfully placed. Success { /// Purse total balance. - total_balance: U512, + total_balance: Box, /// Purse available balance after hold placed. - available_balance: U512, - /// Were we able to hold the full amount? - full_amount_held: bool, + available_balance: Box, + /// How much were we supposed to hold? + hold: Box, + /// How much did we actually hold? + held: Box, + /// Effects of bidding interaction. + effects: Box, }, /// Failed to place balance hold. Failure(BalanceHoldError), } + +impl BalanceHoldResult { + pub fn success( + total_balance: U512, + available_balance: U512, + hold: U512, + held: U512, + effects: Effects, + ) -> Self { + BalanceHoldResult::Success { + total_balance: Box::new(total_balance), + available_balance: Box::new(available_balance), + hold: Box::new(hold), + held: Box::new(held), + effects: Box::new(effects), + } + } + + /// Was the hold fully covered? + pub fn is_fully_covered(&self) -> bool { + match self { + BalanceHoldResult::RootNotFound | BalanceHoldResult::Failure(_) => false, + BalanceHoldResult::Success { hold, held, .. } => hold == held, + } + } + + /// Was the hold successful? + pub fn is_success(&self) -> bool { + matches!(self, BalanceHoldResult::Success { .. }) + } + + /// Was the root not found? + pub fn is_root_not_found(&self) -> bool { + matches!(self, BalanceHoldResult::RootNotFound) + } + + /// The effects, if any. + pub fn effects(&self) -> Effects { + match self { + BalanceHoldResult::RootNotFound | BalanceHoldResult::Failure(_) => Effects::new(), + BalanceHoldResult::Success { effects, .. } => *effects.clone(), + } + } + + pub fn error_message(&self) -> String { + match self { + BalanceHoldResult::Success { hold, held, .. } => { + if hold == held { + String::default() + } else { + format!( + "insufficient balance to cover hold amount: {}, held remaining amount: {}", + hold, held + ) + } + } + BalanceHoldResult::RootNotFound => "root not found".to_string(), + BalanceHoldResult::Failure(bhe) => { + format!("{:?}", bhe) + } + } + } +} diff --git a/storage/src/global_state/state/mod.rs b/storage/src/global_state/state/mod.rs index 71908d08ee..342faf6e82 100644 --- a/storage/src/global_state/state/mod.rs +++ b/storage/src/global_state/state/mod.rs @@ -860,10 +860,10 @@ pub trait StateProvider { } => (total_balance, available_balance, purse_addr), }; - let (hold_amount, covered) = { + let held_amount = { if remaining_balance >= request.hold_amount() { // the purse has sufficient balance to fully cover the hold - (request.hold_amount(), true) + request.hold_amount() } else if request.insufficient_handling() == InsufficientBalanceHandling::Noop { // the purse has insufficient balance but the holding mode is noop, so get out return BalanceHoldResult::Failure(BalanceHoldError::InsufficientBalance { @@ -879,11 +879,11 @@ pub trait StateProvider { // knowing that they will fail due to insufficient funds, but only // after making the system do the work of processing the balance // check without penalty to themselves. - (remaining_balance, false) + remaining_balance } }; - let cl_value = match CLValue::from_t(hold_amount) { + let cl_value = match CLValue::from_t(held_amount) { Ok(cl_value) => cl_value, Err(cve) => { return BalanceHoldResult::Failure(BalanceHoldError::TrackingCopy( @@ -903,13 +903,17 @@ pub trait StateProvider { Key::BalanceHold(balance_hold_addr), StoredValue::CLValue(cl_value), ); - let available_balance = remaining_balance.saturating_sub(hold_amount); - BalanceHoldResult::Success { + let available_balance = remaining_balance.saturating_sub(held_amount); + let effects = tc.effects(); + + BalanceHoldResult::success( total_balance, available_balance, - full_amount_held: covered, - } + held_amount, + request.hold_amount(), + effects, + ) } /// Get the requested era validators. diff --git a/storage/src/system/handle_payment/internal.rs b/storage/src/system/handle_payment/internal.rs index 8d9c884922..6edb623808 100644 --- a/storage/src/system/handle_payment/internal.rs +++ b/storage/src/system/handle_payment/internal.rs @@ -202,7 +202,7 @@ pub fn finalize_payment( provider.write_balance(payment_purse, U512::zero())?; provider.reduce_total_supply(fee)?; } - FeeHandling::None => { + FeeHandling::NoFee => { // noop } } @@ -244,7 +244,7 @@ where // Distribute accumulation purse balance into all administrators match provider.fee_handling() { - FeeHandling::PayToProposer | FeeHandling::Burn | FeeHandling::None => return Ok(()), + FeeHandling::PayToProposer | FeeHandling::Burn | FeeHandling::NoFee => return Ok(()), FeeHandling::Accumulate => {} } diff --git a/storage/src/system/protocol_upgrade.rs b/storage/src/system/protocol_upgrade.rs index b5fdc7e04d..9efa6ec05c 100644 --- a/storage/src/system/protocol_upgrade.rs +++ b/storage/src/system/protocol_upgrade.rs @@ -571,7 +571,7 @@ where debug!(?fee_handling, "create accumulation purse if required"); match fee_handling { FeeHandling::PayToProposer | FeeHandling::Burn => return Ok(()), - FeeHandling::Accumulate | FeeHandling::None => {} + FeeHandling::Accumulate | FeeHandling::NoFee => {} } let mut address_generator = { let seed_bytes = ( diff --git a/types/src/chainspec.rs b/types/src/chainspec.rs index 1dfcd9578b..aede3c0848 100644 --- a/types/src/chainspec.rs +++ b/types/src/chainspec.rs @@ -17,6 +17,7 @@ mod transaction_config; mod upgrade_config; mod vm_config; +#[cfg(any(feature = "std", test))] use std::{fmt::Debug, sync::Arc}; #[cfg(feature = "datasize")] diff --git a/types/src/chainspec/fee_handling.rs b/types/src/chainspec/fee_handling.rs index 199d956c61..a5e9b76fba 100644 --- a/types/src/chainspec/fee_handling.rs +++ b/types/src/chainspec/fee_handling.rs @@ -26,7 +26,7 @@ pub enum FeeHandling { /// Burn the fees. Burn, /// No fees. - None, + NoFee, } impl FeeHandling { @@ -42,7 +42,7 @@ impl ToBytes for FeeHandling { FeeHandling::PayToProposer => Ok(vec![FEE_HANDLING_PROPOSER_TAG]), FeeHandling::Accumulate => Ok(vec![FEE_HANDLING_ACCUMULATE_TAG]), FeeHandling::Burn => Ok(vec![FEE_HANDLING_BURN_TAG]), - FeeHandling::None => Ok(vec![FEE_HANDLING_NONE_TAG]), + FeeHandling::NoFee => Ok(vec![FEE_HANDLING_NONE_TAG]), } } @@ -58,7 +58,7 @@ impl FromBytes for FeeHandling { FEE_HANDLING_PROPOSER_TAG => Ok((FeeHandling::PayToProposer, rem)), FEE_HANDLING_ACCUMULATE_TAG => Ok((FeeHandling::Accumulate, rem)), FEE_HANDLING_BURN_TAG => Ok((FeeHandling::Burn, rem)), - FEE_HANDLING_NONE_TAG => Ok((FeeHandling::None, rem)), + FEE_HANDLING_NONE_TAG => Ok((FeeHandling::NoFee, rem)), _ => Err(bytesrepr::Error::Formatting), } } diff --git a/types/src/chainspec/genesis_config.rs b/types/src/chainspec/genesis_config.rs index 1a1dcd71ea..480e35c1fa 100644 --- a/types/src/chainspec/genesis_config.rs +++ b/types/src/chainspec/genesis_config.rs @@ -1,3 +1,5 @@ +//! Contains genesis configuration settings. + #[cfg(any(feature = "testing", test))] use std::iter; diff --git a/types/src/execution/transform_kind.rs b/types/src/execution/transform_kind.rs index 45731dbb67..521be83b70 100644 --- a/types/src/execution/transform_kind.rs +++ b/types/src/execution/transform_kind.rs @@ -46,7 +46,7 @@ impl From for TransformInstruction { /// Representation of a single transformation occurring during execution. /// -/// Note that all arithmetic variants of [`TransformKind`] are commutative which means that a given +/// Note that all arithmetic variants of TransformKind are commutative which means that a given /// collection of them can be executed in any order to produce the same end result. #[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Debug)] #[cfg_attr(feature = "datasize", derive(DataSize))] diff --git a/types/src/lib.rs b/types/src/lib.rs index 9c2dae93c8..f3f5056b87 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -181,16 +181,20 @@ pub use tagged::Tagged; #[cfg(any(feature = "std", test))] pub use timestamp::serde_option_time_diff; pub use timestamp::{TimeDiff, Timestamp}; + +#[cfg(any(feature = "std", test))] +pub use transaction::GasLimited; pub use transaction::{ - AddressableEntityIdentifier, Approval, ApprovalsHash, Deploy, DeployConfigFailure, - DeployDecodeFromJsonError, DeployError, DeployExcessiveSizeError, DeployHash, DeployHeader, - DeployId, ExecutableDeployItem, ExecutableDeployItemIdentifier, ExecutionInfo, InitiatorAddr, - NamedArg, PackageIdentifier, PricingMode, RuntimeArgs, Transaction, TransactionCategory, - TransactionConfigFailure, TransactionEntryPoint, TransactionHash, TransactionHeader, - TransactionId, TransactionInvocationTarget, TransactionRuntime, TransactionScheduling, - TransactionSessionKind, TransactionTarget, TransactionV1, TransactionV1Body, - TransactionV1ConfigFailure, TransactionV1DecodeFromJsonError, TransactionV1Error, - TransactionV1ExcessiveSizeError, TransactionV1Hash, TransactionV1Header, TransferTarget, + AddressableEntityIdentifier, Approval, ApprovalsHash, Categorized as CategorizedTransaction, + Deploy, DeployDecodeFromJsonError, DeployError, DeployExcessiveSizeError, DeployHash, + DeployHeader, DeployId, ExecutableDeployItem, ExecutableDeployItemIdentifier, ExecutionInfo, + InitiatorAddr, InvalidDeploy, InvalidTransaction, InvalidTransactionV1, NamedArg, + PackageIdentifier, PricingMode, RuntimeArgs, Transaction, TransactionCategory, + TransactionEntryPoint, TransactionHash, TransactionHeader, TransactionId, + TransactionInvocationTarget, TransactionRuntime, TransactionScheduling, TransactionSessionKind, + TransactionTarget, TransactionV1, TransactionV1Body, TransactionV1DecodeFromJsonError, + TransactionV1Error, TransactionV1ExcessiveSizeError, TransactionV1Hash, TransactionV1Header, + TransferTarget, }; #[cfg(any(feature = "std", test))] pub use transaction::{ diff --git a/types/src/transaction.rs b/types/src/transaction.rs index 4dbbf3b2dc..40a7c200d6 100644 --- a/types/src/transaction.rs +++ b/types/src/transaction.rs @@ -2,6 +2,7 @@ mod addressable_entity_identifier; mod approval; mod approvals_hash; mod deploy; +mod error; mod execution_info; mod initiator_addr; #[cfg(any(feature = "std", test))] @@ -23,8 +24,8 @@ mod transaction_v1; use alloc::{collections::BTreeSet, vec::Vec}; use core::fmt::{self, Debug, Display, Formatter}; -#[cfg(feature = "std")] -use std::error::Error as StdError; +#[cfg(any(feature = "std", test))] +use std::hash::Hash; #[cfg(feature = "datasize")] use datasize::DataSize; @@ -38,25 +39,31 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use tracing::error; +#[cfg(any(feature = "std", test))] +use crate::SystemConfig; + #[cfg(any(all(feature = "std", feature = "testing"), test))] use crate::testing::TestRng; +#[cfg(any(feature = "std", test))] +use crate::Gas; use crate::{ account::AccountHash, bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, - Digest, SecretKey, Timestamp, + Digest, SecretKey, TimeDiff, Timestamp, }; #[cfg(feature = "json-schema")] -use crate::{account::ACCOUNT_HASH_LENGTH, TimeDiff, URef}; +use crate::{account::ACCOUNT_HASH_LENGTH, URef}; pub use addressable_entity_identifier::AddressableEntityIdentifier; pub use approval::Approval; pub use approvals_hash::ApprovalsHash; pub use deploy::{ - Deploy, DeployConfigFailure, DeployDecodeFromJsonError, DeployError, DeployExcessiveSizeError, - DeployHash, DeployHeader, DeployId, ExecutableDeployItem, ExecutableDeployItemIdentifier, + Deploy, DeployDecodeFromJsonError, DeployError, DeployExcessiveSizeError, DeployHash, + DeployHeader, DeployId, ExecutableDeployItem, ExecutableDeployItemIdentifier, InvalidDeploy, TransferTarget, }; #[cfg(any(feature = "std", test))] pub use deploy::{DeployBuilder, DeployBuilderError}; +pub use error::InvalidTransaction; pub use execution_info::ExecutionInfo; pub use initiator_addr::InitiatorAddr; #[cfg(any(feature = "std", test))] @@ -74,7 +81,7 @@ pub use transaction_scheduling::TransactionScheduling; pub use transaction_session_kind::TransactionSessionKind; pub use transaction_target::TransactionTarget; pub use transaction_v1::{ - TransactionCategory, TransactionV1, TransactionV1Body, TransactionV1ConfigFailure, + InvalidTransactionV1, TransactionCategory, TransactionV1, TransactionV1Body, TransactionV1DecodeFromJsonError, TransactionV1Error, TransactionV1ExcessiveSizeError, TransactionV1Hash, TransactionV1Header, }; @@ -109,46 +116,6 @@ pub(super) static TRANSACTION: Lazy = Lazy::new(|| { Transaction::V1(v1_txn) }); -/// A representation of the way in which a transaction failed validation checks. -#[derive(Debug)] -pub enum TransactionConfigFailure { - /// Error details for the Deploy variant. - Deploy(DeployConfigFailure), - /// Error details for the TransactionV1 variant. - V1(TransactionV1ConfigFailure), -} - -impl From for TransactionConfigFailure { - fn from(value: DeployConfigFailure) -> Self { - Self::Deploy(value) - } -} - -impl From for TransactionConfigFailure { - fn from(value: TransactionV1ConfigFailure) -> Self { - Self::V1(value) - } -} - -#[cfg(feature = "std")] -impl StdError for TransactionConfigFailure { - fn source(&self) -> Option<&(dyn StdError + 'static)> { - match self { - TransactionConfigFailure::Deploy(deploy) => deploy.source(), - TransactionConfigFailure::V1(v1) => v1.source(), - } - } -} - -impl Display for TransactionConfigFailure { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self { - TransactionConfigFailure::Deploy(deploy) => write!(f, "{}", deploy), - TransactionConfigFailure::V1(v1) => write!(f, "{}", v1), - } - } -} - /// A versioned wrapper for a transaction or deploy. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[cfg_attr( @@ -175,9 +142,41 @@ impl Transaction { } } + /// Body hash. + pub fn body_hash(&self) -> Digest { + match self { + Transaction::Deploy(deploy) => *deploy.header().body_hash(), + Transaction::V1(v1) => *v1.header().body_hash(), + } + } + + /// Size estimate. + pub fn size_estimate(&self) -> usize { + match self { + Transaction::Deploy(deploy) => deploy.serialized_length(), + Transaction::V1(v1) => v1.header().serialized_length(), + } + } + + /// Timestamp. + pub fn timestamp(&self) -> Timestamp { + match self { + Transaction::Deploy(deploy) => deploy.header().timestamp(), + Transaction::V1(v1) => v1.header().timestamp(), + } + } + + /// Time to live. + pub fn ttl(&self) -> TimeDiff { + match self { + Transaction::Deploy(deploy) => deploy.header().ttl(), + Transaction::V1(v1) => v1.header().ttl(), + } + } + /// Returns `Ok` if the given transaction is valid. Verification procedure is delegated to the /// implementation of the particular variant of the transaction. - pub fn verify(&self) -> Result<(), TransactionConfigFailure> { + pub fn verify(&self) -> Result<(), InvalidTransaction> { match self { Transaction::Deploy(deploy) => deploy.is_valid().map_err(Into::into), Transaction::V1(v1) => v1.verify().map_err(Into::into), @@ -386,6 +385,55 @@ impl Transaction { } } +/// Self discloses category. +pub trait Categorized { + /// What category does this instance belong in. + fn category(&self) -> TransactionCategory; +} + +impl Categorized for Transaction { + fn category(&self) -> TransactionCategory { + match self { + Transaction::Deploy(deploy) => deploy.category(), + Transaction::V1(v1) => v1.category(), + } + } +} + +/// Calculates gas limit for a transaction. +#[cfg(any(feature = "std", test))] +pub trait GasLimited { + /// The error type. + type Error; + + /// Returns the gas limit or an error. + fn gas_limit( + &self, + system_costs: &SystemConfig, + gas_price: Option, + ) -> Result; +} + +#[cfg(any(feature = "std", test))] +impl GasLimited for Transaction { + type Error = InvalidTransaction; + + fn gas_limit( + &self, + system_costs: &SystemConfig, + gas_price: Option, + ) -> Result { + match self { + Transaction::Deploy(deploy) => deploy + .gas_limit(system_costs, gas_price) + .map_err(InvalidTransaction::from), + Transaction::V1(v1) => v1 + .gas_limit(system_costs, gas_price) + .map_err(InvalidTransaction::from), + } + } +} + impl From for Transaction { fn from(deploy: Deploy) -> Self { Self::Deploy(deploy) @@ -399,19 +447,6 @@ impl From for Transaction { } impl ToBytes for Transaction { - fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - match self { - Transaction::Deploy(deploy) => { - DEPLOY_TAG.write_bytes(writer)?; - deploy.write_bytes(writer) - } - Transaction::V1(txn) => { - V1_TAG.write_bytes(writer)?; - txn.write_bytes(writer) - } - } - } - fn to_bytes(&self) -> Result, bytesrepr::Error> { let mut buffer = bytesrepr::allocate_buffer(self)?; self.write_bytes(&mut buffer)?; @@ -425,6 +460,19 @@ impl ToBytes for Transaction { Transaction::V1(txn) => txn.serialized_length(), } } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + match self { + Transaction::Deploy(deploy) => { + DEPLOY_TAG.write_bytes(writer)?; + deploy.write_bytes(writer) + } + Transaction::V1(txn) => { + V1_TAG.write_bytes(writer)?; + txn.write_bytes(writer) + } + } + } } impl FromBytes for Transaction { diff --git a/types/src/transaction/deploy.rs b/types/src/transaction/deploy.rs index 5ea2e38068..946b1dab6f 100644 --- a/types/src/transaction/deploy.rs +++ b/types/src/transaction/deploy.rs @@ -55,13 +55,16 @@ use crate::runtime_args; use crate::RuntimeArgs; use crate::{ bytesrepr::{self, FromBytes, ToBytes}, - crypto, Digest, DisplayIter, PublicKey, SecretKey, TimeDiff, Timestamp, + crypto, Digest, DisplayIter, PublicKey, SecretKey, TimeDiff, Timestamp, TransactionCategory, }; #[cfg(any(feature = "std", test))] use crate::{system::auction::ARG_AMOUNT, SystemConfig}; -use crate::transaction::{Approval, ApprovalsHash}; +#[cfg(any(feature = "std", test))] +pub use crate::transaction::GasLimited; + +use crate::transaction::{Approval, ApprovalsHash, Categorized}; #[cfg(any(feature = "std", test))] pub use deploy_builder::{DeployBuilder, DeployBuilderError}; pub use deploy_category::DeployCategory; @@ -69,8 +72,8 @@ pub use deploy_hash::DeployHash; pub use deploy_header::DeployHeader; pub use deploy_id::DeployId; pub use error::{ - DecodeFromJsonError as DeployDecodeFromJsonError, DeployConfigFailure, Error as DeployError, - ExcessiveSizeError as DeployExcessiveSizeError, + DecodeFromJsonError as DeployDecodeFromJsonError, Error as DeployError, + ExcessiveSizeError as DeployExcessiveSizeError, InvalidDeploy, }; pub use executable_deploy_item::{ ExecutableDeployItem, ExecutableDeployItemIdentifier, TransferTarget, @@ -148,7 +151,7 @@ pub struct Deploy { data_size(skip) )] #[cfg(any(feature = "once_cell", test))] - is_valid: OnceCell>, + is_valid: OnceCell>, } impl Deploy { @@ -330,13 +333,13 @@ impl Deploy { /// Returns `Ok` if and only if this `Deploy`'s body hashes to the value of `body_hash()`, and /// if this `Deploy`'s header hashes to the value claimed as the deploy hash. - pub fn has_valid_hash(&self) -> Result<(), DeployConfigFailure> { + pub fn has_valid_hash(&self) -> Result<(), InvalidDeploy> { let serialized_body = serialize_body(&self.payment, &self.session); let body_hash = Digest::hash(serialized_body); if body_hash != *self.header.body_hash() { #[cfg(any(all(feature = "std", feature = "testing"), test))] warn!(?self, ?body_hash, "invalid deploy body hash"); - return Err(DeployConfigFailure::InvalidBodyHash); + return Err(InvalidDeploy::InvalidBodyHash); } let serialized_header = serialize_header(&self.header); @@ -344,7 +347,7 @@ impl Deploy { if hash != self.hash { #[cfg(any(all(feature = "std", feature = "testing"), test))] warn!(?self, ?hash, "invalid deploy hash"); - return Err(DeployConfigFailure::InvalidDeployHash); + return Err(InvalidDeploy::InvalidDeployHash); } Ok(()) } @@ -354,7 +357,7 @@ impl Deploy { /// * the body hash is correct (should be the hash of the body), and /// * approvals are non empty, and /// * all approvals are valid signatures of the deploy hash - pub fn is_valid(&self) -> Result<(), DeployConfigFailure> { + pub fn is_valid(&self) -> Result<(), InvalidDeploy> { #[cfg(any(feature = "once_cell", test))] return self.is_valid.get_or_init(|| validate_deploy(self)).clone(); @@ -367,40 +370,6 @@ impl Deploy { self.session.is_transfer() } - /// Gas limit. - #[cfg(any(feature = "std", test))] - pub fn gas_limit( - &self, - system_costs: &SystemConfig, - gas_price: Option, - ) -> Result { - let user_specified_price = self.gas_price(); - let actual_price = match gas_price { - Some(price) => price.max(user_specified_price), - None => user_specified_price, - }; - let motes = { - if self.is_transfer() { - Motes::new(U512::from(system_costs.mint_costs().transfer)) - } else { - let value = self - .payment() - .args() - .get(ARG_AMOUNT) - .ok_or(DeployConfigFailure::MissingPaymentAmount)?; - let payment_amount = value - .clone() - .into_t::() - .map_err(|_| DeployConfigFailure::FailedToParsePaymentAmount)?; - Motes::new(payment_amount) - } - }; - match Gas::from_motes(motes, actual_price) { - Some(gas) => Ok(gas), - None => Err(DeployConfigFailure::MissingPaymentAmount), - } - } - /// Returns `Ok` if and only if: /// * the chain_name is correct, /// * the configured parameters are complied with at the given timestamp @@ -413,7 +382,7 @@ impl Deploy { max_associated_keys: u32, timestamp_leeway: TimeDiff, at: Timestamp, - ) -> Result<(), DeployConfigFailure> { + ) -> Result<(), InvalidDeploy> { self.is_valid_size(config.max_transaction_size)?; let header = self.header(); @@ -424,7 +393,7 @@ impl Deploy { chain_name = %header.chain_name(), "invalid chain identifier" ); - return Err(DeployConfigFailure::InvalidChainName { + return Err(InvalidDeploy::InvalidChainName { expected: chain_name.to_string(), got: header.chain_name().to_string(), }); @@ -439,7 +408,7 @@ impl Deploy { max_associated_keys = %max_associated_keys, "number of associated keys exceeds the maximum limit" ); - return Err(DeployConfigFailure::ExcessiveApprovals { + return Err(InvalidDeploy::ExcessiveApprovals { got: self.approvals.len() as u32, max_associated_keys, }); @@ -453,7 +422,7 @@ impl Deploy { %block_gas_limit, "transaction gas limit exceeds block gas limit" ); - return Err(DeployConfigFailure::ExceededBlockGasLimit { + return Err(InvalidDeploy::ExceededBlockGasLimit { block_gas_limit: config.block_gas_limit, got: Box::new(gas_limit.value()), }); @@ -466,7 +435,7 @@ impl Deploy { payment_args_max_length = config.deploy_config.payment_args_max_length, "payment args excessive" ); - return Err(DeployConfigFailure::ExcessivePaymentArgsLength { + return Err(InvalidDeploy::ExcessivePaymentArgsLength { max_length: config.deploy_config.payment_args_max_length as usize, got: payment_args_length, }); @@ -479,7 +448,7 @@ impl Deploy { session_args_max_length = config.deploy_config.session_args_max_length, "session args excessive" ); - return Err(DeployConfigFailure::ExcessiveSessionArgsLength { + return Err(InvalidDeploy::ExcessiveSessionArgsLength { max_length: config.deploy_config.session_args_max_length as usize, got: session_args_length, }); @@ -492,13 +461,13 @@ impl Deploy { .get(ARG_AMOUNT) .ok_or_else(|| { debug!("missing transfer 'amount' runtime argument"); - DeployConfigFailure::MissingTransferAmount + InvalidDeploy::MissingTransferAmount })? .clone() .into_t::() .map_err(|_| { debug!("failed to parse transfer 'amount' runtime argument as a U512"); - DeployConfigFailure::FailedToParseTransferAmount + InvalidDeploy::FailedToParseTransferAmount })?; let minimum = U512::from(config.native_transfer_minimum_motes); if attempted < minimum { @@ -507,7 +476,7 @@ impl Deploy { amount = %attempted, "insufficient transfer amount" ); - return Err(DeployConfigFailure::InsufficientTransferAmount { + return Err(InvalidDeploy::InsufficientTransferAmount { minimum: Box::new(minimum), attempted: Box::new(attempted), }); @@ -1116,6 +1085,53 @@ impl Deploy { } } +impl Categorized for Deploy { + fn category(&self) -> TransactionCategory { + if self.is_transfer() { + TransactionCategory::Mint + } else { + TransactionCategory::Standard + } + } +} + +#[cfg(any(feature = "std", test))] +impl GasLimited for Deploy { + type Error = InvalidDeploy; + + fn gas_limit( + &self, + system_costs: &SystemConfig, + gas_price: Option, + ) -> Result { + let user_specified_price = self.gas_price(); + let actual_price = match gas_price { + Some(price) => price.max(user_specified_price), + None => user_specified_price, + }; + let motes = { + if self.is_transfer() { + Motes::new(U512::from(system_costs.mint_costs().transfer)) + } else { + let value = self + .payment() + .args() + .get(ARG_AMOUNT) + .ok_or(InvalidDeploy::MissingPaymentAmount)?; + let payment_amount = value + .clone() + .into_t::() + .map_err(|_| InvalidDeploy::FailedToParsePaymentAmount)?; + Motes::new(payment_amount) + } + }; + match Gas::from_motes(motes, actual_price) { + Some(gas) => Ok(gas), + None => Err(InvalidDeploy::MissingPaymentAmount), + } + } +} + impl hash::Hash for Deploy { fn hash(&self, state: &mut H) { // Destructure to make sure we don't accidentally omit fields. @@ -1283,11 +1299,11 @@ fn serialize_body(payment: &ExecutableDeployItem, session: &ExecutableDeployItem /// Computationally expensive validity check for a given deploy instance, including asymmetric_key /// signing verification. -fn validate_deploy(deploy: &Deploy) -> Result<(), DeployConfigFailure> { +fn validate_deploy(deploy: &Deploy) -> Result<(), InvalidDeploy> { if deploy.approvals.is_empty() { #[cfg(any(all(feature = "std", feature = "testing"), test))] warn!(?deploy, "deploy has no approvals"); - return Err(DeployConfigFailure::EmptyApprovals); + return Err(InvalidDeploy::EmptyApprovals); } deploy.has_valid_hash()?; @@ -1296,7 +1312,7 @@ fn validate_deploy(deploy: &Deploy) -> Result<(), DeployConfigFailure> { if let Err(error) = crypto::verify(deploy.hash, approval.signature(), approval.signer()) { #[cfg(any(all(feature = "std", feature = "testing"), test))] warn!(?deploy, "failed to verify approval {}: {}", index, error); - return Err(DeployConfigFailure::InvalidApproval { index, error }); + return Err(InvalidDeploy::InvalidApproval { index, error }); } } @@ -1390,7 +1406,7 @@ mod tests { ); } - fn check_is_not_valid(invalid_deploy: Deploy, expected_error: DeployConfigFailure) { + fn check_is_not_valid(invalid_deploy: Deploy, expected_error: InvalidDeploy) { assert!( invalid_deploy.is_valid.get().is_none(), "is valid should initially be None" @@ -1401,11 +1417,11 @@ mod tests { // this makes the test too fragile. Otherwise expect the actual error should exactly match // the expected error. match expected_error { - DeployConfigFailure::InvalidApproval { + InvalidDeploy::InvalidApproval { index: expected_index, .. } => match actual_error { - DeployConfigFailure::InvalidApproval { + InvalidDeploy::InvalidApproval { index: actual_index, .. } => { @@ -1436,7 +1452,7 @@ mod tests { "amount" => 1 }, }; - check_is_not_valid(deploy, DeployConfigFailure::InvalidBodyHash); + check_is_not_valid(deploy, InvalidDeploy::InvalidBodyHash); } #[test] @@ -1446,7 +1462,7 @@ mod tests { // deploy.header.gas_price = 2; deploy.invalidate(); - check_is_not_valid(deploy, DeployConfigFailure::InvalidDeployHash); + check_is_not_valid(deploy, InvalidDeploy::InvalidDeployHash); } #[test] @@ -1455,7 +1471,7 @@ mod tests { let mut deploy = create_deploy(&mut rng, TransactionConfig::default().max_ttl, 0, "net-1"); deploy.approvals = BTreeSet::new(); assert!(deploy.approvals.is_empty()); - check_is_not_valid(deploy, DeployConfigFailure::EmptyApprovals) + check_is_not_valid(deploy, InvalidDeploy::EmptyApprovals) } #[test] @@ -1477,7 +1493,7 @@ mod tests { .unwrap(); check_is_not_valid( deploy, - DeployConfigFailure::InvalidApproval { + InvalidDeploy::InvalidApproval { index: expected_index, error: crypto::Error::SignatureError, // This field is ignored in the check. }, @@ -1525,7 +1541,7 @@ mod tests { &wrong_chain_name, ); - let expected_error = DeployConfigFailure::InvalidChainName { + let expected_error = InvalidDeploy::InvalidChainName { expected: expected_chain_name.to_string(), got: wrong_chain_name, }; @@ -1559,7 +1575,7 @@ mod tests { let deploy = create_deploy(&mut rng, config.max_ttl, dependency_count, chain_name); - let expected_error = DeployConfigFailure::DependenciesNoLongerSupported; + let expected_error = InvalidDeploy::DependenciesNoLongerSupported; let current_timestamp = deploy.header().timestamp(); assert_eq!( @@ -1595,7 +1611,7 @@ mod tests { chain_name, ); - let expected_error = DeployConfigFailure::ExcessiveTimeToLive { + let expected_error = InvalidDeploy::ExcessiveTimeToLive { max_ttl: config.max_ttl, got: ttl, }; @@ -1634,7 +1650,7 @@ mod tests { ); let current_timestamp = deploy.header.timestamp() - leeway - TimeDiff::from_seconds(1); - let expected_error = DeployConfigFailure::TimestampInFuture { + let expected_error = InvalidDeploy::TimestampInFuture { validation_timestamp: current_timestamp, timestamp_leeway: leeway, got: deploy.header.timestamp(), @@ -1724,7 +1740,7 @@ mod tests { TimeDiff::default(), current_timestamp ), - Err(DeployConfigFailure::MissingPaymentAmount) + Err(InvalidDeploy::MissingPaymentAmount) ); assert!( deploy.is_valid.get().is_none(), @@ -1774,7 +1790,7 @@ mod tests { TimeDiff::default(), current_timestamp ), - Err(DeployConfigFailure::FailedToParsePaymentAmount) + Err(InvalidDeploy::FailedToParsePaymentAmount) ); assert!( deploy.is_valid.get().is_none(), @@ -1815,7 +1831,7 @@ mod tests { deploy.payment = payment; deploy.session = session; - let expected_error = DeployConfigFailure::ExceededBlockGasLimit { + let expected_error = InvalidDeploy::ExceededBlockGasLimit { block_gas_limit: config.block_gas_limit, got: Box::new(amount), }; @@ -1907,7 +1923,7 @@ mod tests { let max_associated_keys = (deploy.approvals.len() - 1) as u32; let current_timestamp = deploy.header().timestamp(); assert_eq!( - Err(DeployConfigFailure::ExcessiveApprovals { + Err(InvalidDeploy::ExcessiveApprovals { got: deploy.approvals.len() as u32, max_associated_keys: (deploy.approvals.len() - 1) as u32 }), @@ -1943,7 +1959,7 @@ mod tests { let current_timestamp = deploy.header().timestamp(); assert_eq!( - Err(DeployConfigFailure::MissingTransferAmount), + Err(InvalidDeploy::MissingTransferAmount), deploy.is_config_compliant( chain_name, &cost_table, @@ -1980,7 +1996,7 @@ mod tests { let current_timestamp = deploy.header().timestamp(); assert_eq!( - Err(DeployConfigFailure::FailedToParseTransferAmount), + Err(InvalidDeploy::FailedToParseTransferAmount), deploy.is_config_compliant( chain_name, &cost_table, @@ -2020,7 +2036,7 @@ mod tests { let current_timestamp = deploy.header().timestamp(); assert_eq!( - Err(DeployConfigFailure::InsufficientTransferAmount { + Err(InvalidDeploy::InsufficientTransferAmount { minimum: Box::new(U512::from(config.native_transfer_minimum_motes)), attempted: Box::new(insufficient_amount), }), diff --git a/types/src/transaction/deploy/deploy_header.rs b/types/src/transaction/deploy/deploy_header.rs index 5c78e4e964..9e15a3a777 100644 --- a/types/src/transaction/deploy/deploy_header.rs +++ b/types/src/transaction/deploy/deploy_header.rs @@ -18,7 +18,7 @@ use crate::{ Digest, DisplayIter, PublicKey, TimeDiff, Timestamp, }; #[cfg(any(feature = "std", test))] -use crate::{DeployConfigFailure, TransactionConfig}; +use crate::{InvalidDeploy, TransactionConfig}; /// The header portion of a [`Deploy`]. #[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)] @@ -112,7 +112,7 @@ impl DeployHeader { timestamp_leeway: TimeDiff, at: Timestamp, deploy_hash: &DeployHash, - ) -> Result<(), DeployConfigFailure> { + ) -> Result<(), InvalidDeploy> { // as of 2.0.0 deploy dependencies are not supported. // a legacy deploy citing dependencies should be rejected if !self.dependencies.is_empty() { @@ -120,7 +120,7 @@ impl DeployHeader { %deploy_hash, "deploy dependencies no longer supported" ); - return Err(DeployConfigFailure::DependenciesNoLongerSupported); + return Err(InvalidDeploy::DependenciesNoLongerSupported); } if self.ttl() > config.max_ttl { @@ -130,7 +130,7 @@ impl DeployHeader { max_ttl = %config.max_ttl, "deploy ttl excessive" ); - return Err(DeployConfigFailure::ExcessiveTimeToLive { + return Err(InvalidDeploy::ExcessiveTimeToLive { max_ttl: config.max_ttl, got: self.ttl(), }); @@ -138,7 +138,7 @@ impl DeployHeader { if self.timestamp() > at + timestamp_leeway { debug!(%deploy_hash, deploy_header = %self, %at, "deploy timestamp in the future"); - return Err(DeployConfigFailure::TimestampInFuture { + return Err(InvalidDeploy::TimestampInFuture { validation_timestamp: at, timestamp_leeway, got: self.timestamp(), diff --git a/types/src/transaction/deploy/error.rs b/types/src/transaction/deploy/error.rs index c00467cdd1..be11b024ef 100644 --- a/types/src/transaction/deploy/error.rs +++ b/types/src/transaction/deploy/error.rs @@ -17,7 +17,7 @@ use crate::{crypto, TimeDiff, Timestamp, U512}; #[cfg_attr(feature = "std", derive(Serialize))] #[cfg_attr(feature = "datasize", derive(DataSize))] #[non_exhaustive] -pub enum DeployConfigFailure { +pub enum InvalidDeploy { /// Invalid chain name. InvalidChainName { /// The expected chain name. @@ -120,30 +120,30 @@ pub enum DeployConfigFailure { }, } -impl Display for DeployConfigFailure { +impl Display for InvalidDeploy { fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { match self { - DeployConfigFailure::InvalidChainName { expected, got } => { + InvalidDeploy::InvalidChainName { expected, got } => { write!( formatter, "invalid chain name: expected {}, got {}", expected, got ) } - DeployConfigFailure::DependenciesNoLongerSupported => { + InvalidDeploy::DependenciesNoLongerSupported => { write!(formatter, "dependencies no longer supported",) } - DeployConfigFailure::ExcessiveSize(error) => { + InvalidDeploy::ExcessiveSize(error) => { write!(formatter, "deploy size too large: {}", error) } - DeployConfigFailure::ExcessiveTimeToLive { max_ttl, got } => { + InvalidDeploy::ExcessiveTimeToLive { max_ttl, got } => { write!( formatter, "time-to-live of {} exceeds limit of {}", got, max_ttl ) } - DeployConfigFailure::TimestampInFuture { + InvalidDeploy::TimestampInFuture { validation_timestamp, timestamp_leeway, got, @@ -154,49 +154,49 @@ impl Display for DeployConfigFailure { got, validation_timestamp, timestamp_leeway ) } - DeployConfigFailure::InvalidBodyHash => { + InvalidDeploy::InvalidBodyHash => { write!( formatter, "the provided body hash does not match the actual hash of the body" ) } - DeployConfigFailure::InvalidDeployHash => { + InvalidDeploy::InvalidDeployHash => { write!( formatter, "the provided hash does not match the actual hash of the deploy" ) } - DeployConfigFailure::EmptyApprovals => { + InvalidDeploy::EmptyApprovals => { write!(formatter, "the deploy has no approvals") } - DeployConfigFailure::InvalidApproval { index, error } => { + InvalidDeploy::InvalidApproval { index, error } => { write!( formatter, "the approval at index {} is invalid: {}", index, error ) } - DeployConfigFailure::ExcessiveSessionArgsLength { max_length, got } => { + InvalidDeploy::ExcessiveSessionArgsLength { max_length, got } => { write!( formatter, "serialized session code runtime args of {} exceeds limit of {}", got, max_length ) } - DeployConfigFailure::ExcessivePaymentArgsLength { max_length, got } => { + InvalidDeploy::ExcessivePaymentArgsLength { max_length, got } => { write!( formatter, "serialized payment code runtime args of {} exceeds limit of {}", got, max_length ) } - DeployConfigFailure::MissingPaymentAmount => { + InvalidDeploy::MissingPaymentAmount => { write!(formatter, "missing payment 'amount' runtime argument") } - DeployConfigFailure::FailedToParsePaymentAmount => { + InvalidDeploy::FailedToParsePaymentAmount => { write!(formatter, "failed to parse payment 'amount' as U512") } - DeployConfigFailure::ExceededBlockGasLimit { + InvalidDeploy::ExceededBlockGasLimit { block_gas_limit, got, } => { @@ -206,20 +206,20 @@ impl Display for DeployConfigFailure { got, block_gas_limit ) } - DeployConfigFailure::MissingTransferAmount => { + InvalidDeploy::MissingTransferAmount => { write!(formatter, "missing transfer 'amount' runtime argument") } - DeployConfigFailure::FailedToParseTransferAmount => { + InvalidDeploy::FailedToParseTransferAmount => { write!(formatter, "failed to parse transfer 'amount' as U512") } - DeployConfigFailure::InsufficientTransferAmount { minimum, attempted } => { + InvalidDeploy::InsufficientTransferAmount { minimum, attempted } => { write!( formatter, "insufficient transfer amount; minimum: {} attempted: {}", minimum, attempted ) } - DeployConfigFailure::ExcessiveApprovals { + InvalidDeploy::ExcessiveApprovals { got, max_associated_keys, } => { @@ -233,34 +233,34 @@ impl Display for DeployConfigFailure { } } -impl From for DeployConfigFailure { +impl From for InvalidDeploy { fn from(error: ExcessiveSizeError) -> Self { - DeployConfigFailure::ExcessiveSize(error) + InvalidDeploy::ExcessiveSize(error) } } #[cfg(feature = "std")] -impl StdError for DeployConfigFailure { +impl StdError for InvalidDeploy { fn source(&self) -> Option<&(dyn StdError + 'static)> { match self { - DeployConfigFailure::InvalidApproval { error, .. } => Some(error), - DeployConfigFailure::InvalidChainName { .. } - | DeployConfigFailure::DependenciesNoLongerSupported { .. } - | DeployConfigFailure::ExcessiveSize(_) - | DeployConfigFailure::ExcessiveTimeToLive { .. } - | DeployConfigFailure::TimestampInFuture { .. } - | DeployConfigFailure::InvalidBodyHash - | DeployConfigFailure::InvalidDeployHash - | DeployConfigFailure::EmptyApprovals - | DeployConfigFailure::ExcessiveSessionArgsLength { .. } - | DeployConfigFailure::ExcessivePaymentArgsLength { .. } - | DeployConfigFailure::MissingPaymentAmount - | DeployConfigFailure::FailedToParsePaymentAmount - | DeployConfigFailure::ExceededBlockGasLimit { .. } - | DeployConfigFailure::MissingTransferAmount - | DeployConfigFailure::FailedToParseTransferAmount - | DeployConfigFailure::InsufficientTransferAmount { .. } - | DeployConfigFailure::ExcessiveApprovals { .. } => None, + InvalidDeploy::InvalidApproval { error, .. } => Some(error), + InvalidDeploy::InvalidChainName { .. } + | InvalidDeploy::DependenciesNoLongerSupported { .. } + | InvalidDeploy::ExcessiveSize(_) + | InvalidDeploy::ExcessiveTimeToLive { .. } + | InvalidDeploy::TimestampInFuture { .. } + | InvalidDeploy::InvalidBodyHash + | InvalidDeploy::InvalidDeployHash + | InvalidDeploy::EmptyApprovals + | InvalidDeploy::ExcessiveSessionArgsLength { .. } + | InvalidDeploy::ExcessivePaymentArgsLength { .. } + | InvalidDeploy::MissingPaymentAmount + | InvalidDeploy::FailedToParsePaymentAmount + | InvalidDeploy::ExceededBlockGasLimit { .. } + | InvalidDeploy::MissingTransferAmount + | InvalidDeploy::FailedToParseTransferAmount + | InvalidDeploy::InsufficientTransferAmount { .. } + | InvalidDeploy::ExcessiveApprovals { .. } => None, } } } diff --git a/types/src/transaction/error.rs b/types/src/transaction/error.rs new file mode 100644 index 0000000000..5d4e8cc32e --- /dev/null +++ b/types/src/transaction/error.rs @@ -0,0 +1,54 @@ +use crate::InvalidDeploy; +use core::fmt::{Display, Formatter}; +#[cfg(feature = "datasize")] +use datasize::DataSize; + +#[cfg(feature = "std")] +use serde::Serialize; +#[cfg(feature = "std")] +use std::error::Error as StdError; + +pub use crate::transaction::transaction_v1::InvalidTransactionV1; + +/// A representation of the way in which a transaction failed validation checks. +#[derive(Clone, Eq, PartialEq, Debug)] +#[cfg_attr(feature = "std", derive(Serialize))] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[non_exhaustive] +pub enum InvalidTransaction { + /// Legacy deploys. + Deploy(InvalidDeploy), + /// V1 transactions. + V1(InvalidTransactionV1), +} + +impl From for InvalidTransaction { + fn from(value: InvalidDeploy) -> Self { + Self::Deploy(value) + } +} + +impl From for InvalidTransaction { + fn from(value: InvalidTransactionV1) -> Self { + Self::V1(value) + } +} + +#[cfg(feature = "std")] +impl StdError for InvalidTransaction { + fn source(&self) -> Option<&(dyn StdError + 'static)> { + match self { + InvalidTransaction::Deploy(deploy) => deploy.source(), + InvalidTransaction::V1(v1) => v1.source(), + } + } +} + +impl Display for InvalidTransaction { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + match self { + InvalidTransaction::Deploy(inner) => Display::fmt(inner, f), + InvalidTransaction::V1(inner) => Display::fmt(inner, f), + } + } +} diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index cd9c3fcc81..c468250c65 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -25,19 +25,16 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use tracing::debug; -#[cfg(any(feature = "std", test))] -use super::InitiatorAddrAndSecretKey; use super::{ - Approval, ApprovalsHash, InitiatorAddr, PricingMode, TransactionEntryPoint, + Approval, ApprovalsHash, Categorized, InitiatorAddr, PricingMode, TransactionEntryPoint, TransactionScheduling, TransactionTarget, }; +#[cfg(any(feature = "std", test))] +use super::{GasLimited, InitiatorAddrAndSecretKey}; #[cfg(any(all(feature = "std", feature = "testing"), test))] use crate::testing::TestRng; #[cfg(any(feature = "std", test))] -use crate::{Gas, Motes, TransactionConfig, U512}; - -#[cfg(any(feature = "std", test))] -use crate::SystemConfig; +use crate::{Gas, Motes, SystemConfig, TransactionConfig, U512}; use crate::{ bytesrepr::{self, FromBytes, ToBytes}, @@ -46,7 +43,8 @@ use crate::{ }; pub use errors_v1::{ DecodeFromJsonErrorV1 as TransactionV1DecodeFromJsonError, ErrorV1 as TransactionV1Error, - ExcessiveSizeErrorV1 as TransactionV1ExcessiveSizeError, TransactionV1ConfigFailure, + ExcessiveSizeErrorV1 as TransactionV1ExcessiveSizeError, + InvalidTransaction as InvalidTransactionV1, }; pub use transaction_v1_body::TransactionV1Body; #[cfg(any(feature = "std", test))] @@ -85,7 +83,7 @@ pub struct TransactionV1 { data_size(skip) )] #[cfg(any(feature = "once_cell", test))] - is_verified: OnceCell>, + is_verified: OnceCell>, } impl TransactionV1 { @@ -221,66 +219,6 @@ impl TransactionV1 { self.body().is_standard() } - /// Returns the gas limit for this transaction. - #[cfg(any(feature = "std", test))] - pub fn gas_limit(&self, costs: &SystemConfig, gas_price: Option) -> Option { - match self.header().pricing_mode() { - PricingMode::Classic { - payment_amount, - gas_price: user_specified_price, - } => { - let actual_price = match gas_price { - Some(system_specified_price) => { - // take the higher of the two possible prices - (*user_specified_price).max(system_specified_price) - } - None => *user_specified_price, - }; - let motes = Motes::new(U512::from(*payment_amount)); - Gas::from_motes(motes, actual_price) - } - PricingMode::Fixed { .. } => { - // if gas price is not provided, assume price == 1 - let gas_price = gas_price.unwrap_or(1); - let cost = { - if self.is_native_mint() { - // Because we currently only support one native mint interaction, - // native transfer, we can short circuit to return that value. - // However if other direct mint interactions are supported - // in the future (such as the upcoming burn feature), - // this logic will need to be expanded to self.mint_costs().field? - // for the value for each verb...see how auction is set up below. - costs.mint_costs().transfer - } else if self.is_native_auction() { - match self.body().entry_point() { - TransactionEntryPoint::Custom(_) | TransactionEntryPoint::Transfer => { - unreachable!("this must be programmer error"); - } - TransactionEntryPoint::AddBid | TransactionEntryPoint::ActivateBid => { - costs.auction_costs().add_bid - } - TransactionEntryPoint::WithdrawBid => { - costs.auction_costs().withdraw_bid - } - TransactionEntryPoint::Delegate => costs.auction_costs().delegate, - TransactionEntryPoint::Undelegate => costs.auction_costs().undelegate, - TransactionEntryPoint::Redelegate => costs.auction_costs().redelegate, - } - } else if self.is_install_or_upgrade() { - costs.install_upgrade_limit() - } else { - costs.standard_transaction_limit() - } - }; - Gas::from_motes(Motes::new(U512::from(cost)), gas_price) - } - PricingMode::Reserved { paid_amount, .. } => { - // prepaid, if receipt is legit (future use, not currently implemented) - Gas::from_motes(Motes::new(U512::from(paid_amount)), 1) - } - } - } - /// Returns the approvals for this transaction. pub fn approvals(&self) -> &BTreeSet { &self.approvals @@ -316,7 +254,7 @@ impl TransactionV1 { /// Returns `Ok` if and only if this transaction's body hashes to the value of `body_hash()`, /// and if this transaction's header hashes to the value claimed as the transaction hash. - pub fn has_valid_hash(&self) -> Result<(), TransactionV1ConfigFailure> { + pub fn has_valid_hash(&self) -> Result<(), InvalidTransactionV1> { let body_hash = Digest::hash( self.body .to_bytes() @@ -324,7 +262,7 @@ impl TransactionV1 { ); if body_hash != *self.header.body_hash() { debug!(?self, ?body_hash, "invalid transaction body hash"); - return Err(TransactionV1ConfigFailure::InvalidBodyHash); + return Err(InvalidTransactionV1::InvalidBodyHash); } let hash = TransactionV1Hash::new(Digest::hash( @@ -334,7 +272,7 @@ impl TransactionV1 { )); if hash != self.hash { debug!(?self, ?hash, "invalid transaction hash"); - return Err(TransactionV1ConfigFailure::InvalidTransactionHash); + return Err(InvalidTransactionV1::InvalidTransactionHash); } Ok(()) } @@ -343,7 +281,7 @@ impl TransactionV1 { /// * the transaction hash is correct (see [`TransactionV1::has_valid_hash`] for details) /// * approvals are non empty, and /// * all approvals are valid signatures of the signed hash - pub fn verify(&self) -> Result<(), TransactionV1ConfigFailure> { + pub fn verify(&self) -> Result<(), InvalidTransactionV1> { #[cfg(any(feature = "once_cell", test))] return self.is_verified.get_or_init(|| self.do_verify()).clone(); @@ -351,10 +289,10 @@ impl TransactionV1 { self.do_verify() } - fn do_verify(&self) -> Result<(), TransactionV1ConfigFailure> { + fn do_verify(&self) -> Result<(), InvalidTransactionV1> { if self.approvals.is_empty() { debug!(?self, "transaction has no approvals"); - return Err(TransactionV1ConfigFailure::EmptyApprovals); + return Err(InvalidTransactionV1::EmptyApprovals); } self.has_valid_hash()?; @@ -365,7 +303,7 @@ impl TransactionV1 { ?self, "failed to verify transaction approval {}: {}", index, error ); - return Err(TransactionV1ConfigFailure::InvalidApproval { index, error }); + return Err(InvalidTransactionV1::InvalidApproval { index, error }); } } @@ -384,7 +322,7 @@ impl TransactionV1 { max_associated_keys: u32, timestamp_leeway: TimeDiff, at: Timestamp, - ) -> Result<(), TransactionV1ConfigFailure> { + ) -> Result<(), InvalidTransactionV1> { self.is_valid_size(transaction_config.max_transaction_size)?; let header = self.header(); @@ -395,7 +333,7 @@ impl TransactionV1 { chain_name = %header.chain_name(), "invalid chain identifier" ); - return Err(TransactionV1ConfigFailure::InvalidChainName { + return Err(InvalidTransactionV1::InvalidChainName { expected: chain_name.to_string(), got: header.chain_name().to_string(), }); @@ -410,25 +348,24 @@ impl TransactionV1 { max_associated_keys = %max_associated_keys, "number of transaction approvals exceeds the limit" ); - return Err(TransactionV1ConfigFailure::ExcessiveApprovals { + return Err(InvalidTransactionV1::ExcessiveApprovals { got: self.approvals.len() as u32, max_associated_keys, }); } - if let Some(gas_limit) = self.gas_limit(cost_table, None) { - let block_gas_limit = Gas::new(U512::from(transaction_config.block_gas_limit)); - if gas_limit > block_gas_limit { - debug!( - amount = %gas_limit, - %block_gas_limit, - "transaction gas limit exceeds block gas limit" - ); - return Err(TransactionV1ConfigFailure::ExceedsBlockGasLimit { - block_gas_limit: transaction_config.block_gas_limit, - got: Box::new(gas_limit.value()), - }); - } + let gas_limit = self.gas_limit(cost_table, None)?; + let block_gas_limit = Gas::new(U512::from(transaction_config.block_gas_limit)); + if gas_limit > block_gas_limit { + debug!( + amount = %gas_limit, + %block_gas_limit, + "transaction gas limit exceeds block gas limit" + ); + return Err(InvalidTransactionV1::ExceedsBlockGasLimit { + block_gas_limit: transaction_config.block_gas_limit, + got: Box::new(gas_limit.value()), + }); } self.body.is_valid(transaction_config) @@ -592,6 +529,104 @@ impl TransactionV1 { } } +impl Categorized for TransactionV1 { + fn category(&self) -> TransactionCategory { + if self.is_native_mint() { + TransactionCategory::Mint + } else if self.is_native_auction() { + TransactionCategory::Auction + } else if self.is_install_or_upgrade() { + TransactionCategory::InstallUpgrade + } else { + TransactionCategory::Standard + } + } +} + +#[cfg(any(feature = "std", test))] +impl GasLimited for TransactionV1 { + type Error = InvalidTransactionV1; + + fn gas_limit(&self, costs: &SystemConfig, gas_price: Option) -> Result { + let gas = match self.header().pricing_mode() { + PricingMode::Classic { + payment_amount, + gas_price: user_specified_price, + } => { + let actual_price = match gas_price { + Some(system_specified_price) => { + // take the higher of the two possible prices + (*user_specified_price).max(system_specified_price) + } + None => *user_specified_price, + }; + let motes = Motes::new(U512::from(*payment_amount)); + Gas::from_motes(motes, actual_price).ok_or( + InvalidTransactionV1::GasPriceConversion { + amount: *payment_amount, + gas_price: actual_price, + }, + )? + } + PricingMode::Fixed { .. } => { + // if gas price is not provided, assume price == 1 + let gas_price = gas_price.unwrap_or(1); + let cost = { + if self.is_native_mint() { + // Because we currently only support one native mint interaction, + // native transfer, we can short circuit to return that value. + // However if other direct mint interactions are supported + // in the future (such as the upcoming burn feature), + // this logic will need to be expanded to self.mint_costs().field? + // for the value for each verb...see how auction is set up below. + costs.mint_costs().transfer + } else if self.is_native_auction() { + let entry_point = self.body().entry_point(); + match entry_point { + TransactionEntryPoint::Custom(_) | TransactionEntryPoint::Transfer => { + return Err(InvalidTransactionV1::EntryPointCannotBeCustom { + entry_point: entry_point.clone(), + }) + } + TransactionEntryPoint::AddBid | TransactionEntryPoint::ActivateBid => { + costs.auction_costs().add_bid + } + TransactionEntryPoint::WithdrawBid => { + costs.auction_costs().withdraw_bid + } + TransactionEntryPoint::Delegate => costs.auction_costs().delegate, + TransactionEntryPoint::Undelegate => costs.auction_costs().undelegate, + TransactionEntryPoint::Redelegate => costs.auction_costs().redelegate, + } + } else if self.is_install_or_upgrade() { + costs.install_upgrade_limit() + } else { + costs.standard_transaction_limit() + } + }; + let fixed_cost = U512::from(cost); + Gas::from_motes(Motes::new(fixed_cost), gas_price).ok_or( + InvalidTransactionV1::GasPriceConversion { + amount: fixed_cost.as_u64(), + gas_price, + }, + )? + } + PricingMode::Reserved { paid_amount, .. } => { + let actual_price = 1; + // prepaid, if receipt is legit (future use, not currently implemented) + Gas::from_motes(Motes::new(*paid_amount), actual_price).ok_or( + InvalidTransactionV1::GasPriceConversion { + amount: paid_amount.as_u64(), + gas_price: actual_price, + }, + )? + } + }; + Ok(gas) + } +} + impl hash::Hash for TransactionV1 { fn hash(&self, state: &mut H) { // Destructure to make sure we don't accidentally omit fields. @@ -757,7 +792,7 @@ mod tests { fn check_is_not_valid( invalid_transaction: TransactionV1, - expected_error: TransactionV1ConfigFailure, + expected_error: InvalidTransactionV1, ) { assert!( invalid_transaction.is_verified.get().is_none(), @@ -769,11 +804,11 @@ mod tests { // this makes the test too fragile. Otherwise expect the actual error should exactly match // the expected error. match expected_error { - TransactionV1ConfigFailure::InvalidApproval { + InvalidTransactionV1::InvalidApproval { index: expected_index, .. } => match actual_error { - TransactionV1ConfigFailure::InvalidApproval { + InvalidTransactionV1::InvalidApproval { index: actual_index, .. } => { @@ -800,10 +835,7 @@ mod tests { let mut transaction = TransactionV1::random(rng); transaction.invalidate(); - check_is_not_valid( - transaction, - TransactionV1ConfigFailure::InvalidTransactionHash, - ); + check_is_not_valid(transaction, InvalidTransactionV1::InvalidTransactionHash); } #[test] @@ -814,7 +846,7 @@ mod tests { .build() .unwrap(); assert!(transaction.approvals.is_empty()); - check_is_not_valid(transaction, TransactionV1ConfigFailure::EmptyApprovals) + check_is_not_valid(transaction, InvalidTransactionV1::EmptyApprovals) } #[test] @@ -840,7 +872,7 @@ mod tests { .unwrap(); check_is_not_valid( transaction, - TransactionV1ConfigFailure::InvalidApproval { + InvalidTransactionV1::InvalidApproval { index: expected_index, error: crypto::Error::SignatureError, // This field is ignored in the check. }, @@ -883,7 +915,7 @@ mod tests { .build() .unwrap(); - let expected_error = TransactionV1ConfigFailure::InvalidChainName { + let expected_error = InvalidTransactionV1::InvalidChainName { expected: expected_chain_name.to_string(), got: wrong_chain_name.to_string(), }; @@ -919,7 +951,7 @@ mod tests { .build() .unwrap(); - let expected_error = TransactionV1ConfigFailure::ExcessiveTimeToLive { + let expected_error = InvalidTransactionV1::ExcessiveTimeToLive { max_ttl: transaction_config.max_ttl, got: ttl, }; @@ -956,7 +988,7 @@ mod tests { .unwrap(); let current_timestamp = transaction.timestamp() - leeway - TimeDiff::from_seconds(1); - let expected_error = TransactionV1ConfigFailure::TimestampInFuture { + let expected_error = InvalidTransactionV1::TimestampInFuture { validation_timestamp: current_timestamp, timestamp_leeway: leeway, got: transaction.timestamp(), @@ -996,7 +1028,7 @@ mod tests { let current_timestamp = transaction.timestamp(); - let expected_error = TransactionV1ConfigFailure::ExcessiveApprovals { + let expected_error = InvalidTransactionV1::ExcessiveApprovals { got: MAX_ASSOCIATED_KEYS + 1, max_associated_keys: MAX_ASSOCIATED_KEYS, }; diff --git a/types/src/transaction/transaction_v1/errors_v1.rs b/types/src/transaction/transaction_v1/errors_v1.rs index 74f361f054..5b7f12a6c5 100644 --- a/types/src/transaction/transaction_v1/errors_v1.rs +++ b/types/src/transaction/transaction_v1/errors_v1.rs @@ -20,7 +20,7 @@ use crate::{crypto, CLType, TimeDiff, Timestamp, U512}; #[cfg_attr(feature = "std", derive(Serialize))] #[cfg_attr(feature = "datasize", derive(DataSize))] #[non_exhaustive] -pub enum TransactionV1ConfigFailure { +pub enum InvalidTransaction { /// Invalid chain name. InvalidChainName { /// The expected chain name. @@ -126,30 +126,36 @@ pub enum TransactionV1ConfigFailure { /// The invalid entry point. entry_point: TransactionEntryPoint, }, - /// The transaction has empty module bytes. EmptyModuleBytes, + /// Attempt to factor the amount over the gas_price failed. + GasPriceConversion { + /// The base amount. + amount: u64, + /// The attempted gas price. + gas_price: u64, + }, } -impl Display for TransactionV1ConfigFailure { +impl Display for InvalidTransaction { fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { match self { - TransactionV1ConfigFailure::InvalidChainName { expected, got } => { + InvalidTransaction::InvalidChainName { expected, got } => { write!( formatter, "invalid chain name: expected {expected}, got {got}" ) } - TransactionV1ConfigFailure::ExcessiveSize(error) => { + InvalidTransaction::ExcessiveSize(error) => { write!(formatter, "transaction size too large: {error}") } - TransactionV1ConfigFailure::ExcessiveTimeToLive { max_ttl, got } => { + InvalidTransaction::ExcessiveTimeToLive { max_ttl, got } => { write!( formatter, "time-to-live of {got} exceeds limit of {max_ttl}" ) } - TransactionV1ConfigFailure::TimestampInFuture { + InvalidTransaction::TimestampInFuture { validation_timestamp, timestamp_leeway, got, @@ -160,35 +166,35 @@ impl Display for TransactionV1ConfigFailure { {validation_timestamp} plus leeway of {timestamp_leeway}" ) } - TransactionV1ConfigFailure::InvalidBodyHash => { + InvalidTransaction::InvalidBodyHash => { write!( formatter, "the provided hash does not match the actual hash of the transaction body" ) } - TransactionV1ConfigFailure::InvalidTransactionHash => { + InvalidTransaction::InvalidTransactionHash => { write!( formatter, "the provided hash does not match the actual hash of the transaction" ) } - TransactionV1ConfigFailure::EmptyApprovals => { + InvalidTransaction::EmptyApprovals => { write!(formatter, "the transaction has no approvals") } - TransactionV1ConfigFailure::InvalidApproval { index, error } => { + InvalidTransaction::InvalidApproval { index, error } => { write!( formatter, "the transaction approval at index {index} is invalid: {error}" ) } - TransactionV1ConfigFailure::ExcessiveArgsLength { max_length, got } => { + InvalidTransaction::ExcessiveArgsLength { max_length, got } => { write!( formatter, "serialized transaction runtime args of {got} bytes exceeds limit of \ {max_length} bytes" ) } - TransactionV1ConfigFailure::ExcessiveApprovals { + InvalidTransaction::ExcessiveApprovals { max_associated_keys, got, } => { @@ -198,7 +204,7 @@ impl Display for TransactionV1ConfigFailure { associated keys {max_associated_keys}", ) } - TransactionV1ConfigFailure::ExceedsBlockGasLimit { + InvalidTransaction::ExceedsBlockGasLimit { block_gas_limit, got, } => { @@ -207,10 +213,10 @@ impl Display for TransactionV1ConfigFailure { "payment amount of {got} exceeds the block gas limit of {block_gas_limit}" ) } - TransactionV1ConfigFailure::MissingArg { arg_name } => { + InvalidTransaction::MissingArg { arg_name } => { write!(formatter, "missing required runtime argument '{arg_name}'") } - TransactionV1ConfigFailure::UnexpectedArgType { + InvalidTransaction::UnexpectedArgType { arg_name, expected, got, @@ -220,52 +226,60 @@ impl Display for TransactionV1ConfigFailure { "expected type of '{arg_name}' runtime argument to be {expected}, but got {got}" ) } - TransactionV1ConfigFailure::InsufficientTransferAmount { minimum, attempted } => { + InvalidTransaction::InsufficientTransferAmount { minimum, attempted } => { write!( formatter, "insufficient transfer amount; minimum: {minimum} attempted: {attempted}" ) } - TransactionV1ConfigFailure::EntryPointCannotBeCustom { entry_point } => { + InvalidTransaction::EntryPointCannotBeCustom { entry_point } => { write!(formatter, "entry point cannot be custom: {entry_point}") } - TransactionV1ConfigFailure::EntryPointMustBeCustom { entry_point } => { + InvalidTransaction::EntryPointMustBeCustom { entry_point } => { write!(formatter, "entry point must be custom: {entry_point}") } - TransactionV1ConfigFailure::EmptyModuleBytes => { + InvalidTransaction::EmptyModuleBytes => { write!(formatter, "the transaction has empty module bytes") } + InvalidTransaction::GasPriceConversion { amount, gas_price } => { + write!( + formatter, + "failed to divide the amount {} by the gas price {}", + amount, gas_price + ) + } } } } -impl From for TransactionV1ConfigFailure { +impl From for InvalidTransaction { fn from(error: ExcessiveSizeErrorV1) -> Self { - TransactionV1ConfigFailure::ExcessiveSize(error) + InvalidTransaction::ExcessiveSize(error) } } #[cfg(feature = "std")] -impl StdError for TransactionV1ConfigFailure { +impl StdError for InvalidTransaction { fn source(&self) -> Option<&(dyn StdError + 'static)> { match self { - TransactionV1ConfigFailure::InvalidApproval { error, .. } => Some(error), - TransactionV1ConfigFailure::InvalidChainName { .. } - | TransactionV1ConfigFailure::ExcessiveSize(_) - | TransactionV1ConfigFailure::ExcessiveTimeToLive { .. } - | TransactionV1ConfigFailure::TimestampInFuture { .. } - | TransactionV1ConfigFailure::InvalidBodyHash - | TransactionV1ConfigFailure::InvalidTransactionHash - | TransactionV1ConfigFailure::EmptyApprovals - | TransactionV1ConfigFailure::ExcessiveArgsLength { .. } - | TransactionV1ConfigFailure::ExcessiveApprovals { .. } - | TransactionV1ConfigFailure::ExceedsBlockGasLimit { .. } - | TransactionV1ConfigFailure::MissingArg { .. } - | TransactionV1ConfigFailure::UnexpectedArgType { .. } - | TransactionV1ConfigFailure::InsufficientTransferAmount { .. } - | TransactionV1ConfigFailure::EntryPointCannotBeCustom { .. } - | TransactionV1ConfigFailure::EntryPointMustBeCustom { .. } - | TransactionV1ConfigFailure::EmptyModuleBytes => None, + InvalidTransaction::InvalidApproval { error, .. } => Some(error), + InvalidTransaction::InvalidChainName { .. } + | InvalidTransaction::ExcessiveSize(_) + | InvalidTransaction::ExcessiveTimeToLive { .. } + | InvalidTransaction::TimestampInFuture { .. } + | InvalidTransaction::InvalidBodyHash + | InvalidTransaction::InvalidTransactionHash + | InvalidTransaction::EmptyApprovals + | InvalidTransaction::ExcessiveArgsLength { .. } + | InvalidTransaction::ExcessiveApprovals { .. } + | InvalidTransaction::ExceedsBlockGasLimit { .. } + | InvalidTransaction::MissingArg { .. } + | InvalidTransaction::UnexpectedArgType { .. } + | InvalidTransaction::InsufficientTransferAmount { .. } + | InvalidTransaction::EntryPointCannotBeCustom { .. } + | InvalidTransaction::EntryPointMustBeCustom { .. } + | InvalidTransaction::EmptyModuleBytes + | InvalidTransaction::GasPriceConversion { .. } => None, } } } diff --git a/types/src/transaction/transaction_v1/transaction_v1_body.rs b/types/src/transaction/transaction_v1/transaction_v1_body.rs index df86bd616a..d36078b06e 100644 --- a/types/src/transaction/transaction_v1/transaction_v1_body.rs +++ b/types/src/transaction/transaction_v1/transaction_v1_body.rs @@ -19,15 +19,18 @@ use super::super::{RuntimeArgs, TransactionEntryPoint, TransactionScheduling, Tr #[cfg(any(all(feature = "std", feature = "testing"), test))] use super::TransactionCategory; +#[cfg(any(feature = "std", test))] +use super::TransactionConfig; #[cfg(doc)] use super::TransactionV1; -#[cfg(any(feature = "std", test))] -use super::{TransactionConfig, TransactionV1ConfigFailure}; use crate::{ bytesrepr::{self, FromBytes, ToBytes}, TransactionSessionKind, }; +#[cfg(any(feature = "std", test))] +use crate::InvalidTransactionV1; + #[cfg(any(all(feature = "std", feature = "testing"), test))] use crate::{ bytesrepr::Bytes, testing::TestRng, PublicKey, TransactionInvocationTarget, TransactionRuntime, @@ -128,10 +131,7 @@ impl TransactionV1Body { } #[cfg(any(feature = "std", test))] - pub(super) fn is_valid( - &self, - config: &TransactionConfig, - ) -> Result<(), TransactionV1ConfigFailure> { + pub(super) fn is_valid(&self, config: &TransactionConfig) -> Result<(), InvalidTransactionV1> { let args_length = self.args.serialized_length(); if args_length > config.transaction_v1_config.max_args_length as usize { debug!( @@ -139,7 +139,7 @@ impl TransactionV1Body { max_args_length = config.transaction_v1_config.max_args_length, "transaction runtime args excessive size" ); - return Err(TransactionV1ConfigFailure::ExcessiveArgsLength { + return Err(InvalidTransactionV1::ExcessiveArgsLength { max_length: config.transaction_v1_config.max_args_length as usize, got: args_length, }); @@ -152,7 +152,7 @@ impl TransactionV1Body { entry_point = %self.entry_point, "native transaction cannot have custom entry point" ); - Err(TransactionV1ConfigFailure::EntryPointCannotBeCustom { + Err(InvalidTransactionV1::EntryPointCannotBeCustom { entry_point: self.entry_point.clone(), }) } @@ -190,7 +190,7 @@ impl TransactionV1Body { entry_point = %self.entry_point, "transaction targeting stored entity/package must have custom entry point" ); - Err(TransactionV1ConfigFailure::EntryPointMustBeCustom { + Err(InvalidTransactionV1::EntryPointMustBeCustom { entry_point: self.entry_point.clone(), }) } @@ -199,7 +199,7 @@ impl TransactionV1Body { TransactionEntryPoint::Custom(_) => { if module_bytes.is_empty() { debug!("transaction with session code must not have empty module bytes"); - return Err(TransactionV1ConfigFailure::EmptyModuleBytes); + return Err(InvalidTransactionV1::EmptyModuleBytes); } Ok(()) } @@ -214,7 +214,7 @@ impl TransactionV1Body { entry_point = %self.entry_point, "transaction with session code must have custom entry point" ); - Err(TransactionV1ConfigFailure::EntryPointMustBeCustom { + Err(InvalidTransactionV1::EntryPointMustBeCustom { entry_point: self.entry_point.clone(), }) } @@ -400,13 +400,6 @@ impl Display for TransactionV1Body { } impl ToBytes for TransactionV1Body { - fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - self.args.write_bytes(writer)?; - self.target.write_bytes(writer)?; - self.entry_point.write_bytes(writer)?; - self.scheduling.write_bytes(writer) - } - fn to_bytes(&self) -> Result, bytesrepr::Error> { let mut buffer = bytesrepr::allocate_buffer(self)?; self.write_bytes(&mut buffer)?; @@ -419,6 +412,13 @@ impl ToBytes for TransactionV1Body { + self.entry_point.serialized_length() + self.scheduling.serialized_length() } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + self.args.write_bytes(writer)?; + self.target.write_bytes(writer)?; + self.entry_point.write_bytes(writer)?; + self.scheduling.write_bytes(writer) + } } impl FromBytes for TransactionV1Body { @@ -452,7 +452,7 @@ mod tests { let mut body = TransactionV1Body::random(rng); body.args = runtime_args! {"a" => 1_u8}; - let expected_error = TransactionV1ConfigFailure::ExcessiveArgsLength { + let expected_error = InvalidTransactionV1::ExcessiveArgsLength { max_length: 10, got: 15, }; @@ -474,7 +474,7 @@ mod tests { TransactionScheduling::random(rng), ); - let expected_error = TransactionV1ConfigFailure::EntryPointCannotBeCustom { entry_point }; + let expected_error = InvalidTransactionV1::EntryPointCannotBeCustom { entry_point }; let config = TransactionConfig::default(); assert_eq!(body.is_valid(&config,), Err(expected_error)); @@ -509,7 +509,7 @@ mod tests { TransactionScheduling::random(rng), ); - let expected_error = TransactionV1ConfigFailure::EntryPointMustBeCustom { entry_point }; + let expected_error = InvalidTransactionV1::EntryPointMustBeCustom { entry_point }; assert_eq!(stored_body.is_valid(&config,), Err(expected_error.clone())); assert_eq!(session_body.is_valid(&config,), Err(expected_error)); diff --git a/types/src/transaction/transaction_v1/transaction_v1_body/arg_handling.rs b/types/src/transaction/transaction_v1/transaction_v1_body/arg_handling.rs index 7a99a942b9..44e2dc1086 100644 --- a/types/src/transaction/transaction_v1/transaction_v1_body/arg_handling.rs +++ b/types/src/transaction/transaction_v1/transaction_v1_body/arg_handling.rs @@ -2,12 +2,11 @@ use core::marker::PhantomData; use tracing::debug; -use super::super::TransactionV1ConfigFailure; use crate::{ account::AccountHash, bytesrepr::{FromBytes, ToBytes}, system::auction::ARG_VALIDATOR_PUBLIC_KEY, - CLTyped, CLValue, CLValueError, PublicKey, RuntimeArgs, URef, U512, + CLTyped, CLValue, CLValueError, InvalidTransactionV1, PublicKey, RuntimeArgs, URef, U512, }; const TRANSFER_ARG_SOURCE: RequiredArg = RequiredArg::new("source"); @@ -52,13 +51,13 @@ impl RequiredArg { } } - fn get(&self, args: &RuntimeArgs) -> Result + fn get(&self, args: &RuntimeArgs) -> Result where T: CLTyped + FromBytes, { let cl_value = args.get(self.name).ok_or_else(|| { debug!("missing required runtime argument '{}'", self.name); - TransactionV1ConfigFailure::MissingArg { + InvalidTransactionV1::MissingArg { arg_name: self.name.to_string(), } })?; @@ -86,7 +85,7 @@ impl OptionalArg { } } - fn get(&self, args: &RuntimeArgs) -> Result, TransactionV1ConfigFailure> + fn get(&self, args: &RuntimeArgs) -> Result, InvalidTransactionV1> where T: CLTyped + FromBytes, { @@ -109,14 +108,14 @@ impl OptionalArg { fn parse_cl_value( cl_value: &CLValue, arg_name: &str, -) -> Result { +) -> Result { cl_value.to_t::().map_err(|_| { debug!( "expected runtime argument '{arg_name}' to be of type {}, but is {}", T::cl_type(), cl_value.cl_type() ); - TransactionV1ConfigFailure::UnexpectedArgType { + InvalidTransactionV1::UnexpectedArgType { arg_name: arg_name.to_string(), expected: T::cl_type(), got: cl_value.cl_type().clone(), @@ -149,7 +148,7 @@ pub(in crate::transaction::transaction_v1) fn new_transfer_args>( pub(in crate::transaction::transaction_v1) fn has_valid_transfer_args( args: &RuntimeArgs, native_transfer_minimum_motes: u64, -) -> Result<(), TransactionV1ConfigFailure> { +) -> Result<(), InvalidTransactionV1> { let _source = TRANSFER_ARG_SOURCE.get(args)?; let _target = TRANSFER_ARG_TARGET.get(args)?; let amount = TRANSFER_ARG_AMOUNT.get(args)?; @@ -159,7 +158,7 @@ pub(in crate::transaction::transaction_v1) fn has_valid_transfer_args( %amount, "insufficient transfer amount" ); - return Err(TransactionV1ConfigFailure::InsufficientTransferAmount { + return Err(InvalidTransactionV1::InsufficientTransferAmount { minimum: native_transfer_minimum_motes, attempted: amount, }); @@ -185,7 +184,7 @@ pub(in crate::transaction::transaction_v1) fn new_add_bid_args>( /// Checks the given `RuntimeArgs` are suitable for use in an add_bid transaction. pub(in crate::transaction::transaction_v1) fn has_valid_add_bid_args( args: &RuntimeArgs, -) -> Result<(), TransactionV1ConfigFailure> { +) -> Result<(), InvalidTransactionV1> { let _public_key = ADD_BID_ARG_PUBLIC_KEY.get(args)?; let _delegation_rate = ADD_BID_ARG_DELEGATION_RATE.get(args)?; let _amount = ADD_BID_ARG_AMOUNT.get(args)?; @@ -206,7 +205,7 @@ pub(in crate::transaction::transaction_v1) fn new_withdraw_bid_args Result<(), TransactionV1ConfigFailure> { +) -> Result<(), InvalidTransactionV1> { let _public_key = WITHDRAW_BID_ARG_PUBLIC_KEY.get(args)?; let _amount = WITHDRAW_BID_ARG_AMOUNT.get(args)?; Ok(()) @@ -228,7 +227,7 @@ pub(in crate::transaction::transaction_v1) fn new_delegate_args>( /// Checks the given `RuntimeArgs` are suitable for use in a delegate transaction. pub(in crate::transaction::transaction_v1) fn has_valid_delegate_args( args: &RuntimeArgs, -) -> Result<(), TransactionV1ConfigFailure> { +) -> Result<(), InvalidTransactionV1> { let _delegator = DELEGATE_ARG_DELEGATOR.get(args)?; let _validator = DELEGATE_ARG_VALIDATOR.get(args)?; let _amount = DELEGATE_ARG_AMOUNT.get(args)?; @@ -251,7 +250,7 @@ pub(in crate::transaction::transaction_v1) fn new_undelegate_args> /// Checks the given `RuntimeArgs` are suitable for use in an undelegate transaction. pub(in crate::transaction::transaction_v1) fn has_valid_undelegate_args( args: &RuntimeArgs, -) -> Result<(), TransactionV1ConfigFailure> { +) -> Result<(), InvalidTransactionV1> { let _delegator = UNDELEGATE_ARG_DELEGATOR.get(args)?; let _validator = UNDELEGATE_ARG_VALIDATOR.get(args)?; let _amount = UNDELEGATE_ARG_AMOUNT.get(args)?; @@ -276,7 +275,7 @@ pub(in crate::transaction::transaction_v1) fn new_redelegate_args> /// Checks the given `RuntimeArgs` are suitable for use in a redelegate transaction. pub(in crate::transaction::transaction_v1) fn has_valid_redelegate_args( args: &RuntimeArgs, -) -> Result<(), TransactionV1ConfigFailure> { +) -> Result<(), InvalidTransactionV1> { let _delegator = REDELEGATE_ARG_DELEGATOR.get(args)?; let _validator = REDELEGATE_ARG_VALIDATOR.get(args)?; let _amount = REDELEGATE_ARG_AMOUNT.get(args)?; @@ -287,7 +286,7 @@ pub(in crate::transaction::transaction_v1) fn has_valid_redelegate_args( /// Checks the given `RuntimeArgs` are suitable for use in a redelegate transaction. pub(in crate::transaction::transaction_v1) fn has_valid_activate_bid_args( args: &RuntimeArgs, -) -> Result<(), TransactionV1ConfigFailure> { +) -> Result<(), InvalidTransactionV1> { let _validator = ACTIVATE_BID_ARG_VALIDATOR.get(args)?; Ok(()) } @@ -349,7 +348,7 @@ mod tests { TRANSFER_ARG_AMOUNT.name => U512::from(min_motes - 1) }; - let expected_error = TransactionV1ConfigFailure::InsufficientTransferAmount { + let expected_error = InvalidTransactionV1::InsufficientTransferAmount { minimum: min_motes, attempted: U512::from(min_motes - 1), }; @@ -370,7 +369,7 @@ mod tests { TRANSFER_ARG_TARGET.name => rng.gen::(), TRANSFER_ARG_AMOUNT.name => U512::from(min_motes) }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: TRANSFER_ARG_SOURCE.name.to_string(), }; assert_eq!( @@ -383,7 +382,7 @@ mod tests { TRANSFER_ARG_SOURCE.name => rng.gen::(), TRANSFER_ARG_AMOUNT.name => U512::from(min_motes) }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: TRANSFER_ARG_TARGET.name.to_string(), }; assert_eq!( @@ -396,7 +395,7 @@ mod tests { TRANSFER_ARG_SOURCE.name => rng.gen::(), TRANSFER_ARG_TARGET.name => rng.gen::() }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: TRANSFER_ARG_AMOUNT.name.to_string(), }; assert_eq!( @@ -416,7 +415,7 @@ mod tests { TRANSFER_ARG_TARGET.name => rng.gen::(), TRANSFER_ARG_AMOUNT.name => U512::from(min_motes) }; - let expected_error = TransactionV1ConfigFailure::UnexpectedArgType { + let expected_error = InvalidTransactionV1::UnexpectedArgType { arg_name: TRANSFER_ARG_SOURCE.name.to_string(), expected: CLType::URef, got: CLType::U8, @@ -433,7 +432,7 @@ mod tests { TRANSFER_ARG_AMOUNT.name => U512::from(min_motes), TRANSFER_ARG_TO.name => 1_u8 }; - let expected_error = TransactionV1ConfigFailure::UnexpectedArgType { + let expected_error = InvalidTransactionV1::UnexpectedArgType { arg_name: TRANSFER_ARG_TO.name.to_string(), expected: Option::::cl_type(), got: CLType::U8, @@ -467,7 +466,7 @@ mod tests { ADD_BID_ARG_DELEGATION_RATE.name => rng.gen::(), ADD_BID_ARG_AMOUNT.name => U512::from(rng.gen::()) }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: ADD_BID_ARG_PUBLIC_KEY.name.to_string(), }; assert_eq!(has_valid_add_bid_args(&args), Err(expected_error)); @@ -477,7 +476,7 @@ mod tests { ADD_BID_ARG_PUBLIC_KEY.name => PublicKey::random(rng), ADD_BID_ARG_AMOUNT.name => U512::from(rng.gen::()) }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: ADD_BID_ARG_DELEGATION_RATE.name.to_string(), }; assert_eq!(has_valid_add_bid_args(&args), Err(expected_error)); @@ -487,7 +486,7 @@ mod tests { ADD_BID_ARG_PUBLIC_KEY.name => PublicKey::random(rng), ADD_BID_ARG_DELEGATION_RATE.name => rng.gen::() }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: ADD_BID_ARG_AMOUNT.name.to_string(), }; assert_eq!(has_valid_add_bid_args(&args), Err(expected_error)); @@ -503,7 +502,7 @@ mod tests { ADD_BID_ARG_DELEGATION_RATE.name => rng.gen::(), ADD_BID_ARG_AMOUNT.name => rng.gen::() }; - let expected_error = TransactionV1ConfigFailure::UnexpectedArgType { + let expected_error = InvalidTransactionV1::UnexpectedArgType { arg_name: ADD_BID_ARG_AMOUNT.name.to_string(), expected: CLType::U512, got: CLType::U64, @@ -532,7 +531,7 @@ mod tests { let args = runtime_args! { WITHDRAW_BID_ARG_AMOUNT.name => U512::from(rng.gen::()) }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: WITHDRAW_BID_ARG_PUBLIC_KEY.name.to_string(), }; assert_eq!(has_valid_withdraw_bid_args(&args), Err(expected_error)); @@ -541,7 +540,7 @@ mod tests { let args = runtime_args! { WITHDRAW_BID_ARG_PUBLIC_KEY.name => PublicKey::random(rng), }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: WITHDRAW_BID_ARG_AMOUNT.name.to_string(), }; assert_eq!(has_valid_withdraw_bid_args(&args), Err(expected_error)); @@ -556,7 +555,7 @@ mod tests { WITHDRAW_BID_ARG_PUBLIC_KEY.name => PublicKey::random(rng), WITHDRAW_BID_ARG_AMOUNT.name => rng.gen::() }; - let expected_error = TransactionV1ConfigFailure::UnexpectedArgType { + let expected_error = InvalidTransactionV1::UnexpectedArgType { arg_name: WITHDRAW_BID_ARG_AMOUNT.name.to_string(), expected: CLType::U512, got: CLType::U64, @@ -591,7 +590,7 @@ mod tests { DELEGATE_ARG_VALIDATOR.name => PublicKey::random(rng), DELEGATE_ARG_AMOUNT.name => U512::from(rng.gen::()) }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: DELEGATE_ARG_DELEGATOR.name.to_string(), }; assert_eq!(has_valid_delegate_args(&args), Err(expected_error)); @@ -601,7 +600,7 @@ mod tests { DELEGATE_ARG_DELEGATOR.name => PublicKey::random(rng), DELEGATE_ARG_AMOUNT.name => U512::from(rng.gen::()) }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: DELEGATE_ARG_VALIDATOR.name.to_string(), }; assert_eq!(has_valid_delegate_args(&args), Err(expected_error)); @@ -611,7 +610,7 @@ mod tests { DELEGATE_ARG_DELEGATOR.name => PublicKey::random(rng), DELEGATE_ARG_VALIDATOR.name => PublicKey::random(rng), }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: DELEGATE_ARG_AMOUNT.name.to_string(), }; assert_eq!(has_valid_delegate_args(&args), Err(expected_error)); @@ -627,7 +626,7 @@ mod tests { DELEGATE_ARG_VALIDATOR.name => PublicKey::random(rng), DELEGATE_ARG_AMOUNT.name => rng.gen::() }; - let expected_error = TransactionV1ConfigFailure::UnexpectedArgType { + let expected_error = InvalidTransactionV1::UnexpectedArgType { arg_name: DELEGATE_ARG_AMOUNT.name.to_string(), expected: CLType::U512, got: CLType::U64, @@ -662,7 +661,7 @@ mod tests { UNDELEGATE_ARG_VALIDATOR.name => PublicKey::random(rng), UNDELEGATE_ARG_AMOUNT.name => U512::from(rng.gen::()) }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: UNDELEGATE_ARG_DELEGATOR.name.to_string(), }; assert_eq!(has_valid_undelegate_args(&args), Err(expected_error)); @@ -672,7 +671,7 @@ mod tests { UNDELEGATE_ARG_DELEGATOR.name => PublicKey::random(rng), UNDELEGATE_ARG_AMOUNT.name => U512::from(rng.gen::()) }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: UNDELEGATE_ARG_VALIDATOR.name.to_string(), }; assert_eq!(has_valid_undelegate_args(&args), Err(expected_error)); @@ -682,7 +681,7 @@ mod tests { UNDELEGATE_ARG_DELEGATOR.name => PublicKey::random(rng), UNDELEGATE_ARG_VALIDATOR.name => PublicKey::random(rng), }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: UNDELEGATE_ARG_AMOUNT.name.to_string(), }; assert_eq!(has_valid_undelegate_args(&args), Err(expected_error)); @@ -698,7 +697,7 @@ mod tests { UNDELEGATE_ARG_VALIDATOR.name => PublicKey::random(rng), UNDELEGATE_ARG_AMOUNT.name => rng.gen::() }; - let expected_error = TransactionV1ConfigFailure::UnexpectedArgType { + let expected_error = InvalidTransactionV1::UnexpectedArgType { arg_name: UNDELEGATE_ARG_AMOUNT.name.to_string(), expected: CLType::U512, got: CLType::U64, @@ -735,7 +734,7 @@ mod tests { REDELEGATE_ARG_AMOUNT.name => U512::from(rng.gen::()), REDELEGATE_ARG_NEW_VALIDATOR.name => PublicKey::random(rng), }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: REDELEGATE_ARG_DELEGATOR.name.to_string(), }; assert_eq!(has_valid_redelegate_args(&args), Err(expected_error)); @@ -746,7 +745,7 @@ mod tests { REDELEGATE_ARG_AMOUNT.name => U512::from(rng.gen::()), REDELEGATE_ARG_NEW_VALIDATOR.name => PublicKey::random(rng), }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: REDELEGATE_ARG_VALIDATOR.name.to_string(), }; assert_eq!(has_valid_redelegate_args(&args), Err(expected_error)); @@ -757,7 +756,7 @@ mod tests { REDELEGATE_ARG_VALIDATOR.name => PublicKey::random(rng), REDELEGATE_ARG_NEW_VALIDATOR.name => PublicKey::random(rng), }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: REDELEGATE_ARG_AMOUNT.name.to_string(), }; assert_eq!(has_valid_redelegate_args(&args), Err(expected_error)); @@ -768,7 +767,7 @@ mod tests { REDELEGATE_ARG_VALIDATOR.name => PublicKey::random(rng), REDELEGATE_ARG_AMOUNT.name => U512::from(rng.gen::()), }; - let expected_error = TransactionV1ConfigFailure::MissingArg { + let expected_error = InvalidTransactionV1::MissingArg { arg_name: REDELEGATE_ARG_NEW_VALIDATOR.name.to_string(), }; assert_eq!(has_valid_redelegate_args(&args), Err(expected_error)); @@ -785,7 +784,7 @@ mod tests { REDELEGATE_ARG_AMOUNT.name => rng.gen::(), REDELEGATE_ARG_NEW_VALIDATOR.name => PublicKey::random(rng), }; - let expected_error = TransactionV1ConfigFailure::UnexpectedArgType { + let expected_error = InvalidTransactionV1::UnexpectedArgType { arg_name: REDELEGATE_ARG_AMOUNT.name.to_string(), expected: CLType::U512, got: CLType::U64, diff --git a/types/src/transaction/transaction_v1/transaction_v1_header.rs b/types/src/transaction/transaction_v1/transaction_v1_header.rs index 316fce90a3..3c784c5631 100644 --- a/types/src/transaction/transaction_v1/transaction_v1_header.rs +++ b/types/src/transaction/transaction_v1/transaction_v1_header.rs @@ -18,7 +18,7 @@ use crate::{ Digest, TimeDiff, Timestamp, }; #[cfg(any(feature = "std", test))] -use crate::{TransactionConfig, TransactionV1ConfigFailure, TransactionV1Hash}; +use crate::{InvalidTransactionV1, TransactionConfig, TransactionV1Hash}; /// The header portion of a [`TransactionV1`]. #[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)] @@ -117,7 +117,7 @@ impl TransactionV1Header { timestamp_leeway: TimeDiff, at: Timestamp, transaction_hash: &TransactionV1Hash, - ) -> Result<(), TransactionV1ConfigFailure> { + ) -> Result<(), InvalidTransactionV1> { if self.ttl() > config.max_ttl { debug!( %transaction_hash, @@ -125,7 +125,7 @@ impl TransactionV1Header { max_ttl = %config.max_ttl, "transaction ttl excessive" ); - return Err(TransactionV1ConfigFailure::ExcessiveTimeToLive { + return Err(InvalidTransactionV1::ExcessiveTimeToLive { max_ttl: config.max_ttl, got: self.ttl(), }); @@ -136,7 +136,7 @@ impl TransactionV1Header { %transaction_hash, transaction_header = %self, %at, "transaction timestamp in the future" ); - return Err(TransactionV1ConfigFailure::TimestampInFuture { + return Err(InvalidTransactionV1::TimestampInFuture { validation_timestamp: at, timestamp_leeway, got: self.timestamp(), @@ -158,15 +158,6 @@ impl TransactionV1Header { } impl ToBytes for TransactionV1Header { - fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - self.chain_name.write_bytes(writer)?; - self.timestamp.write_bytes(writer)?; - self.ttl.write_bytes(writer)?; - self.body_hash.write_bytes(writer)?; - self.pricing_mode.write_bytes(writer)?; - self.initiator_addr.write_bytes(writer) - } - fn to_bytes(&self) -> Result, bytesrepr::Error> { let mut buffer = bytesrepr::allocate_buffer(self)?; self.write_bytes(&mut buffer)?; @@ -181,6 +172,15 @@ impl ToBytes for TransactionV1Header { + self.pricing_mode.serialized_length() + self.initiator_addr.serialized_length() } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + self.chain_name.write_bytes(writer)?; + self.timestamp.write_bytes(writer)?; + self.ttl.write_bytes(writer)?; + self.body_hash.write_bytes(writer)?; + self.pricing_mode.write_bytes(writer)?; + self.initiator_addr.write_bytes(writer) + } } impl FromBytes for TransactionV1Header { diff --git a/utils/validation/tests/fixtures/ABI/key.json b/utils/validation/tests/fixtures/ABI/key.json index a2d9662210..732ccaf183 100644 --- a/utils/validation/tests/fixtures/ABI/key.json +++ b/utils/validation/tests/fixtures/ABI/key.json @@ -24,7 +24,7 @@ "value": "balance-hold-002a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0000000000000000" } ], - "output": "15002a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0000000000000000" + "output": "16002a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0000000000000000" }, "ChainspecRegistry": { "input": [ From dcbe34c6770ac25ce3629faeae567144a180af88 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Fri, 15 Mar 2024 03:13:35 -0700 Subject: [PATCH 19/70] reworked execute finalized block flow...all node tests are passing except should_store_finalized_approvals; will investigate further prior to opening PR --- .../test_support/src/wasm_test_builder.rs | 9 +- .../system_contracts/auction/distribute.rs | 3 + node/src/components/contract_runtime.rs | 4 +- .../components/contract_runtime/operations.rs | 530 +++++++++--------- node/src/components/contract_runtime/types.rs | 226 +++++++- node/src/components/contract_runtime/utils.rs | 10 +- node/src/reactor/main_reactor/tests.rs | 6 +- storage/src/data_access_layer/balance.rs | 10 + storage/src/data_access_layer/balance_hold.rs | 1 + storage/src/data_access_layer/bidding.rs | 10 +- storage/src/global_state/state/mod.rs | 222 ++++---- types/src/transaction.rs | 15 + 12 files changed, 626 insertions(+), 420 deletions(-) diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index 5ba6d08eea..e6402b1eaa 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -792,14 +792,7 @@ where authorization_keys, auction_method, ); - let ret = self.data_access_layer().bidding(bidding_req); - if let BiddingResult::Success { - post_state_hash, .. - } = ret - { - self.post_state_hash = Some(post_state_hash); - } - ret + self.data_access_layer().bidding(bidding_req) } /// Runs an [`ExecuteRequest`]. diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs b/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs index 5dddddac78..5328759da2 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs @@ -998,6 +998,7 @@ fn should_distribute_rewards_after_restaking_delegated_funds() { }, ); assert!(undelegate_result.is_success(), "{:?}", undelegate_result); + builder.commit_transforms(builder.get_post_state_hash(), undelegate_result.effects()); delegator_1_stake = get_delegator_staked_amount(&mut builder, VALIDATOR_1.clone(), DELEGATOR_1.clone()); @@ -1017,6 +1018,7 @@ fn should_distribute_rewards_after_restaking_delegated_funds() { }, ); assert!(updelegate_result.is_success(), "{:?}", updelegate_result); + builder.commit_transforms(builder.get_post_state_hash(), undelegate_result.effects()); delegator_2_stake = get_delegator_staked_amount(&mut builder, VALIDATOR_1.clone(), DELEGATOR_2.clone()); @@ -1044,6 +1046,7 @@ fn should_distribute_rewards_after_restaking_delegated_funds() { auction_method, ); assert!(bid_flip_result.is_success(), "{:?}", bid_flip_result); + builder.commit_transforms(builder.get_post_state_hash(), undelegate_result.effects()); validator_stake = get_validator_bid(&mut builder, VALIDATOR_1.clone()) .expect("should have validator bid") .staked_amount(); diff --git a/node/src/components/contract_runtime.rs b/node/src/components/contract_runtime.rs index c91fd19297..4c7bcb9e40 100644 --- a/node/src/components/contract_runtime.rs +++ b/node/src/components/contract_runtime.rs @@ -72,8 +72,8 @@ pub(crate) use operations::compute_execution_results_checksum; pub use operations::execute_finalized_block; use operations::speculatively_execute; pub(crate) use types::{ - BlockAndExecutionResults, ExecutionArtifact, ExecutionPreState, SpeculativeExecutionState, - StepEffectsAndUpcomingEraValidators, + BlockAndExecutionArtifacts, ExecutionArtifact, ExecutionArtifacts, ExecutionPreState, + SpeculativeExecutionState, StepOutcome, }; use utils::{exec_or_requeue, run_intensive_task}; diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 3a664a48da..90594b695b 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -11,10 +11,11 @@ use casper_execution_engine::engine_state::{ use casper_storage::{ block_store::types::ApprovalsHashes, data_access_layer::{ - AuctionMethod, BalanceHoldRequest, BiddingRequest, BiddingResult, BlockRewardsRequest, - BlockRewardsResult, DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, EvictItem, - FeeRequest, FeeResult, FlushRequest, InsufficientBalanceHandling, PruneRequest, - PruneResult, StepRequest, StepResult, TransferRequest, TransferResult, + balance::BalanceHandling, AuctionMethod, BalanceHoldRequest, BalanceIdentifier, + BalanceRequest, BiddingRequest, BlockRewardsRequest, BlockRewardsResult, DataAccessLayer, + EraValidatorsRequest, EraValidatorsResult, EvictItem, FeeRequest, FeeResult, FlushRequest, + InsufficientBalanceHandling, PruneRequest, PruneResult, StepRequest, StepResult, + TransferRequest, }, global_state::{ error::Error as GlobalStateError, @@ -29,26 +30,27 @@ use casper_types::{ binary_port::SpeculativeExecutionResult, bytesrepr::{self, ToBytes, U32_SERIALIZED_LENGTH}, contract_messages::Messages, - execution::{Effects, ExecutionResult, ExecutionResultV2, TransformKindV2, TransformV2}, + execution::{Effects, ExecutionResult, TransformKindV2, TransformV2}, system::mint::BalanceHoldAddrTag, - ApprovalsHash, BlockTime, BlockV2, CLValue, Chainspec, ChecksumRegistry, DeployHash, Digest, - EraEndV2, EraId, FeeHandling, GasLimited, Key, ProtocolVersion, PublicKey, Transaction, U512, + BlockTime, BlockV2, CLValue, CategorizedTransaction, Chainspec, ChecksumRegistry, DeployHash, + Digest, EraEndV2, EraId, FeeHandling, GasLimited, Key, ProtocolVersion, PublicKey, Transaction, + TransactionCategory, U512, }; use crate::{ components::{ contract_runtime::{ - error::BlockExecutionError, types::StepEffectsAndUpcomingEraValidators, - BlockAndExecutionResults, ExecutionPreState, Metrics, SpeculativeExecutionState, - APPROVALS_CHECKSUM_NAME, EXECUTION_RESULTS_CHECKSUM_NAME, + error::BlockExecutionError, types::StepOutcome, BlockAndExecutionArtifacts, + ExecutionPreState, Metrics, SpeculativeExecutionState, APPROVALS_CHECKSUM_NAME, + EXECUTION_RESULTS_CHECKSUM_NAME, }, fetcher::FetchItem, }, - contract_runtime::utils::calculate_prune_eras, + contract_runtime::{types::ExecutionArtifactOutcome, utils::calculate_prune_eras}, types::{self, Chunkable, ExecutableBlock, InternalEraReport}, }; -use super::ExecutionArtifact; +use super::{ExecutionArtifact, ExecutionArtifacts}; /// Executes a finalized block. #[allow(clippy::too_many_arguments)] @@ -60,7 +62,7 @@ pub fn execute_finalized_block( execution_pre_state: ExecutionPreState, executable_block: ExecutableBlock, key_block_height_for_activation_point: u64, -) -> Result { +) -> Result { if executable_block.height != execution_pre_state.next_block_height() { return Err(BlockExecutionError::WrongBlockHeight { executable_block: Box::new(executable_block), @@ -78,21 +80,15 @@ pub fn execute_finalized_block( let parent_seed = execution_pre_state.parent_seed(); let mut state_root_hash = pre_state_root_hash; - let mut execution_artifacts: Vec = - Vec::with_capacity(executable_block.transactions.len()); + let mut artifacts = ExecutionArtifacts::with_capacity(executable_block.transactions.len()); let block_time = executable_block.timestamp.millis(); + let balance_handling = BalanceHandling::Available { + block_time, + hold_interval: chainspec.core_config.balance_hold_interval.millis(), + }; let holds_epoch = Some(chainspec.balance_holds_epoch(executable_block.timestamp)); let start = Instant::now(); - let txn_ids = executable_block - .transactions - .iter() - .map(Transaction::fetch_id) - .collect_vec(); - let approvals_checksum = types::compute_approvals_checksum(txn_ids.clone()) - .map_err(BlockExecutionError::FailedToComputeApprovalsChecksum)?; - let approvals_hashes: Vec = - txn_ids.into_iter().map(|id| id.approvals_hash()).collect(); let scratch_state = data_access_layer.get_scratch_global_state(); let mut effects = Effects::new(); @@ -101,79 +97,195 @@ pub fn execute_finalized_block( let insufficient_balance_handling = InsufficientBalanceHandling::HoldRemaining; let gas_price = Some(1); // < --TODO: this is where Karan's calculated gas price needs to be used - for transaction in executable_block.transactions { + for transaction in &executable_block.transactions { let transaction_hash = transaction.hash(); + let transaction_header = transaction.header(); let runtime_args = transaction.session_args().clone(); let entry_point = transaction.entry_point(); + let balance_identifier: BalanceIdentifier = transaction.initiator_addr().into(); // NOTE: this is the actual adjusted cost (gas limit * gas price) // NOT the allowed computation limit (gas limit) let cost = match transaction.gas_limit(&system_costs, gas_price) { Ok(gas) => gas.value(), Err(ite) => { - execution_artifacts.push(ExecutionArtifact::new( + artifacts.push_invalid_transaction( transaction_hash, - transaction.header(), - ExecutionResult::V2(ExecutionResultV2::Failure { - effects: Effects::new(), - cost: U512::zero(), - transfers: vec![], - error_message: format!("{:?}", ite), - }), - Messages::default(), - )); + transaction_header.clone(), + ite.clone(), + ); debug!(%ite, "invalid transaction"); continue; } }; + let initial_balance_result = scratch_state.balance(BalanceRequest::new( + state_root_hash, + protocol_version, + balance_identifier.clone(), + balance_handling, + )); + + let is_sufficient_balance = initial_balance_result.is_sufficient(cost); + let authorization_keys = transaction.authorization_keys(); + + match (transaction.category(), is_sufficient_balance) { + (_, false) => { + debug!( + "skipping execution of {} due to insufficient balance", + transaction_hash + ); + } + (TransactionCategory::Mint, _) => { + let transfer_result = scratch_state.transfer(TransferRequest::with_runtime_args( + native_runtime_config.clone(), + state_root_hash, + holds_epoch, + protocol_version, + transaction_hash, + transaction.initiator_addr().account_hash(), + authorization_keys.clone(), + runtime_args.clone(), + cost, + )); + match artifacts.push_transfer_result( + transaction_hash, + transaction_header.clone(), + transfer_result, + cost, + ) { + ExecutionArtifactOutcome::RootNotFound => { + return Err(BlockExecutionError::RootNotFound(state_root_hash)) + } + ExecutionArtifactOutcome::Failure => { + continue; + } + ExecutionArtifactOutcome::Success(transfer_effects) => { + effects.append(transfer_effects.clone()); + } + } + } + (TransactionCategory::Auction, _) => { + let auction_method = match AuctionMethod::from_parts( + entry_point, + &runtime_args, + holds_epoch, + chainspec, + ) { + Ok(auction_method) => auction_method, + Err(_) => { + artifacts.push_auction_method_failure( + transaction_hash, + transaction_header.clone(), + cost, + ); + continue; + } + }; + let bidding_result = scratch_state.bidding(BiddingRequest::new( + native_runtime_config.clone(), + state_root_hash, + block_time, + protocol_version, + transaction_hash, + transaction.initiator_addr().account_hash(), + authorization_keys.clone(), + auction_method, + )); + match artifacts.push_bidding_result( + transaction_hash, + transaction_header.clone(), + bidding_result, + cost, + ) { + ExecutionArtifactOutcome::RootNotFound => { + return Err(BlockExecutionError::RootNotFound(state_root_hash)) + } + ExecutionArtifactOutcome::Failure => { + continue; + } + ExecutionArtifactOutcome::Success(bidding_effects) => { + effects.append(bidding_effects.clone()); + } + } + } + (TransactionCategory::Standard, _) | (TransactionCategory::InstallUpgrade, _) => { + // TODO: i think fraser is doing the Transaction::V1(_) fixing here, but either way + // it needs to get done soonish to complete this work. All of this section needs + // a bit of a re-work to allow the rest of this logic to move further away from + // the legacy notions. + let (deploy_hash, deploy) = match transaction { + Transaction::Deploy(deploy) => { + let deploy_hash = *deploy.hash(); + (deploy_hash, deploy) + } + Transaction::V1(_) => continue, + }; + + let deploy_header = deploy.header().clone(); + let execute_request = ExecuteRequest::new( + state_root_hash, + block_time, + vec![DeployItem::from(deploy.clone())], + protocol_version, + PublicKey::clone(&executable_block.proposer), + ); + + let exec_result = execute( + &scratch_state, + execution_engine_v1, + metrics.clone(), + execute_request, + )?; + + trace!(?deploy_hash, ?exec_result, "transaction execution result"); + // As for now a given state is expected to exist. + let (state_hash, execution_result, messages) = commit_execution_results( + &scratch_state, + metrics.clone(), + state_root_hash, + deploy_hash, + exec_result, + )?; + artifacts.push(ExecutionArtifact::deploy( + deploy_hash, + deploy_header, + execution_result, + messages, + )); + state_root_hash = state_hash; + } + } + // handle payment per the chainspec determined fee setting match chainspec.core_config.fee_handling { FeeHandling::NoFee => { // this is the "fee elimination" model...a BalanceHold for the full cost is placed // on the initiator's purse. - let hold_amount = cost; let hold_result = scratch_state.balance_hold(BalanceHoldRequest::new( state_root_hash, protocol_version, - transaction.initiator_addr().into(), + balance_identifier.clone(), BalanceHoldAddrTag::Gas, - hold_amount, + cost, BlockTime::new(block_time), chainspec.core_config.balance_hold_interval, insufficient_balance_handling, )); - if hold_result.is_root_not_found() { - return Err(BlockExecutionError::RootNotFound(state_root_hash)); - } - let execution_result = { - let hold_cost = U512::zero(); // we don't charge for the hold itself. - let hold_effects = hold_result.effects(); - if hold_result.is_fully_covered() { - ExecutionResultV2::Success { - effects: hold_effects, - transfers: vec![], - cost: hold_cost, - } - } else { - let error_message = hold_result.error_message(); - debug!(%error_message); - ExecutionResultV2::Failure { - effects: hold_effects, - transfers: vec![], - error_message, - cost: hold_cost, - } - } - }; - execution_artifacts.push(ExecutionArtifact::new( + match artifacts.push_hold_result( transaction_hash, - transaction.header(), - ExecutionResult::V2(execution_result), - Messages::default(), - )); - if !hold_result.is_fully_covered() { - continue; + transaction_header.clone(), + hold_result, + ) { + ExecutionArtifactOutcome::RootNotFound => { + return Err(BlockExecutionError::RootNotFound(state_root_hash)) + } + ExecutionArtifactOutcome::Failure => { + continue; + } + ExecutionArtifactOutcome::Success(hold_effects) => { + effects.append(hold_effects.clone()) + } } } FeeHandling::PayToProposer => { @@ -194,158 +306,47 @@ pub fn execute_finalized_block( // fees are simply burned, lowering total supply. } } + } - if transaction.is_native_mint() { - // native transfers are routed to the data provider - let authorization_keys = transaction.authorization_keys(); - let transfer_req = TransferRequest::with_runtime_args( - native_runtime_config.clone(), - state_root_hash, - holds_epoch, - protocol_version, - transaction_hash, - transaction.initiator_addr().account_hash(), - authorization_keys, - runtime_args, - U512::zero(), /* <-- this should be from chainspec cost table */ - ); - //NOTE: native mint interactions auto-commit - let transfer_result = scratch_state.transfer(transfer_req); - trace!( - ?transaction_hash, - ?transfer_result, - "native transfer result" - ); - match transfer_result { - TransferResult::RootNotFound => { - return Err(BlockExecutionError::RootNotFound(state_root_hash)); - } - TransferResult::Failure(transfer_error) => { - let artifact = ExecutionArtifact::new( - transaction_hash, - transaction.header(), - ExecutionResult::V2(ExecutionResultV2::Failure { - effects: Effects::new(), - cost: U512::zero(), - transfers: vec![], - error_message: format!("{:?}", transfer_error), - }), - Messages::default(), - ); - execution_artifacts.push(artifact); - debug!(%transfer_error); - // a failure does not auto commit - continue; - } - TransferResult::Success { - effects: transfer_effects, - transfers, - .. - } => { - effects.append(transfer_effects.clone()); - let artifact = ExecutionArtifact::new( - transaction_hash, - transaction.header(), - ExecutionResult::V2(ExecutionResultV2::Success { - effects: transfer_effects, - cost: U512::zero(), - transfers, - }), - Messages::default(), - ); - execution_artifacts.push(artifact); - } - } - continue; - } - if transaction.is_native_auction() { - let runtime_args = transaction.session_args(); - let auction_method = match AuctionMethod::from_parts( - entry_point, - runtime_args, - holds_epoch, - chainspec, - ) { - Ok(auction_method) => auction_method, - Err(_) => { - error!(%transaction_hash, "failed to resolve auction method"); - continue; // skip to next record - } - }; - let authorization_keys = transaction.authorization_keys(); - let bidding_req = BiddingRequest::new( - native_runtime_config.clone(), - state_root_hash, - block_time, - protocol_version, - transaction_hash, - transaction.initiator_addr().account_hash(), - authorization_keys, - auction_method, - ); + // calculate and store checksums for approvals and execution effects across the transactions in + // the block we do this so that the full set of approvals and the full set of effect meta + // data can be verified if necessary for a given block. the block synchronizer in particular + // depends on the existence of such checksums. + let transactions_approvals_hashes = { + let mut checksum_registry = ChecksumRegistry::new(); - let bidding_result = scratch_state.bidding(bidding_req); - trace!(?transaction_hash, ?bidding_result, "native auction result"); - match bidding_result { - BiddingResult::RootNotFound => { - return Err(BlockExecutionError::RootNotFound(state_root_hash)) - } - BiddingResult::Success { - post_state_hash, .. - } => { - // we need a way to capture the effects from this without double committing - state_root_hash = post_state_hash; - } - BiddingResult::Failure(tce) => { - debug!(%tce); - continue; - } - } - } + let txn_ids = executable_block + .transactions + .iter() + .map(Transaction::fetch_id) + .collect_vec(); - let (deploy_hash, deploy) = match transaction { - Transaction::Deploy(deploy) => { - let deploy_hash = *deploy.hash(); - (deploy_hash, deploy) - } - Transaction::V1(_) => continue, - }; + let approvals_checksum = types::compute_approvals_checksum(txn_ids.clone()) + .map_err(BlockExecutionError::FailedToComputeApprovalsChecksum)?; - let deploy_header = deploy.header().clone(); - let execute_request = ExecuteRequest::new( - state_root_hash, - block_time, - vec![DeployItem::from(deploy)], - protocol_version, - PublicKey::clone(&executable_block.proposer), - ); + checksum_registry.insert(APPROVALS_CHECKSUM_NAME, approvals_checksum); - let exec_result = execute( - &scratch_state, - execution_engine_v1, - metrics.clone(), - execute_request, - )?; - - trace!(?deploy_hash, ?exec_result, "transaction execution result"); - // As for now a given state is expected to exist. - let (state_hash, execution_result, messages) = commit_execution_results( - &scratch_state, - metrics.clone(), - state_root_hash, - deploy_hash, - exec_result, - )?; - execution_artifacts.push(ExecutionArtifact::deploy( - deploy_hash, - deploy_header, - execution_result, - messages, + // Write the deploy approvals' and execution results' checksums to global state. + let execution_results_checksum = + compute_execution_results_checksum(artifacts.execution_results().into_iter())?; + checksum_registry.insert(EXECUTION_RESULTS_CHECKSUM_NAME, execution_results_checksum); + + effects.push(TransformV2::new( + Key::ChecksumRegistry, + TransformKindV2::Write( + CLValue::from_t(checksum_registry) + .map_err(BlockExecutionError::ChecksumRegistryToCLValue)? + .into(), + ), )); - state_root_hash = state_hash; - } - // Pay out fees, if relevant. + txn_ids.into_iter().map(|id| id.approvals_hash()).collect() + }; + + // After all transaction processing has been completed, commit all of the effects. + scratch_state.commit(state_root_hash, effects)?; + + // Pay out block fees, if relevant. { let fee_req = FeeRequest::new( native_runtime_config.clone(), @@ -373,6 +374,12 @@ pub fn execute_finalized_block( } } + // Update exec_block metric BEFORE determining per era things such as era rewards and step. + // the commit_step function handles the metrics for step + if let Some(metrics) = metrics.as_ref() { + metrics.exec_block.observe(start.elapsed().as_secs_f64()); + } + // Pay out ̶b̶l̶o̶c̶k̶ e͇r͇a͇ rewards // NOTE: despite the name, these rewards are currently paid out per ERA not per BLOCK // at one point, they were going to be paid out per block (and might be in the future) @@ -401,43 +408,9 @@ pub fn execute_finalized_block( } } - // handle checksum registry - let approvals_hashes = { - let mut checksum_registry = ChecksumRegistry::new(); - - checksum_registry.insert(APPROVALS_CHECKSUM_NAME, approvals_checksum); - - // Write the deploy approvals' and execution results' checksums to global state. - let execution_results_checksum = compute_execution_results_checksum( - execution_artifacts - .iter() - .map(|artifact| &artifact.execution_result), - )?; - checksum_registry.insert(EXECUTION_RESULTS_CHECKSUM_NAME, execution_results_checksum); - - effects.push(TransformV2::new( - Key::ChecksumRegistry, - TransformKindV2::Write( - CLValue::from_t(checksum_registry) - .map_err(BlockExecutionError::ChecksumRegistryToCLValue)? - .into(), - ), - )); - - approvals_hashes - }; - - scratch_state.commit(state_root_hash, effects)?; - - if let Some(metrics) = metrics.as_ref() { - metrics.exec_block.observe(start.elapsed().as_secs_f64()); - } - - // If the finalized block has an era report, run the auction contract and get the upcoming era - // validators. - let maybe_step_effects_and_upcoming_era_validators = if let Some(era_report) = - &executable_block.era_report - { + // if era report is some, this is a switch block. a series of end-of-era extra processing must + // transpire before this block is entirely finished. + let step_outcome = if let Some(era_report) = &executable_block.era_report { let step_effects = match commit_step( native_runtime_config, &scratch_state, @@ -452,7 +425,14 @@ pub fn execute_finalized_block( return Err(BlockExecutionError::RootNotFound(state_root_hash)) } StepResult::Failure(err) => return Err(BlockExecutionError::Step(err)), - StepResult::Success { effects, .. } => effects, + StepResult::Success { + effects, + post_state_hash, + .. + } => { + state_root_hash = post_state_hash; + effects + } }; state_root_hash = data_access_layer.write_scratch_to_db(state_root_hash, scratch_state)?; @@ -461,12 +441,12 @@ pub fn execute_finalized_block( let era_validators_result = data_access_layer.era_validators(era_validators_req); let upcoming_era_validators = match era_validators_result { - EraValidatorsResult::AuctionNotFound => { - panic!("auction not found"); - } EraValidatorsResult::RootNotFound => { panic!("root not found"); } + EraValidatorsResult::AuctionNotFound => { + panic!("auction not found"); + } EraValidatorsResult::ValueNotFound(msg) => { panic!("validator snapshot not found: {}", msg); } @@ -476,7 +456,7 @@ pub fn execute_finalized_block( EraValidatorsResult::Success { era_validators } => era_validators, }; - Some(StepEffectsAndUpcomingEraValidators { + Some(StepOutcome { step_effects, upcoming_era_validators, }) @@ -487,14 +467,6 @@ pub fn execute_finalized_block( None }; - // Flush once, after all deploys have been executed. - let flush_req = FlushRequest::new(); - let flush_result = data_access_layer.flush(flush_req); - if let Err(gse) = flush_result.as_error() { - error!("failed to flush lmdb"); - return Err(BlockExecutionError::Lmdb(gse)); - } - // Pruning if let Some(previous_block_height) = executable_block.height.checked_sub(1) { if let Some(keys_to_prune) = calculate_prune_eras( @@ -555,16 +527,22 @@ pub fn execute_finalized_block( } } + // Flush once, after all data mutation. + let flush_req = FlushRequest::new(); + let flush_result = data_access_layer.flush(flush_req); + if let Err(gse) = flush_result.as_error() { + error!("failed to flush lmdb"); + return Err(BlockExecutionError::Lmdb(gse)); + } + let maybe_next_era_validator_weights: Option> = { let next_era_id = executable_block.era_id.successor(); - maybe_step_effects_and_upcoming_era_validators - .as_ref() - .and_then( - |StepEffectsAndUpcomingEraValidators { - upcoming_era_validators, - .. - }| upcoming_era_validators.get(&next_era_id).cloned(), - ) + step_outcome.as_ref().and_then( + |StepOutcome { + upcoming_era_validators, + .. + }| upcoming_era_validators.get(&next_era_id).cloned(), + ) }; let era_end = match ( @@ -637,16 +615,18 @@ pub fn execute_finalized_block( Box::new(ApprovalsHashes::new( *block.hash(), - approvals_hashes, + transactions_approvals_hashes, proof_of_checksum_registry, )) }; - Ok(BlockAndExecutionResults { + let execution_artifacts = artifacts.take(); + + Ok(BlockAndExecutionArtifacts { block, approvals_hashes, - execution_results: execution_artifacts, - maybe_step_effects_and_upcoming_era_validators, + execution_artifacts, + step_outcome, }) } diff --git a/node/src/components/contract_runtime/types.rs b/node/src/components/contract_runtime/types.rs index d15226e368..ffa6ccf01a 100644 --- a/node/src/components/contract_runtime/types.rs +++ b/node/src/components/contract_runtime/types.rs @@ -2,15 +2,17 @@ use std::{collections::BTreeMap, sync::Arc}; use datasize::DataSize; use serde::Serialize; +use tracing::{debug, trace}; use casper_storage::{ - block_store::types::ApprovalsHashes, data_access_layer::EraValidatorsRequest, + block_store::types::ApprovalsHashes, + data_access_layer::{BalanceHoldResult, BiddingResult, EraValidatorsRequest, TransferResult}, }; use casper_types::{ contract_messages::Messages, - execution::{Effects, ExecutionResult}, - BlockHash, BlockHeaderV2, BlockV2, DeployHash, DeployHeader, Digest, EraId, ProtocolVersion, - PublicKey, Timestamp, TransactionHash, TransactionHeader, TransactionV1Hash, + execution::{Effects, ExecutionResult, ExecutionResultV2}, + BlockHash, BlockHeaderV2, BlockV2, DeployHash, DeployHeader, Digest, EraId, InvalidTransaction, + ProtocolVersion, PublicKey, Timestamp, TransactionHash, TransactionHeader, TransactionV1Hash, TransactionV1Header, U512, }; @@ -56,13 +58,218 @@ impl From for EraValidatorsRequest { /// Effects from running step and the next era validators that are gathered when an era ends. #[derive(Clone, Debug, DataSize)] -pub(crate) struct StepEffectsAndUpcomingEraValidators { +pub(crate) struct StepOutcome { /// Validator sets for all upcoming eras that have already been determined. pub(crate) upcoming_era_validators: BTreeMap>, /// An [`Effects`] created by an era ending. pub(crate) step_effects: Effects, } +pub(crate) struct ExecutionArtifacts { + artifacts: Vec, +} + +pub(crate) enum ExecutionArtifactOutcome { + RootNotFound, + Failure, + Success(Effects), +} + +impl ExecutionArtifacts { + pub fn with_capacity(capacity: usize) -> Self { + let artifacts = Vec::with_capacity(capacity); + ExecutionArtifacts { artifacts } + } + + pub fn push(&mut self, execution_artifact: ExecutionArtifact) { + self.artifacts.push(execution_artifact); + } + + pub fn push_invalid_transaction( + &mut self, + transaction_hash: TransactionHash, + transaction_header: TransactionHeader, + invalid_transaction: InvalidTransaction, + ) { + self.push_failure( + transaction_hash, + transaction_header, + format!("{:?}", invalid_transaction), + ); + } + + pub fn push_auction_method_failure( + &mut self, + transaction_hash: TransactionHash, + transaction_header: TransactionHeader, + cost: U512, + ) { + let msg = "failed to resolve auction method".to_string(); + let artifact = ExecutionArtifact::new( + transaction_hash, + transaction_header, + ExecutionResult::V2(ExecutionResultV2::Failure { + effects: Effects::new(), + transfers: vec![], + error_message: msg.clone(), + cost, + }), + Messages::default(), + ); + debug!(%transaction_hash, "{:?}", msg); + self.artifacts.push(artifact); + } + + pub fn push_transfer_result( + &mut self, + transaction_hash: TransactionHash, + transaction_header: TransactionHeader, + transfer_result: TransferResult, + cost: U512, + ) -> ExecutionArtifactOutcome { + trace!( + ?transaction_hash, + ?transfer_result, + "native transfer result" + ); + match transfer_result { + TransferResult::RootNotFound => ExecutionArtifactOutcome::RootNotFound, + TransferResult::Failure(transfer_error) => { + self.push_failure( + transaction_hash, + transaction_header, + format!("{:?}", transfer_error), + ); + debug!(%transfer_error); + ExecutionArtifactOutcome::Failure + } + TransferResult::Success { + effects: transfer_effects, + transfers, + } => { + self.artifacts.push(ExecutionArtifact::new( + transaction_hash, + transaction_header, + ExecutionResult::V2(ExecutionResultV2::Success { + effects: transfer_effects.clone(), + cost, + transfers, + }), + Messages::default(), + )); + ExecutionArtifactOutcome::Success(transfer_effects) + } + } + } + + pub fn push_bidding_result( + &mut self, + transaction_hash: TransactionHash, + transaction_header: TransactionHeader, + bidding_result: BiddingResult, + cost: U512, + ) -> ExecutionArtifactOutcome { + trace!(?transaction_hash, ?bidding_result, "bidding result"); + match bidding_result { + BiddingResult::RootNotFound => ExecutionArtifactOutcome::RootNotFound, + BiddingResult::Failure(tce) => { + self.artifacts.push(ExecutionArtifact::new( + transaction_hash, + transaction_header, + ExecutionResult::V2(ExecutionResultV2::Failure { + effects: Effects::new(), + cost, + transfers: vec![], + error_message: format!("{:?}", tce), + }), + Messages::default(), + )); + debug!(%tce); + ExecutionArtifactOutcome::Failure + } + BiddingResult::Success { + effects: bidding_effects, + .. + } => { + self.artifacts.push(ExecutionArtifact::new( + transaction_hash, + transaction_header, + ExecutionResult::V2(ExecutionResultV2::Success { + effects: bidding_effects.clone(), + cost, + transfers: vec![], + }), + Messages::default(), + )); + ExecutionArtifactOutcome::Success(bidding_effects) + } + } + } + + pub fn push_hold_result( + &mut self, + transaction_hash: TransactionHash, + transaction_header: TransactionHeader, + hold_result: BalanceHoldResult, + ) -> ExecutionArtifactOutcome { + trace!(?transaction_hash, ?hold_result, "balance hold result"); + if hold_result.is_root_not_found() { + return ExecutionArtifactOutcome::RootNotFound; + } + if !hold_result.is_fully_covered() { + let error_message = hold_result.error_message(); + self.push_failure(transaction_hash, transaction_header, error_message.clone()); + debug!(%error_message); + ExecutionArtifactOutcome::Failure + } else { + let hold_cost = U512::zero(); // we don't charge for the hold itself. + let hold_effects = hold_result.effects(); + self.artifacts.push(ExecutionArtifact::new( + transaction_hash, + transaction_header, + ExecutionResult::V2(ExecutionResultV2::Success { + effects: hold_effects.clone(), + transfers: vec![], + cost: hold_cost, + }), + Messages::default(), + )); + ExecutionArtifactOutcome::Success(hold_effects) + } + } + + fn push_failure( + &mut self, + transaction_hash: TransactionHash, + transaction_header: TransactionHeader, + error_message: String, + ) { + let execution_artifact = ExecutionArtifact::new( + transaction_hash, + transaction_header, + ExecutionResult::V2(ExecutionResultV2::Failure { + effects: Effects::new(), + cost: U512::zero(), + transfers: vec![], + error_message, + }), + Messages::default(), + ); + self.artifacts.push(execution_artifact); + } + + pub fn execution_results(&self) -> Vec<&ExecutionResult> { + self.artifacts + .iter() + .map(|artifact| &artifact.execution_result) + .collect::>() + } + + pub fn take(self) -> Vec { + self.artifacts + } +} + #[derive(Clone, Debug, DataSize, PartialEq, Eq, Serialize)] pub(crate) struct ExecutionArtifact { pub(crate) transaction_hash: TransactionHash, @@ -120,16 +327,15 @@ impl ExecutionArtifact { /// A [`Block`] that was the result of execution in the `ContractRuntime` along with any execution /// effects it may have. #[derive(Clone, Debug, DataSize)] -pub struct BlockAndExecutionResults { +pub struct BlockAndExecutionArtifacts { /// The [`Block`] the contract runtime executed. pub(crate) block: Arc, /// The [`ApprovalsHashes`] for the deploys in this block. pub(crate) approvals_hashes: Box, - /// The results from executing the deploys in the block. - pub(crate) execution_results: Vec, + /// The results from executing the transactions in the block. + pub(crate) execution_artifacts: Vec, /// The [`Effects`] and the upcoming validator sets determined by the `step` - pub(crate) maybe_step_effects_and_upcoming_era_validators: - Option, + pub(crate) step_outcome: Option, } #[derive(DataSize, Debug, Clone, Serialize)] diff --git a/node/src/components/contract_runtime/utils.rs b/node/src/components/contract_runtime/utils.rs index 61e73f5adc..5d1856c4dd 100644 --- a/node/src/components/contract_runtime/utils.rs +++ b/node/src/components/contract_runtime/utils.rs @@ -3,7 +3,7 @@ use crate::{ exec_queue::{ExecQueue, QueueItem}, execute_finalized_block, metrics::Metrics, - rewards, BlockAndExecutionResults, ExecutionPreState, StepEffectsAndUpcomingEraValidators, + rewards, BlockAndExecutionArtifacts, ExecutionPreState, StepOutcome, }, effect::{ announcements::{ContractRuntimeAnnouncement, FatalAnnouncement, MetaBlockAnnouncement}, @@ -99,11 +99,11 @@ pub(super) async fn exec_or_requeue( }); } - let BlockAndExecutionResults { + let BlockAndExecutionArtifacts { block, approvals_hashes, - execution_results, - maybe_step_effects_and_upcoming_era_validators, + execution_artifacts: execution_results, + step_outcome: maybe_step_effects_and_upcoming_era_validators, } = match run_intensive_task(move || { debug!("ContractRuntime: execute_finalized_block"); execute_finalized_block( @@ -149,7 +149,7 @@ pub(super) async fn exec_or_requeue( let current_era_id = block.era_id(); - if let Some(StepEffectsAndUpcomingEraValidators { + if let Some(StepOutcome { step_effects, mut upcoming_era_validators, }) = maybe_step_effects_and_upcoming_era_validators diff --git a/node/src/reactor/main_reactor/tests.rs b/node/src/reactor/main_reactor/tests.rs index 3f9aa3a2af..e59ef4b7e4 100644 --- a/node/src/reactor/main_reactor/tests.rs +++ b/node/src/reactor/main_reactor/tests.rs @@ -1311,11 +1311,11 @@ async fn should_store_finalized_approvals() { // Run until the transaction gets executed. let has_stored_exec_results = |nodes: &Nodes| { nodes.values().all(|runner| { - runner + let read = runner .main_reactor() .storage() - .read_execution_result(&transaction_hash) - .is_some() + .read_execution_result(&transaction_hash); + read.is_some() }) }; fixture.run_until(has_stored_exec_results, ONE_MIN).await; diff --git a/storage/src/data_access_layer/balance.rs b/storage/src/data_access_layer/balance.rs index 8311a8fed9..2263c259e1 100644 --- a/storage/src/data_access_layer/balance.rs +++ b/storage/src/data_access_layer/balance.rs @@ -290,4 +290,14 @@ impl BalanceResult { _ => None, } } + + /// Is the available balance sufficient to cover the cost? + pub fn is_sufficient(&self, cost: U512) -> bool { + match self { + BalanceResult::RootNotFound | BalanceResult::Failure(_) => false, + BalanceResult::Success { + available_balance, .. + } => available_balance >= &cost, + } + } } diff --git a/storage/src/data_access_layer/balance_hold.rs b/storage/src/data_access_layer/balance_hold.rs index 794015eb2e..d56250e240 100644 --- a/storage/src/data_access_layer/balance_hold.rs +++ b/storage/src/data_access_layer/balance_hold.rs @@ -236,6 +236,7 @@ impl Display for BalanceHoldError { } /// Result enum that represents all possible outcomes of a balance hold request. +#[derive(Debug)] pub enum BalanceHoldResult { /// Returned if a passed state root hash is not found. RootNotFound, diff --git a/storage/src/data_access_layer/bidding.rs b/storage/src/data_access_layer/bidding.rs index 85b6e604c3..7982376bb3 100644 --- a/storage/src/data_access_layer/bidding.rs +++ b/storage/src/data_access_layer/bidding.rs @@ -279,8 +279,6 @@ pub enum BiddingResult { Success { // The ret value, if any. ret: AuctionMethodRet, - /// State hash after bidding interaction is committed to the global state. - post_state_hash: Digest, /// Effects of bidding interaction. effects: Effects, }, @@ -293,4 +291,12 @@ impl BiddingResult { pub fn is_success(&self) -> bool { matches!(self, BiddingResult::Success { .. }) } + + /// Effects. + pub fn effects(&self) -> Effects { + match self { + BiddingResult::RootNotFound | BiddingResult::Failure(_) => Effects::new(), + BiddingResult::Success { effects, .. } => effects.clone(), + } + } } diff --git a/storage/src/global_state/state/mod.rs b/storage/src/global_state/state/mod.rs index 342faf6e82..df258f4263 100644 --- a/storage/src/global_state/state/mod.rs +++ b/storage/src/global_state/state/mod.rs @@ -619,121 +619,6 @@ pub trait CommitProvider: StateProvider { } FeeResult::Failure(FeeError::NoFeesDistributed) } - - /// Direct auction interaction for all variations of bid management. - fn bidding(&self, request: BiddingRequest) -> BiddingResult { - let state_hash = request.state_hash(); - let tc = match self.tracking_copy(state_hash) { - Ok(Some(tc)) => Rc::new(RefCell::new(tc)), - Ok(None) => return BiddingResult::RootNotFound, - Err(err) => return BiddingResult::Failure(TrackingCopyError::Storage(err)), - }; - - let protocol_version = request.protocol_version(); - let config = request.config(); - - let mut runtime = match RuntimeNative::new_system_runtime( - config.clone(), - protocol_version, - Id::Transaction(request.transaction_hash()), - Rc::clone(&tc), - Phase::Session, - ) { - Ok(rt) => rt, - Err(tce) => { - return BiddingResult::Failure(tce); - } - }; - - let auction_method = request.auction_method(); - - let result = match auction_method { - AuctionMethod::ActivateBid { - validator_public_key, - } => runtime - .activate_bid(validator_public_key) - .map(|_| AuctionMethodRet::Unit) - .map_err(|auc_err| { - TrackingCopyError::SystemContract(system::Error::Auction(auc_err)) - }), - AuctionMethod::AddBid { - public_key, - delegation_rate, - amount, - holds_epoch, - } => runtime - .add_bid(public_key, delegation_rate, amount, holds_epoch) - .map(AuctionMethodRet::UpdatedAmount) - .map_err(TrackingCopyError::Api), - AuctionMethod::WithdrawBid { public_key, amount } => runtime - .withdraw_bid(public_key, amount) - .map(AuctionMethodRet::UpdatedAmount) - .map_err(|auc_err| { - TrackingCopyError::SystemContract(system::Error::Auction(auc_err)) - }), - AuctionMethod::Delegate { - delegator_public_key, - validator_public_key, - amount, - max_delegators_per_validator, - minimum_delegation_amount, - holds_epoch, - } => runtime - .delegate( - delegator_public_key, - validator_public_key, - amount, - max_delegators_per_validator, - minimum_delegation_amount, - holds_epoch, - ) - .map(AuctionMethodRet::UpdatedAmount) - .map_err(TrackingCopyError::Api), - AuctionMethod::Undelegate { - delegator_public_key, - validator_public_key, - amount, - } => runtime - .undelegate(delegator_public_key, validator_public_key, amount) - .map(AuctionMethodRet::UpdatedAmount) - .map_err(|auc_err| { - TrackingCopyError::SystemContract(system::Error::Auction(auc_err)) - }), - AuctionMethod::Redelegate { - delegator_public_key, - validator_public_key, - amount, - new_validator, - minimum_delegation_amount, - } => runtime - .redelegate( - delegator_public_key, - validator_public_key, - amount, - new_validator, - minimum_delegation_amount, - ) - .map(AuctionMethodRet::UpdatedAmount) - .map_err(|auc_err| { - TrackingCopyError::SystemContract(system::Error::Auction(auc_err)) - }), - }; - - let effects = tc.borrow_mut().effects(); - - // commit - match result { - Ok(ret) => match self.commit(state_hash, effects.clone()) { - Ok(post_state_hash) => BiddingResult::Success { - ret, - post_state_hash, - effects, - }, - Err(tce) => BiddingResult::Failure(tce.into()), - }, - Err(tce) => BiddingResult::Failure(tce), - } - } } /// A trait expressing operations over the trie. @@ -1010,6 +895,113 @@ pub trait StateProvider { BidsResult::Success { bids } } + /// Direct auction interaction for all variations of bid management. + fn bidding(&self, request: BiddingRequest) -> BiddingResult { + let state_hash = request.state_hash(); + let tc = match self.tracking_copy(state_hash) { + Ok(Some(tc)) => Rc::new(RefCell::new(tc)), + Ok(None) => return BiddingResult::RootNotFound, + Err(err) => return BiddingResult::Failure(TrackingCopyError::Storage(err)), + }; + + let protocol_version = request.protocol_version(); + let config = request.config(); + + let mut runtime = match RuntimeNative::new_system_runtime( + config.clone(), + protocol_version, + Id::Transaction(request.transaction_hash()), + Rc::clone(&tc), + Phase::Session, + ) { + Ok(rt) => rt, + Err(tce) => { + return BiddingResult::Failure(tce); + } + }; + + let auction_method = request.auction_method(); + + let result = match auction_method { + AuctionMethod::ActivateBid { + validator_public_key, + } => runtime + .activate_bid(validator_public_key) + .map(|_| AuctionMethodRet::Unit) + .map_err(|auc_err| { + TrackingCopyError::SystemContract(system::Error::Auction(auc_err)) + }), + AuctionMethod::AddBid { + public_key, + delegation_rate, + amount, + holds_epoch, + } => runtime + .add_bid(public_key, delegation_rate, amount, holds_epoch) + .map(AuctionMethodRet::UpdatedAmount) + .map_err(TrackingCopyError::Api), + AuctionMethod::WithdrawBid { public_key, amount } => runtime + .withdraw_bid(public_key, amount) + .map(AuctionMethodRet::UpdatedAmount) + .map_err(|auc_err| { + TrackingCopyError::SystemContract(system::Error::Auction(auc_err)) + }), + AuctionMethod::Delegate { + delegator_public_key, + validator_public_key, + amount, + max_delegators_per_validator, + minimum_delegation_amount, + holds_epoch, + } => runtime + .delegate( + delegator_public_key, + validator_public_key, + amount, + max_delegators_per_validator, + minimum_delegation_amount, + holds_epoch, + ) + .map(AuctionMethodRet::UpdatedAmount) + .map_err(TrackingCopyError::Api), + AuctionMethod::Undelegate { + delegator_public_key, + validator_public_key, + amount, + } => runtime + .undelegate(delegator_public_key, validator_public_key, amount) + .map(AuctionMethodRet::UpdatedAmount) + .map_err(|auc_err| { + TrackingCopyError::SystemContract(system::Error::Auction(auc_err)) + }), + AuctionMethod::Redelegate { + delegator_public_key, + validator_public_key, + amount, + new_validator, + minimum_delegation_amount, + } => runtime + .redelegate( + delegator_public_key, + validator_public_key, + amount, + new_validator, + minimum_delegation_amount, + ) + .map(AuctionMethodRet::UpdatedAmount) + .map_err(|auc_err| { + TrackingCopyError::SystemContract(system::Error::Auction(auc_err)) + }), + }; + + let effects = tc.borrow_mut().effects(); + + match result { + Ok(ret) => BiddingResult::Success { ret, effects }, + Err(tce) => BiddingResult::Failure(tce), + } + } + /// Gets the execution result checksum. fn execution_result_checksum( &self, diff --git a/types/src/transaction.rs b/types/src/transaction.rs index 40a7c200d6..76da0a449b 100644 --- a/types/src/transaction.rs +++ b/types/src/transaction.rs @@ -335,6 +335,21 @@ impl Transaction { } } + /// Is this a transaction that should be sent to the v1 execution engine? + pub fn is_v1_wasm(&self) -> bool { + match self { + Transaction::Deploy(deploy) => !deploy.is_transfer(), + Transaction::V1(v1) => match v1.target() { + TransactionTarget::Native => false, + TransactionTarget::Stored { runtime, .. } + | TransactionTarget::Session { runtime, .. } => { + matches!(runtime, TransactionRuntime::VmCasperV1) + && (v1.is_standard() || v1.is_install_or_upgrade()) + } + }, + } + } + /// Authorization keys. pub fn authorization_keys(&self) -> BTreeSet { match self { From 5830cb218e18a8aa9e89fadf3d6a6792e4299405 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Mon, 18 Mar 2024 04:08:39 -0700 Subject: [PATCH 20/70] stripped down wasm exec, binary port types extracted into own crate, etc --- Cargo.lock | 19 + Cargo.toml | 2 + binary_port/README.md | 16 + .../src}/binary_request.rs | 80 +- .../src}/binary_response.rs | 26 +- .../src}/binary_response_and_request.rs | 28 +- .../src}/binary_response_header.rs | 13 +- .../src}/error_code.rs | 63 +- .../src}/get_request.rs | 14 +- .../src}/global_state_query_result.rs | 11 +- .../src}/information_request.rs | 10 +- .../binary_port.rs => binary_port/src/lib.rs | 40 +- .../src}/minimal_block_info.rs | 17 +- .../src}/node_status.rs | 12 +- .../src}/payload_type.rs | 43 +- .../src/speculative_execution_result.rs | 118 +++ .../src}/state_request.rs | 12 +- .../src}/type_wrappers.rs | 50 +- execution_engine/src/engine_state/error.rs | 91 +- .../src/engine_state/executable_item.rs | 910 ++++++++++++++++++ .../src/engine_state/execution_kind.rs | 165 +++- .../src/engine_state/execution_result.rs | 2 +- execution_engine/src/engine_state/mod.rs | 190 +++- execution_engine/src/engine_state/wasm_v1.rs | 238 +++++ execution_engine/src/execution/error.rs | 33 +- execution_engine/src/execution/executor.rs | 22 +- execution_engine/src/runtime/mod.rs | 15 +- execution_engine/src/runtime/stack.rs | 1 - execution_engine/src/runtime_context/mod.rs | 24 +- execution_engine/src/runtime_context/tests.rs | 8 +- .../test_support/src/wasm_test_builder.rs | 2 + .../tests/src/test/deploy/receipts.rs | 26 +- node/Cargo.toml | 1 + node/src/components/binary_port.rs | 488 +++++----- node/src/components/binary_port/event.rs | 2 +- node/src/components/binary_port/tests.rs | 19 +- .../components/consensus/era_supervisor.rs | 3 +- node/src/components/contract_runtime.rs | 45 +- .../components/contract_runtime/metrics.rs | 14 +- .../components/contract_runtime/operations.rs | 349 +++---- node/src/components/contract_runtime/tests.rs | 3 +- node/src/components/contract_runtime/types.rs | 160 +-- node/src/components/fetcher.rs | 2 +- node/src/components/fetcher/tests.rs | 8 +- node/src/components/gossiper/tests.rs | 8 +- node/src/components/rest_server/info.rs | 7 +- node/src/components/storage.rs | 2 +- node/src/components/storage/error.rs | 7 +- node/src/components/storage/tests.rs | 13 +- node/src/components/transaction_acceptor.rs | 75 +- .../components/transaction_acceptor/error.rs | 9 +- .../components/transaction_acceptor/tests.rs | 37 +- node/src/effect.rs | 39 +- node/src/effect/requests.rs | 62 +- node/src/reactor/main_reactor.rs | 10 +- .../reactor/main_reactor/tests/binary_port.rs | 25 +- node/src/types/status_feed.rs | 6 +- node/src/utils.rs | 10 +- storage/README.md | 6 +- .../lmdb/indexed_lmdb_block_store.rs | 9 +- .../block_store/lmdb/versioned_databases.rs | 2 +- storage/src/block_store/mod.rs | 38 + .../src/block_store}/record_id.rs | 6 +- storage/src/data_access_layer/balance.rs | 44 +- storage/src/global_state/state/mod.rs | 39 +- storage/src/lib.rs | 2 + storage/src/system/auction.rs | 3 + storage/src/system/mint/mint_native.rs | 35 +- storage/src/tracking_copy/error.rs | 3 + storage/src/tracking_copy/mod.rs | 35 +- types/benches/bytesrepr_bench.rs | 6 +- types/src/block/available_block_range.rs | 12 +- types/src/block/block_identifier.rs | 10 +- types/src/block/block_sync_status.rs | 17 +- types/src/block_time.rs | 14 +- types/src/chainspec/next_upgrade.rs | 9 +- types/src/digest.rs | 1 - types/src/gas.rs | 29 +- types/src/key.rs | 7 +- types/src/lib.rs | 1 - types/src/peers_map.rs | 17 +- .../stored_value/global_state_identifier.rs | 11 +- types/src/transaction.rs | 26 +- .../addressable_entity_identifier.rs | 23 +- types/src/transaction/deploy.rs | 16 +- types/src/transaction/deploy/error.rs | 8 +- types/src/transaction/pricing_mode.rs | 21 +- types/src/transaction/transaction_hash.rs | 41 +- types/src/transaction/transaction_v1.rs | 15 +- .../transaction/transaction_v1/errors_v1.rs | 8 +- .../transaction_v1/transaction_v1_hash.rs | 1 - types/src/transfer.rs | 30 +- utils/validation/src/generators.rs | 4 +- 93 files changed, 2921 insertions(+), 1333 deletions(-) create mode 100644 binary_port/README.md rename {types/src/binary_port => binary_port/src}/binary_request.rs (69%) rename {types/src/binary_port => binary_port/src}/binary_response.rs (93%) rename {types/src/binary_port => binary_port/src}/binary_response_and_request.rs (87%) rename {types/src/binary_port => binary_port/src}/binary_response_header.rs (95%) rename {types/src/binary_port => binary_port/src}/error_code.rs (51%) rename {types/src/binary_port => binary_port/src}/get_request.rs (95%) rename {types/src/binary_port => binary_port/src}/global_state_query_result.rs (93%) rename {types/src/binary_port => binary_port/src}/information_request.rs (99%) rename types/src/binary_port.rs => binary_port/src/lib.rs (50%) rename {types/src/binary_port => binary_port/src}/minimal_block_info.rs (89%) rename {types/src/binary_port => binary_port/src}/node_status.rs (97%) rename {types/src/binary_port => binary_port/src}/payload_type.rs (96%) create mode 100644 binary_port/src/speculative_execution_result.rs rename {types/src/binary_port => binary_port/src}/state_request.rs (97%) rename {types/src/binary_port => binary_port/src}/type_wrappers.rs (88%) create mode 100644 execution_engine/src/engine_state/executable_item.rs create mode 100644 execution_engine/src/engine_state/wasm_v1.rs rename {types/src/binary_port => storage/src/block_store}/record_id.rs (96%) diff --git a/Cargo.lock b/Cargo.lock index 6f22caee7e..a3479c55f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -467,6 +467,24 @@ dependencies = [ "casper-types", ] +[[package]] +name = "casper-binary-port" +version = "1.0.0" +dependencies = [ + "bincode", + "casper-execution-engine", + "casper-storage", + "casper-types", + "once_cell", + "rand", + "schemars", + "serde", + "serde-map-to-array", + "serde_json", + "serde_test", + "thiserror", +] + [[package]] name = "casper-contract" version = "3.0.0" @@ -609,6 +627,7 @@ dependencies = [ "base64 0.13.1", "bincode", "bytes", + "casper-binary-port", "casper-execution-engine", "casper-json-rpc", "casper-storage", diff --git a/Cargo.toml b/Cargo.toml index 311e39213c..415095a803 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ members = [ "types", "utils/global-state-update-gen", "utils/validation", + "binary_port" ] default-members = [ @@ -25,6 +26,7 @@ default-members = [ "types", "utils/global-state-update-gen", "utils/validation", + "binary_port", ] exclude = ["utils/nctl/remotes/casper-client-rs"] diff --git a/binary_port/README.md b/binary_port/README.md new file mode 100644 index 0000000000..80099cc02b --- /dev/null +++ b/binary_port/README.md @@ -0,0 +1,16 @@ +# `casper-binary-port` + +[![LOGO](https://raw.githubusercontent.com/casper-network/casper-node/master/images/casper-association-logo-primary.svg)](https://casper.network/) + +[![Build Status](https://drone-auto-casper-network.casperlabs.io/api/badges/casper-network/casper-node/status.svg?branch=dev)](http://drone-auto-casper-network.casperlabs.io/casper-network/casper-node) +[![Crates.io](https://img.shields.io/crates/v/casper-hashing)](https://crates.io/crates/casper-binary-port) +[![Documentation](https://docs.rs/casper-hashing/badge.svg)](https://docs.rs/casper-binary-port) +[![License](https://img.shields.io/badge/license-Apache-blue)](https://github.com/CasperLabs/casper-node/blob/master/LICENSE) + +Types for the binary port on a casper network node. + +[Node Operator Guide](https://docs.casperlabs.io/operators/) + +## License + +Licensed under the [Apache License Version 2.0](https://github.com/casper-network/casper-node/blob/master/LICENSE). diff --git a/types/src/binary_port/binary_request.rs b/binary_port/src/binary_request.rs similarity index 69% rename from types/src/binary_port/binary_request.rs rename to binary_port/src/binary_request.rs index b1c7ecefe5..0441c53e6a 100644 --- a/types/src/binary_port/binary_request.rs +++ b/binary_port/src/binary_request.rs @@ -1,18 +1,16 @@ use core::convert::TryFrom; -use crate::{ +use casper_types::{ bytesrepr::{self, FromBytes, ToBytes}, - BlockHeader, Digest, ProtocolVersion, Timestamp, Transaction, + ProtocolVersion, Transaction, }; -use alloc::vec::Vec; -use super::get_request::GetRequest; +use crate::get_request::GetRequest; #[cfg(test)] -use rand::Rng; - +use casper_types::testing::TestRng; #[cfg(test)] -use crate::{testing::TestRng, Block, TestBlockV1Builder}; +use rand::Rng; /// The header of a binary request. #[derive(Debug, PartialEq)] @@ -92,16 +90,8 @@ pub enum BinaryRequest { }, /// Request to execute a transaction speculatively. TrySpeculativeExec { - /// State root on top of which to execute deploy. - state_root_hash: Digest, - /// Block time. - block_time: Timestamp, - /// Protocol version used when creating the original block. - protocol_version: ProtocolVersion, /// Transaction to execute. transaction: Transaction, - /// Block header of block at which we should perform speculative execution. - speculative_exec_at_block: BlockHeader, }, } @@ -122,18 +112,9 @@ impl BinaryRequest { BinaryRequestTag::TryAcceptTransaction => Self::TryAcceptTransaction { transaction: Transaction::random(rng), }, - BinaryRequestTag::TrySpeculativeExec => { - let block_v1 = TestBlockV1Builder::new().build(rng); - let block = Block::V1(block_v1); - - Self::TrySpeculativeExec { - state_root_hash: Digest::random(rng), - block_time: Timestamp::random(rng), - protocol_version: ProtocolVersion::from_parts(rng.gen(), rng.gen(), rng.gen()), - transaction: Transaction::random(rng), - speculative_exec_at_block: block.take_header(), - } - } + BinaryRequestTag::TrySpeculativeExec => Self::TrySpeculativeExec { + transaction: Transaction::random(rng), + }, } } } @@ -149,19 +130,7 @@ impl ToBytes for BinaryRequest { match self { BinaryRequest::Get(inner) => inner.write_bytes(writer), BinaryRequest::TryAcceptTransaction { transaction } => transaction.write_bytes(writer), - BinaryRequest::TrySpeculativeExec { - transaction, - state_root_hash, - block_time, - protocol_version, - speculative_exec_at_block, - } => { - transaction.write_bytes(writer)?; - state_root_hash.write_bytes(writer)?; - block_time.write_bytes(writer)?; - protocol_version.write_bytes(writer)?; - speculative_exec_at_block.write_bytes(writer) - } + BinaryRequest::TrySpeculativeExec { transaction } => transaction.write_bytes(writer), } } @@ -169,19 +138,7 @@ impl ToBytes for BinaryRequest { match self { BinaryRequest::Get(inner) => inner.serialized_length(), BinaryRequest::TryAcceptTransaction { transaction } => transaction.serialized_length(), - BinaryRequest::TrySpeculativeExec { - transaction, - state_root_hash, - block_time, - protocol_version, - speculative_exec_at_block, - } => { - transaction.serialized_length() - + state_root_hash.serialized_length() - + block_time.serialized_length() - + protocol_version.serialized_length() - + speculative_exec_at_block.serialized_length() - } + BinaryRequest::TrySpeculativeExec { transaction } => transaction.serialized_length(), } } } @@ -204,20 +161,7 @@ impl TryFrom<(BinaryRequestTag, &[u8])> for BinaryRequest { } BinaryRequestTag::TrySpeculativeExec => { let (transaction, remainder) = FromBytes::from_bytes(bytes)?; - let (state_root_hash, remainder) = FromBytes::from_bytes(remainder)?; - let (block_time, remainder) = FromBytes::from_bytes(remainder)?; - let (protocol_version, remainder) = FromBytes::from_bytes(remainder)?; - let (speculative_exec_at_block, remainder) = FromBytes::from_bytes(remainder)?; - ( - BinaryRequest::TrySpeculativeExec { - transaction, - state_root_hash, - block_time, - protocol_version, - speculative_exec_at_block, - }, - remainder, - ) + (BinaryRequest::TrySpeculativeExec { transaction }, remainder) } }; if !remainder.is_empty() { @@ -277,7 +221,7 @@ pub struct InvalidBinaryRequestTag(u8); #[cfg(test)] mod tests { use super::*; - use crate::testing::TestRng; + use casper_types::testing::TestRng; #[test] fn header_bytesrepr_roundtrip() { diff --git a/types/src/binary_port/binary_response.rs b/binary_port/src/binary_response.rs similarity index 93% rename from types/src/binary_port/binary_response.rs rename to binary_port/src/binary_response.rs index f821bc3b7a..9b1043bbe7 100644 --- a/types/src/binary_port/binary_response.rs +++ b/binary_port/src/binary_response.rs @@ -1,19 +1,18 @@ -use crate::{ +use casper_storage::{block_store::record_id::RecordId, DbRawBytesSpec}; +use casper_types::{ bytesrepr::{self, Bytes, FromBytes, ToBytes}, ProtocolVersion, }; -use alloc::vec::Vec; - -#[cfg(test)] -use crate::testing::TestRng; -use super::{ +use crate::{ binary_response_header::BinaryResponseHeader, + error_code::ErrorCode, payload_type::{PayloadEntity, PayloadType}, - record_id::RecordId, - DbRawBytesSpec, ErrorCode, }; +#[cfg(test)] +use casper_types::testing::TestRng; + /// The response used in the binary port protocol. #[derive(Debug, PartialEq)] pub struct BinaryResponse { @@ -47,15 +46,12 @@ impl BinaryResponse { protocol_version: ProtocolVersion, ) -> Self { match spec { - Some(DbRawBytesSpec { - is_legacy, - raw_bytes, - }) => BinaryResponse { + Some(val) => BinaryResponse { header: BinaryResponseHeader::new( - Some(PayloadType::new_from_record_id(record_id, is_legacy)), + Some(PayloadType::new_from_record_id(record_id, val.is_legacy())), protocol_version, ), - payload: raw_bytes, + payload: val.raw_bytes(), }, None => BinaryResponse { header: BinaryResponseHeader::new_error(ErrorCode::NotFound, protocol_version), @@ -165,7 +161,7 @@ impl FromBytes for BinaryResponse { #[cfg(test)] mod tests { use super::*; - use crate::testing::TestRng; + use casper_types::testing::TestRng; #[test] fn bytesrepr_roundtrip() { diff --git a/types/src/binary_port/binary_response_and_request.rs b/binary_port/src/binary_response_and_request.rs similarity index 87% rename from types/src/binary_port/binary_response_and_request.rs rename to binary_port/src/binary_response_and_request.rs index 78d4785d41..3a497d7065 100644 --- a/types/src/binary_port/binary_response_and_request.rs +++ b/binary_port/src/binary_response_and_request.rs @@ -1,17 +1,13 @@ -use crate::bytesrepr::{self, Bytes, FromBytes, ToBytes}; +use casper_storage::{block_store::record_id::RecordId, DbRawBytesSpec}; +use casper_types::{ + bytesrepr::{self, Bytes, FromBytes, ToBytes}, + ProtocolVersion, +}; -use super::binary_response::BinaryResponse; -#[cfg(any(feature = "testing", test))] -use super::payload_type::PayloadEntity; -use alloc::vec::Vec; - -#[cfg(any(feature = "testing", test))] -use super::record_id::RecordId; -#[cfg(any(feature = "testing", test))] -use crate::ProtocolVersion; +use crate::{binary_response::BinaryResponse, payload_type::PayloadEntity}; #[cfg(test)] -use crate::testing::TestRng; +use casper_types::testing::TestRng; /// The binary response along with the original binary request attached. #[derive(Debug, PartialEq)] @@ -31,15 +27,12 @@ impl BinaryResponseAndRequest { } } - /// Returns a new binary response with specified data and no original request. - #[cfg(any(feature = "testing", test))] + /// Returns a new binary response with specified data and no original request. pub fn new_test_response( record_id: RecordId, data: &A, protocol_version: ProtocolVersion, ) -> BinaryResponseAndRequest { - use super::DbRawBytesSpec; - let response = BinaryResponse::from_db_raw_bytes( record_id, Some(DbRawBytesSpec::new_current(&data.to_bytes().unwrap())), @@ -49,14 +42,11 @@ impl BinaryResponseAndRequest { } /// Returns a new binary response with specified legacy data and no original request. - #[cfg(any(feature = "testing", test))] pub fn new_legacy_test_response( record_id: RecordId, data: &A, protocol_version: ProtocolVersion, ) -> BinaryResponseAndRequest { - use super::DbRawBytesSpec; - let response = BinaryResponse::from_db_raw_bytes( record_id, Some(DbRawBytesSpec::new_legacy( @@ -143,7 +133,7 @@ impl From for BinaryResponse { #[cfg(test)] mod tests { use super::*; - use crate::testing::TestRng; + use casper_types::testing::TestRng; #[test] fn bytesrepr_roundtrip() { diff --git a/types/src/binary_port/binary_response_header.rs b/binary_port/src/binary_response_header.rs similarity index 95% rename from types/src/binary_port/binary_response_header.rs rename to binary_port/src/binary_response_header.rs index 025a9068e6..fb25deea25 100644 --- a/types/src/binary_port/binary_response_header.rs +++ b/binary_port/src/binary_response_header.rs @@ -1,15 +1,14 @@ -#[cfg(test)] -use crate::testing::TestRng; -use crate::{ +use crate::{error_code::ErrorCode, payload_type::PayloadType}; +use casper_types::{ bytesrepr::{self, FromBytes, ToBytes}, ProtocolVersion, }; -use alloc::vec::Vec; + +#[cfg(test)] +use casper_types::testing::TestRng; #[cfg(test)] use rand::Rng; -use super::{ErrorCode, PayloadType}; - /// Header of the binary response. #[derive(Debug, PartialEq)] pub struct BinaryResponseHeader { @@ -122,7 +121,7 @@ impl FromBytes for BinaryResponseHeader { #[cfg(test)] mod tests { use super::*; - use crate::testing::TestRng; + use casper_types::testing::TestRng; #[test] fn bytesrepr_roundtrip() { diff --git a/types/src/binary_port/error_code.rs b/binary_port/src/error_code.rs similarity index 51% rename from types/src/binary_port/error_code.rs rename to binary_port/src/error_code.rs index 769205371c..c17bdef487 100644 --- a/types/src/binary_port/error_code.rs +++ b/binary_port/src/error_code.rs @@ -1,46 +1,51 @@ use core::{convert::TryFrom, fmt}; +use casper_execution_engine::engine_state::Error as EngineError; +use casper_types::InvalidTransaction; + /// The error code indicating the result of handling the binary request. -#[derive(Debug, Clone)] -#[cfg_attr(feature = "std", derive(thiserror::Error))] +#[derive(Debug, Clone, thiserror::Error)] #[repr(u8)] pub enum ErrorCode { /// Request executed correctly. - #[cfg_attr(feature = "std", error("request executed correctly"))] + #[error("request executed correctly")] NoError = 0, /// This function is disabled. - #[cfg_attr(feature = "std", error("this function is disabled"))] + #[error("this function is disabled")] FunctionDisabled = 1, /// Data not found. - #[cfg_attr(feature = "std", error("data not found"))] + #[error("data not found")] NotFound = 2, /// Root not found. - #[cfg_attr(feature = "std", error("root not found"))] + #[error("root not found")] RootNotFound = 3, /// Invalid deploy item variant. - #[cfg_attr(feature = "std", error("invalid deploy item variant"))] - InvalidDeployItemVariant = 4, + #[error("invalid deploy item variant")] + InvalidItemVariant = 4, /// Wasm preprocessing. - #[cfg_attr(feature = "std", error("wasm preprocessing"))] + #[error("wasm preprocessing")] WasmPreprocessing = 5, /// Invalid protocol version. - #[cfg_attr(feature = "std", error("unsupported protocol version"))] + #[error("unsupported protocol version")] UnsupportedProtocolVersion = 6, /// Invalid transaction. - #[cfg_attr(feature = "std", error("invalid transaction"))] + #[error("invalid transaction")] InvalidTransaction = 7, /// Internal error. - #[cfg_attr(feature = "std", error("internal error"))] + #[error("internal error")] InternalError = 8, /// The query to global state failed. - #[cfg_attr(feature = "std", error("the query to global state failed"))] - QueryFailedToExecute = 9, + #[error("the query to global state failed")] + FailedQuery = 9, /// Bad request. - #[cfg_attr(feature = "std", error("bad request"))] + #[error("bad request")] BadRequest = 10, /// Received an unsupported type of request. - #[cfg_attr(feature = "std", error("unsupported request"))] + #[error("unsupported request")] UnsupportedRequest = 11, + /// This node has no complete blocks. + #[error("no complete blocks")] + NoCompleteBlocks = 12, } impl TryFrom for ErrorCode { @@ -52,14 +57,15 @@ impl TryFrom for ErrorCode { 1 => Ok(ErrorCode::FunctionDisabled), 2 => Ok(ErrorCode::NotFound), 3 => Ok(ErrorCode::RootNotFound), - 4 => Ok(ErrorCode::InvalidDeployItemVariant), + 4 => Ok(ErrorCode::InvalidItemVariant), 5 => Ok(ErrorCode::WasmPreprocessing), 6 => Ok(ErrorCode::UnsupportedProtocolVersion), 7 => Ok(ErrorCode::InvalidTransaction), 8 => Ok(ErrorCode::InternalError), - 9 => Ok(ErrorCode::QueryFailedToExecute), + 9 => Ok(ErrorCode::FailedQuery), 10 => Ok(ErrorCode::BadRequest), 11 => Ok(ErrorCode::UnsupportedRequest), + 12 => Ok(ErrorCode::NoCompleteBlocks), _ => Err(UnknownErrorCode), } } @@ -75,5 +81,24 @@ impl fmt::Display for UnknownErrorCode { } } -#[cfg(feature = "std")] impl std::error::Error for UnknownErrorCode {} + +impl From for ErrorCode { + fn from(err: EngineError) -> Self { + match err { + EngineError::RootNotFound(_) => ErrorCode::RootNotFound, + EngineError::Deploy => ErrorCode::InvalidTransaction, + EngineError::InvalidItemVariant(_) => ErrorCode::InvalidItemVariant, + EngineError::WasmPreprocessing(_) => ErrorCode::WasmPreprocessing, + EngineError::InvalidProtocolVersion(_) => ErrorCode::UnsupportedProtocolVersion, + EngineError::Deprecated(_) => ErrorCode::FunctionDisabled, + _ => ErrorCode::InternalError, + } + } +} + +impl From for ErrorCode { + fn from(_value: InvalidTransaction) -> Self { + ErrorCode::InvalidTransaction + } +} diff --git a/types/src/binary_port/get_request.rs b/binary_port/src/get_request.rs similarity index 95% rename from types/src/binary_port/get_request.rs rename to binary_port/src/get_request.rs index 01fb8f23b7..e11af5ff09 100644 --- a/types/src/binary_port/get_request.rs +++ b/binary_port/src/get_request.rs @@ -1,13 +1,11 @@ -use crate::bytesrepr::{self, Bytes, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}; -use alloc::vec::Vec; +use casper_types::bytesrepr::{self, Bytes, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}; -#[cfg(test)] -use rand::Rng; +use crate::state_request::GlobalStateRequest; #[cfg(test)] -use crate::testing::TestRng; - -use super::state_request::GlobalStateRequest; +use casper_types::testing::TestRng; +#[cfg(test)] +use rand::Rng; const RECORD_TAG: u8 = 0; const INFORMATION_TAG: u8 = 1; @@ -134,7 +132,7 @@ impl FromBytes for GetRequest { #[cfg(test)] mod tests { use super::*; - use crate::testing::TestRng; + use casper_types::testing::TestRng; #[test] fn bytesrepr_roundtrip() { diff --git a/types/src/binary_port/global_state_query_result.rs b/binary_port/src/global_state_query_result.rs similarity index 93% rename from types/src/binary_port/global_state_query_result.rs rename to binary_port/src/global_state_query_result.rs index a6592da97d..cf69037e60 100644 --- a/types/src/binary_port/global_state_query_result.rs +++ b/binary_port/src/global_state_query_result.rs @@ -1,17 +1,16 @@ //! The result of the query for the global state value. -use crate::{ +use casper_types::{ bytesrepr::{self, FromBytes, ToBytes}, global_state::TrieMerkleProof, Key, StoredValue, }; -use alloc::vec::Vec; #[cfg(test)] -use crate::testing::TestRng; +use casper_types::testing::TestRng; #[cfg(test)] -use crate::{ByteCode, ByteCodeKind}; +use casper_types::{ByteCode, ByteCodeKind}; /// Carries the successful result of the global state query. #[derive(Debug, PartialEq, Clone)] @@ -38,7 +37,7 @@ impl GlobalStateQueryResult { #[cfg(test)] pub(crate) fn random_invalid(rng: &mut TestRng) -> Self { - use crate::{global_state::TrieMerkleProofStep, CLValue}; + use casper_types::{global_state::TrieMerkleProofStep, CLValue}; use rand::Rng; // Note: This does NOT create a logically-valid struct. Instance created by this function // should be used in `bytesrepr` tests only. @@ -102,7 +101,7 @@ impl FromBytes for GlobalStateQueryResult { #[cfg(test)] mod tests { use super::*; - use crate::testing::TestRng; + use casper_types::testing::TestRng; #[test] fn bytesrepr_roundtrip() { diff --git a/types/src/binary_port/information_request.rs b/binary_port/src/information_request.rs similarity index 99% rename from types/src/binary_port/information_request.rs rename to binary_port/src/information_request.rs index a3ae67f60e..648db76dc8 100644 --- a/types/src/binary_port/information_request.rs +++ b/binary_port/src/information_request.rs @@ -1,18 +1,16 @@ -use alloc::vec::Vec; use core::convert::TryFrom; #[cfg(test)] use rand::Rng; +use crate::get_request::GetRequest; #[cfg(test)] -use crate::testing::TestRng; -use crate::{ +use casper_types::testing::TestRng; +use casper_types::{ bytesrepr::{self, FromBytes, ToBytes}, BlockIdentifier, TransactionHash, }; -use super::GetRequest; - /// Request for information from the node. #[derive(Clone, Debug, PartialEq)] pub enum InformationRequest { @@ -348,7 +346,7 @@ pub struct UnknownInformationRequestTag(u16); #[cfg(test)] mod tests { use super::*; - use crate::testing::TestRng; + use casper_types::testing::TestRng; #[test] fn tag_roundtrip() { diff --git a/types/src/binary_port.rs b/binary_port/src/lib.rs similarity index 50% rename from types/src/binary_port.rs rename to binary_port/src/lib.rs index e7df629708..80093c7c61 100644 --- a/types/src/binary_port.rs +++ b/binary_port/src/lib.rs @@ -1,4 +1,5 @@ -//! The binary port. +//! A Rust library for types used by the binary port of a casper node. + mod binary_request; mod binary_response; mod binary_response_and_request; @@ -8,10 +9,9 @@ mod get_request; mod global_state_query_result; mod information_request; mod minimal_block_info; -#[cfg(any(feature = "std", test))] mod node_status; mod payload_type; -mod record_id; +mod speculative_execution_result; mod state_request; mod type_wrappers; @@ -23,42 +23,12 @@ pub use error_code::ErrorCode; pub use get_request::GetRequest; pub use global_state_query_result::GlobalStateQueryResult; pub use information_request::{InformationRequest, InformationRequestTag}; -#[cfg(any(feature = "std", test))] pub use minimal_block_info::MinimalBlockInfo; -#[cfg(any(feature = "std", test))] pub use node_status::NodeStatus; pub use payload_type::{PayloadEntity, PayloadType}; -pub use record_id::RecordId; +pub use speculative_execution_result::SpeculativeExecutionResult; pub use state_request::GlobalStateRequest; pub use type_wrappers::{ ConsensusStatus, ConsensusValidatorChanges, GetTrieFullResult, LastProgress, NetworkName, - ReactorStateName, SpeculativeExecutionResult, TransactionWithExecutionInfo, Uptime, + ReactorStateName, TransactionWithExecutionInfo, Uptime, }; - -use alloc::vec::Vec; - -/// Stores raw bytes from the DB along with the flag indicating whether data come from legacy or -/// current version of the DB. -#[derive(Debug)] -pub struct DbRawBytesSpec { - is_legacy: bool, - raw_bytes: Vec, -} - -impl DbRawBytesSpec { - /// Creates a variant indicating that raw bytes are coming from the legacy database. - pub fn new_legacy(raw_bytes: &[u8]) -> Self { - Self { - is_legacy: true, - raw_bytes: raw_bytes.to_vec(), - } - } - - /// Creates a variant indicating that raw bytes are coming from the current database. - pub fn new_current(raw_bytes: &[u8]) -> Self { - Self { - is_legacy: false, - raw_bytes: raw_bytes.to_vec(), - } - } -} diff --git a/types/src/binary_port/minimal_block_info.rs b/binary_port/src/minimal_block_info.rs similarity index 89% rename from types/src/binary_port/minimal_block_info.rs rename to binary_port/src/minimal_block_info.rs index 7e4708951c..21552d0795 100644 --- a/types/src/binary_port/minimal_block_info.rs +++ b/binary_port/src/minimal_block_info.rs @@ -1,24 +1,19 @@ -use crate::{ +use casper_types::{ bytesrepr::{self, FromBytes, ToBytes}, Block, BlockHash, Digest, EraId, PublicKey, Timestamp, }; -use alloc::vec::Vec; -#[cfg(feature = "json-schema")] -use schemars::JsonSchema; -#[cfg(any(feature = "std", test))] use serde::{Deserialize, Serialize}; #[cfg(test)] use rand::Rng; +use schemars::JsonSchema; #[cfg(test)] -use crate::testing::TestRng; +use casper_types::testing::TestRng; /// Minimal info about a `Block` needed to satisfy the node status request. -#[derive(Debug, PartialEq, Eq)] -#[cfg_attr(any(feature = "std", test), derive(Serialize, Deserialize))] -#[cfg_attr(feature = "json-schema", derive(JsonSchema))] -#[cfg_attr(any(feature = "std", test), serde(deny_unknown_fields))] +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] +#[serde(deny_unknown_fields)] pub struct MinimalBlockInfo { hash: BlockHash, timestamp: Timestamp, @@ -111,7 +106,7 @@ impl From for MinimalBlockInfo { #[cfg(test)] mod tests { use super::*; - use crate::testing::TestRng; + use casper_types::testing::TestRng; #[test] fn bytesrepr_roundtrip() { diff --git a/types/src/binary_port/node_status.rs b/binary_port/src/node_status.rs similarity index 97% rename from types/src/binary_port/node_status.rs rename to binary_port/src/node_status.rs index 9b52a18305..fd85d315b0 100644 --- a/types/src/binary_port/node_status.rs +++ b/binary_port/src/node_status.rs @@ -1,17 +1,15 @@ -use crate::{ +use casper_types::{ bytesrepr::{self, FromBytes, ToBytes}, AvailableBlockRange, BlockSynchronizerStatus, Digest, NextUpgrade, Peers, PublicKey, TimeDiff, Timestamp, }; -use alloc::{string::String, vec::Vec}; #[cfg(test)] -use rand::Rng; - +use casper_types::testing::TestRng; #[cfg(test)] -use crate::testing::TestRng; +use rand::Rng; -use super::{type_wrappers::ReactorStateName, MinimalBlockInfo}; +use crate::{minimal_block_info::MinimalBlockInfo, type_wrappers::ReactorStateName}; /// Status information about the node. #[derive(Debug, PartialEq)] @@ -161,7 +159,7 @@ impl ToBytes for NodeStatus { #[cfg(test)] mod tests { use super::*; - use crate::testing::TestRng; + use casper_types::testing::TestRng; #[test] fn bytesrepr_roundtrip() { diff --git a/types/src/binary_port/payload_type.rs b/binary_port/src/payload_type.rs similarity index 96% rename from types/src/binary_port/payload_type.rs rename to binary_port/src/payload_type.rs index 89d692780d..73f0fc18fd 100644 --- a/types/src/binary_port/payload_type.rs +++ b/binary_port/src/payload_type.rs @@ -6,32 +6,31 @@ use schemars::JsonSchema; #[cfg(test)] use rand::Rng; -use alloc::vec::Vec; +use casper_execution_engine::engine_state::WasmV1Result; +use casper_storage::block_store::record_id::RecordId; use core::{convert::TryFrom, fmt}; #[cfg(test)] -use crate::testing::TestRng; +use casper_types::testing::TestRng; -#[cfg(any(feature = "std", test))] -use super::NodeStatus; -use crate::{ +use casper_types::{ bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, execution::{ExecutionResult, ExecutionResultV1}, AvailableBlockRange, BlockBody, BlockBodyV1, BlockHeader, BlockHeaderV1, BlockSignatures, BlockSignaturesV1, BlockSynchronizerStatus, Deploy, Peers, SignedBlock, StoredValue, Transaction, Transfer, }; -#[cfg(any(feature = "std", test))] -use crate::{ChainspecRawBytes, NextUpgrade}; -use super::{ +use casper_types::{ChainspecRawBytes, NextUpgrade}; + +use crate::{ global_state_query_result::GlobalStateQueryResult, - record_id::RecordId, + node_status::NodeStatus, + speculative_execution_result::SpeculativeExecutionResult, type_wrappers::{ ConsensusStatus, ConsensusValidatorChanges, GetTrieFullResult, LastProgress, NetworkName, - ReactorStateName, SpeculativeExecutionResult, + ReactorStateName, TransactionWithExecutionInfo, Uptime, }, - TransactionWithExecutionInfo, Uptime, }; /// A type of the payload being returned in a binary response. @@ -63,6 +62,8 @@ pub enum PayloadType { ExecutionResultV1, /// Execution result. ExecutionResult, + /// Wasm V1 execution result. + WasmV1Result, /// Transfers. Transfers, /// Finalized deploy approvals. @@ -242,6 +243,7 @@ impl fmt::Display for PayloadType { PayloadType::StoredValues => write!(f, "StoredValues"), PayloadType::GetTrieFullResult => write!(f, "GetTrieFullResult"), PayloadType::NodeStatus => write!(f, "NodeStatus"), + PayloadType::WasmV1Result => write!(f, "WasmV1Result"), } } } @@ -280,6 +282,7 @@ const GLOBAL_STATE_QUERY_RESULT_TAG: u8 = 30; const STORED_VALUES_TAG: u8 = 31; const GET_TRIE_FULL_RESULT_TAG: u8 = 32; const NODE_STATUS_TAG: u8 = 33; +const WASM_V1_RESULT_TAG: u8 = 34; impl ToBytes for PayloadType { fn to_bytes(&self) -> Result, bytesrepr::Error> { @@ -288,6 +291,10 @@ impl ToBytes for PayloadType { Ok(buffer) } + fn serialized_length(&self) -> usize { + U8_SERIALIZED_LENGTH + } + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { match self { PayloadType::BlockHeaderV1 => BLOCK_HEADER_V1_TAG, @@ -324,13 +331,10 @@ impl ToBytes for PayloadType { PayloadType::StoredValues => STORED_VALUES_TAG, PayloadType::GetTrieFullResult => GET_TRIE_FULL_RESULT_TAG, PayloadType::NodeStatus => NODE_STATUS_TAG, + PayloadType::WasmV1Result => WASM_V1_RESULT_TAG, } .write_bytes(writer) } - - fn serialized_length(&self) -> usize { - U8_SERIALIZED_LENGTH - } } impl FromBytes for PayloadType { @@ -415,6 +419,10 @@ impl PayloadEntity for BlockSignaturesV1 { const PAYLOAD_TYPE: PayloadType = PayloadType::BlockSignaturesV1; } +impl PayloadEntity for WasmV1Result { + const PAYLOAD_TYPE: PayloadType = PayloadType::WasmV1Result; +} + impl PayloadEntity for ExecutionResult { const PAYLOAD_TYPE: PayloadType = PayloadType::ExecutionResult; } @@ -443,7 +451,6 @@ impl PayloadEntity for AvailableBlockRange { const PAYLOAD_TYPE: PayloadType = PayloadType::AvailableBlockRange; } -#[cfg(any(feature = "std", test))] impl PayloadEntity for ChainspecRawBytes { const PAYLOAD_TYPE: PayloadType = PayloadType::ChainspecRawBytes; } @@ -468,12 +475,10 @@ impl PayloadEntity for SpeculativeExecutionResult { const PAYLOAD_TYPE: PayloadType = PayloadType::SpeculativeExecutionResult; } -#[cfg(any(feature = "std", test))] impl PayloadEntity for NodeStatus { const PAYLOAD_TYPE: PayloadType = PayloadType::NodeStatus; } -#[cfg(any(feature = "std", test))] impl PayloadEntity for NextUpgrade { const PAYLOAD_TYPE: PayloadType = PayloadType::NextUpgrade; } @@ -505,7 +510,7 @@ impl PayloadEntity for ConsensusStatus { #[cfg(test)] mod tests { use super::*; - use crate::testing::TestRng; + use casper_types::testing::TestRng; #[test] fn bytesrepr_roundtrip() { diff --git a/binary_port/src/speculative_execution_result.rs b/binary_port/src/speculative_execution_result.rs new file mode 100644 index 0000000000..23d60e9c53 --- /dev/null +++ b/binary_port/src/speculative_execution_result.rs @@ -0,0 +1,118 @@ +use casper_execution_engine::engine_state::WasmV1Result; +use casper_types::{ + bytesrepr, + bytesrepr::{FromBytes, ToBytes}, + contract_messages::Messages, + execution::Effects, + Gas, InvalidTransaction, TransferAddr, +}; + +#[derive(Debug)] +pub struct SpeculativeExecutionResult { + /// List of transfers that happened during execution. + transfers: Vec, + /// Gas limit. + limit: Gas, + /// Gas consumed. + consumed: Gas, + /// Execution effects. + effects: Effects, + /// Messages emitted during execution. + messages: Messages, + /// Did the wasm execute successfully? + error: Option, +} + +impl From for SpeculativeExecutionResult { + fn from(invalid_transaction: InvalidTransaction) -> Self { + SpeculativeExecutionResult { + transfers: Default::default(), + limit: Default::default(), + consumed: Default::default(), + effects: Default::default(), + messages: Default::default(), + error: Some(format!("{}", invalid_transaction)), + } + } +} + +impl From for SpeculativeExecutionResult { + fn from(wasm_v1_result: WasmV1Result) -> Self { + let error = wasm_v1_result + .error() + .as_ref() + .map(|err| format!("{}", err)); + + SpeculativeExecutionResult { + transfers: wasm_v1_result.transfers().to_owned(), + limit: wasm_v1_result.limit(), + consumed: wasm_v1_result.consumed(), + effects: wasm_v1_result.effects().to_owned(), + messages: wasm_v1_result.messages().to_owned(), + error, + } + } +} + +impl ToBytes for SpeculativeExecutionResult { + fn to_bytes(&self) -> Result, bytesrepr::Error> { + let mut buffer = bytesrepr::allocate_buffer(self)?; + self.write_bytes(&mut buffer)?; + Ok(buffer) + } + + fn serialized_length(&self) -> usize { + ToBytes::serialized_length(&self.transfers) + + ToBytes::serialized_length(&self.limit) + + ToBytes::serialized_length(&self.consumed) + + ToBytes::serialized_length(&self.effects) + + ToBytes::serialized_length(&self.messages) + + ToBytes::serialized_length(&self.error) + } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + self.transfers.write_bytes(writer)?; + self.limit.write_bytes(writer)?; + self.consumed.write_bytes(writer)?; + self.effects.write_bytes(writer)?; + self.messages.write_bytes(writer)?; + self.error.write_bytes(writer) + } +} + +impl FromBytes for SpeculativeExecutionResult { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (transfers, bytes) = Vec::::from_bytes(bytes)?; + let (limit, bytes) = Gas::from_bytes(bytes)?; + let (consumed, bytes) = Gas::from_bytes(bytes)?; + let (effects, bytes) = Effects::from_bytes(bytes)?; + let (messages, bytes) = Messages::from_bytes(bytes)?; + let (error, bytes) = Option::::from_bytes(bytes)?; + Ok(( + SpeculativeExecutionResult { + transfers, + limit, + consumed, + effects, + messages, + error, + }, + bytes, + )) + } +} +// +// #[cfg(test)] +// mod tests { +// // use super::*; +// // use casper_types::testing::TestRng; +// +// #[test] +// fn bytesrepr_roundtrip() { +// todo!(); +// let rng = &mut TestRng::new(); +// +// let val = SpeculativeExecutionResult::random(rng); +// bytesrepr::test_serialization_roundtrip(&val); +// } +// } diff --git a/types/src/binary_port/state_request.rs b/binary_port/src/state_request.rs similarity index 97% rename from types/src/binary_port/state_request.rs rename to binary_port/src/state_request.rs index 0492c1e0f8..2ea753f1c5 100644 --- a/types/src/binary_port/state_request.rs +++ b/binary_port/src/state_request.rs @@ -1,11 +1,9 @@ -use alloc::{string::String, vec::Vec}; - +#[cfg(test)] +use casper_types::testing::TestRng; #[cfg(test)] use rand::Rng; -#[cfg(test)] -use crate::testing::TestRng; -use crate::{ +use casper_types::{ bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, Digest, GlobalStateIdentifier, Key, KeyTag, }; @@ -43,7 +41,7 @@ pub enum GlobalStateRequest { impl GlobalStateRequest { #[cfg(test)] pub(crate) fn random(rng: &mut TestRng) -> Self { - match rng.gen_range(0..3) { + match TestRng::gen_range(rng, 0..3) { 0 => { let path_count = rng.gen_range(10..20); let state_identifier = if rng.gen() { @@ -173,7 +171,7 @@ impl FromBytes for GlobalStateRequest { #[cfg(test)] mod tests { use super::*; - use crate::testing::TestRng; + use casper_types::testing::TestRng; #[test] fn bytesrepr_roundtrip() { diff --git a/types/src/binary_port/type_wrappers.rs b/binary_port/src/type_wrappers.rs similarity index 88% rename from types/src/binary_port/type_wrappers.rs rename to binary_port/src/type_wrappers.rs index de2094741b..8556e29278 100644 --- a/types/src/binary_port/type_wrappers.rs +++ b/binary_port/src/type_wrappers.rs @@ -1,17 +1,11 @@ use core::{convert::TryFrom, num::TryFromIntError, time::Duration}; +use std::collections::BTreeMap; -use alloc::{ - collections::BTreeMap, - string::{String, ToString}, - vec::Vec, -}; #[cfg(feature = "datasize")] use datasize::DataSize; -use crate::{ +use casper_types::{ bytesrepr::{self, Bytes, FromBytes, ToBytes}, - contract_messages::Messages, - execution::ExecutionResultV2, EraId, ExecutionInfo, PublicKey, TimeDiff, Timestamp, Transaction, ValidatorChange, }; @@ -161,22 +155,6 @@ impl From for Timestamp { } } -/// Type representing results of the speculative execution. -#[derive(Debug, PartialEq, Eq)] -pub struct SpeculativeExecutionResult(Option<(ExecutionResultV2, Messages)>); - -impl SpeculativeExecutionResult { - /// Constructs new speculative execution result. - pub fn new(value: Option<(ExecutionResultV2, Messages)>) -> Self { - Self(value) - } - - /// Returns the inner value. - pub fn into_inner(self) -> Option<(ExecutionResultV2, Messages)> { - self.0 - } -} - /// Type representing results of the get full trie request. #[derive(Debug, PartialEq, Eq)] pub struct GetTrieFullResult(Option); @@ -277,14 +255,14 @@ impl ToBytes for TransactionWithExecutionInfo { Ok(buffer) } + fn serialized_length(&self) -> usize { + self.transaction.serialized_length() + self.execution_info.serialized_length() + } + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { self.transaction.write_bytes(writer)?; self.execution_info.write_bytes(writer) } - - fn serialized_length(&self) -> usize { - self.transaction.serialized_length() + self.execution_info.serialized_length() - } } impl FromBytes for TransactionWithExecutionInfo { @@ -303,7 +281,6 @@ impl_bytesrepr_for_type_wrapper!(ConsensusValidatorChanges); impl_bytesrepr_for_type_wrapper!(NetworkName); impl_bytesrepr_for_type_wrapper!(ReactorStateName); impl_bytesrepr_for_type_wrapper!(LastProgress); -impl_bytesrepr_for_type_wrapper!(SpeculativeExecutionResult); impl_bytesrepr_for_type_wrapper!(GetTrieFullResult); #[cfg(test)] @@ -312,7 +289,7 @@ mod tests { use rand::Rng; use super::*; - use crate::testing::TestRng; + use casper_types::testing::TestRng; #[test] fn uptime_roundtrip() { @@ -348,19 +325,6 @@ mod tests { bytesrepr::test_serialization_roundtrip(&LastProgress::new(Timestamp::random(rng))); } - #[test] - fn speculative_execution_result_roundtrip() { - let rng = &mut TestRng::new(); - if rng.gen_bool(0.5) { - bytesrepr::test_serialization_roundtrip(&SpeculativeExecutionResult::new(None)); - } else { - bytesrepr::test_serialization_roundtrip(&SpeculativeExecutionResult::new(Some(( - ExecutionResultV2::random(rng), - rng.random_vec(0..20), - )))); - } - } - #[test] fn get_trie_full_result_roundtrip() { let rng = &mut TestRng::new(); diff --git a/execution_engine/src/engine_state/error.rs b/execution_engine/src/engine_state/error.rs index 0cf5ad0b12..d6d48be8b4 100644 --- a/execution_engine/src/engine_state/error.rs +++ b/execution_engine/src/engine_state/error.rs @@ -2,17 +2,8 @@ use datasize::DataSize; use thiserror::Error; -use casper_storage::{ - global_state::{self, state::CommitError}, - system::{ - genesis::GenesisError, protocol_upgrade::ProtocolUpgradeError, transfer::TransferError, - }, - tracking_copy::TrackingCopyError, -}; -use casper_types::{ - account::AccountHash, binary_port, bytesrepr, system::mint, ApiError, Digest, Key, KeyTag, - PackageHash, ProtocolVersion, -}; +use casper_storage::{system::transfer::TransferError, tracking_copy::TrackingCopyError}; +use casper_types::{bytesrepr, system::mint, ApiError, Digest, ProtocolVersion}; use crate::{ execution::ExecError, @@ -29,24 +20,12 @@ pub enum Error { /// Protocol version used in the deploy is invalid. #[error("Invalid protocol version: {0}")] InvalidProtocolVersion(ProtocolVersion), - /// Genesis error. - #[error("{0:?}")] - Genesis(Box), /// WASM preprocessing error. #[error("Wasm preprocessing error: {0}")] WasmPreprocessing(#[from] PreprocessingError), - /// WASM serialization error. - #[error("Wasm serialization error: {0:?}")] - WasmSerialization(#[from] casper_wasm::SerializationError), /// Contract execution error. #[error(transparent)] Exec(ExecError), - /// Storage error. - #[error("Storage error: {0}")] - Storage(#[from] global_state::error::Error), - /// Authorization error. - #[error("Authorization failure: not authorized.")] - Authorization, /// Payment code provided insufficient funds for execution. #[error("Insufficient payment")] InsufficientPayment, @@ -68,57 +47,15 @@ pub enum Error { /// Invalid key variant. #[error("Unsupported key type")] InvalidKeyVariant, - /// Protocol upgrade error. - #[error("Protocol upgrade error: {0}")] - ProtocolUpgrade(#[from] ProtocolUpgradeError), /// Invalid deploy item variant. #[error("Unsupported deploy item variant: {0}")] - InvalidDeployItemVariant(String), - /// Commit error. - #[error(transparent)] - CommitError(#[from] CommitError), - /// Missing system contract registry. - #[error("Missing system contract registry")] - MissingSystemContractRegistry, + InvalidItemVariant(String), /// Missing system contract hash. #[error("Missing system contract hash: {0}")] MissingSystemContractHash(String), - /// Missing checksum registry. - #[error("Missing checksum registry")] - MissingChecksumRegistry, /// An attempt to push to the runtime stack while already at the maximum height. #[error("Runtime stack overflow")] RuntimeStackOverflow, - /// Failed to get the set of keys matching the specified tag. - #[error("Failed to get keys of kind: {0:?}")] - FailedToGetKeys(KeyTag), - /// Failed to get the purses stored under Key::Withdraw - #[error("Failed to get stored values under withdraws")] - FailedToGetStoredWithdraws, - /// Failed to convert the StoredValue into WithdrawPurse. - #[error("Failed to convert the stored value to a withdraw purse")] - FailedToGetWithdrawPurses, - /// Failed to retrieve the unbonding delay from the auction state. - #[error("Failed to retrieve the unbonding delay from the auction state")] - FailedToRetrieveUnbondingDelay, - /// Failed to retrieve the current EraId from the auction state. - #[error("Failed to retrieve the era_id from the auction state")] - FailedToRetrieveEraId, - /// Failed to put a trie node into global state because some of its children were missing. - #[error("Failed to put a trie into global state because some of its children were missing")] - MissingTrieNodeChildren(Vec), - /// Failed to retrieve contract record by a given account hash. - #[error("Failed to retrieve contract by account hash {0}")] - MissingContractByAccountHash(AccountHash), - /// Failed to retrieve the entity's package - #[error("Failed to retrieve the entity package as {0}")] - MissingEntityPackage(PackageHash), - /// Failed to retrieve accumulation purse from handle payment system contract. - #[error("Failed to retrieve accumulation purse from the handle payment contract")] - FailedToRetrieveAccumulationPurse, - /// Failed to prune listed keys. - #[error("Pruning attempt failed.")] - FailedToPrune(Vec), /// Storage error. #[error("Tracking copy error: {0}")] TrackingCopy(TrackingCopyError), @@ -128,6 +65,9 @@ pub enum Error { /// Deprecated functionality. #[error("Deprecated: {0}")] Deprecated(String), + /// Could not derive a valid item to execute. + #[error("Invalid executable item")] + InvalidExecutableItem, } impl Error { @@ -170,12 +110,6 @@ impl From for Error { } } -impl From> for Error { - fn from(genesis_error: Box) -> Self { - Self::Genesis(genesis_error) - } -} - impl From for Error { fn from(_: stack::RuntimeStackOverflow) -> Self { Self::RuntimeStackOverflow @@ -188,19 +122,6 @@ impl From for Error { } } -impl From for binary_port::ErrorCode { - fn from(err: Error) -> Self { - match err { - Error::RootNotFound(_) => binary_port::ErrorCode::RootNotFound, - Error::InvalidDeployItemVariant(_) => binary_port::ErrorCode::InvalidDeployItemVariant, - Error::WasmPreprocessing(_) => binary_port::ErrorCode::WasmPreprocessing, - Error::InvalidProtocolVersion(_) => binary_port::ErrorCode::UnsupportedProtocolVersion, - Error::Deploy => binary_port::ErrorCode::InvalidTransaction, - _ => binary_port::ErrorCode::InternalError, - } - } -} - impl DataSize for Error { const IS_DYNAMIC: bool = true; diff --git a/execution_engine/src/engine_state/executable_item.rs b/execution_engine/src/engine_state/executable_item.rs new file mode 100644 index 0000000000..9811309d9d --- /dev/null +++ b/execution_engine/src/engine_state/executable_item.rs @@ -0,0 +1,910 @@ +//! Code supporting an executable item. +use core::fmt::{self, Debug, Display, Formatter}; +use std::convert::TryFrom; + +#[cfg(feature = "datasize")] +use datasize::DataSize; + +use hex_fmt::HexFmt; + +use serde::{Deserialize, Serialize}; + +use casper_types::{ + account::AccountHash, + addressable_entity::DEFAULT_ENTRY_POINT_NAME, + bytesrepr::{self, Bytes, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, + package::{EntityVersion, PackageHash}, + runtime_args, + system::mint::ARG_AMOUNT, + AddressableEntityHash, AddressableEntityIdentifier, EntityAddr, ExecutableDeployItem, Gas, + Motes, PackageIdentifier, Phase, PublicKey, RuntimeArgs, Transaction, + TransactionInvocationTarget, TransactionRuntime, TransactionTarget, URef, U512, +}; + +#[cfg(test)] +use casper_types::testing::TestRng; +#[cfg(test)] +use rand::distributions::Alphanumeric; +#[cfg(test)] +use rand::distributions::Distribution; +#[cfg(test)] +use rand::distributions::Standard; +#[cfg(test)] +use rand::Rng; + +const TAG_LENGTH: usize = U8_SERIALIZED_LENGTH; +const MODULE_BYTES_TAG: u8 = 0; +const BY_HASH_TAG: u8 = 1; +const BY_NAME_TAG: u8 = 2; +const BY_PACKAGE_HASH: u8 = 3; +const BY_PACKAGE_NAME: u8 = 4; +const BY_ADDR_TAG: u8 = 5; + +/// Identifier for an [`ExecutableItem`]. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +pub enum ExecutableItemIdentifier { + /// The item is of the type [`ExecutableItem::Wasm`] + Module, + /// The item is a variation of a stored contract. + AddressableEntity(AddressableEntityIdentifier), + /// The item is a variation of a stored contract package. + Package(PackageIdentifier), + /// The item is a native transfer. + Transfer, +} + +/// The executable component of a [``]. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +#[serde(deny_unknown_fields)] +pub enum ExecutableItem { + /// Executable specified as raw bytes that represent Wasm code and an instance of + /// [`RuntimeArgs`]. + Wasm { + /// Raw Wasm module bytes with 'call' exported as an entrypoint. + #[cfg_attr( + feature = "json-schema", + schemars(description = "Hex-encoded raw Wasm bytes.") + )] + module_bytes: Bytes, + /// Runtime arguments. + args: RuntimeArgs, + }, + /// Entity referenced by its [`AddressableEntityHash`], entry point and an instance of + /// [`RuntimeArgs`]. + ByHash { + /// entity hash. + hash: AddressableEntityHash, + /// Name of an entry point. + entry_point: String, + /// Runtime arguments. + args: RuntimeArgs, + }, + /// Entity referenced by its [`EntityAddr`], entry point and an instance of + /// [`RuntimeArgs`]. + ByAddress { + /// Entity address. + address: EntityAddr, + /// Name of an entry point. + entry_point: String, + /// Runtime arguments. + args: RuntimeArgs, + }, + /// Entity referenced by a named key existing in the signer's account context, entry + /// point and an instance of [`RuntimeArgs`]. + ByName { + /// Named key. + name: String, + /// Name of an entry point. + entry_point: String, + /// Runtime arguments. + args: RuntimeArgs, + }, + /// Entity referenced by its [`PackageHash`], entry point and an + /// instance of [`RuntimeArgs`]. + ByPackageHash { + /// Contract package hash + hash: PackageHash, + /// An optional version of the contract to call. It will default to the highest enabled + /// version if no value is specified. + version: Option, + /// Entry point name. + entry_point: String, + /// Runtime arguments. + args: RuntimeArgs, + }, + /// Entity referenced by a named key existing in the signer's account + /// context, entry point and an instance of [`RuntimeArgs`]. + ByPackageName { + /// Named key. + name: String, + /// An optional version of the contract to call. It will default to the highest enabled + /// version if no value is specified. + version: Option, + /// Entry point name. + entry_point: String, + /// Runtime arguments. + args: RuntimeArgs, + }, +} + +impl ExecutableItem { + /// Returns a new `ExecutableItem::Wasm`. + pub fn new_wasm(module_bytes: Bytes, args: RuntimeArgs) -> Self { + ExecutableItem::Wasm { module_bytes, args } + } + + /// Returns a new `ExecutableItem::Wasm` suitable for use as standard payment code + /// of a ``. + pub fn new_standard_payment>(amount: A) -> Self { + ExecutableItem::Wasm { + module_bytes: Bytes::new(), + args: runtime_args! { + ARG_AMOUNT => amount.into(), + }, + } + } + + /// Returns a new `ExecutableItem::ByHash`. + pub fn new_by_hash( + hash: AddressableEntityHash, + entry_point: String, + args: RuntimeArgs, + ) -> Self { + ExecutableItem::ByHash { + hash, + entry_point, + args, + } + } + + /// Returns a new `ExecutableItem::ByAddress`. + pub fn new_by_addr(addr: EntityAddr, entry_point: String, args: RuntimeArgs) -> Self { + ExecutableItem::ByAddress { + address: addr, + entry_point, + args, + } + } + + /// Returns a new `ExecutableItem::ByName`. + pub fn new_by_name(name: String, entry_point: String, args: RuntimeArgs) -> Self { + ExecutableItem::ByName { + name, + entry_point, + args, + } + } + + /// Returns a new `ExecutableItem::ByPackageHash`. + pub fn new_by_package_hash( + hash: PackageHash, + version: Option, + entry_point: String, + args: RuntimeArgs, + ) -> Self { + ExecutableItem::ByPackageHash { + hash, + version, + entry_point, + args, + } + } + + /// Returns a new `ExecutableItem::ByPackageName`. + pub fn new_by_package( + name: String, + version: Option, + entry_point: String, + args: RuntimeArgs, + ) -> Self { + ExecutableItem::ByPackageName { + name, + version, + entry_point, + args, + } + } + + /// Returns the entry point name. + pub fn entry_point_name(&self) -> &str { + match self { + ExecutableItem::Wasm { .. } => DEFAULT_ENTRY_POINT_NAME, + ExecutableItem::ByPackageName { entry_point, .. } + | ExecutableItem::ByPackageHash { entry_point, .. } + | ExecutableItem::ByAddress { entry_point, .. } + | ExecutableItem::ByName { entry_point, .. } + | ExecutableItem::ByHash { entry_point, .. } => entry_point, + } + } + + /// Returns the identifier of the `ExecutableItem`. + pub fn identifier(&self) -> ExecutableItemIdentifier { + match self { + ExecutableItem::Wasm { .. } => ExecutableItemIdentifier::Module, + ExecutableItem::ByHash { hash, .. } => ExecutableItemIdentifier::AddressableEntity( + AddressableEntityIdentifier::Hash(*hash), + ), + ExecutableItem::ByAddress { address, .. } => { + ExecutableItemIdentifier::AddressableEntity(AddressableEntityIdentifier::Addr( + *address, + )) + } + ExecutableItem::ByName { name, .. } => ExecutableItemIdentifier::AddressableEntity( + AddressableEntityIdentifier::Name(name.clone()), + ), + ExecutableItem::ByPackageHash { hash, version, .. } => { + ExecutableItemIdentifier::Package(PackageIdentifier::Hash { + package_hash: *hash, + version: *version, + }) + } + ExecutableItem::ByPackageName { name, version, .. } => { + ExecutableItemIdentifier::Package(PackageIdentifier::Name { + name: name.clone(), + version: *version, + }) + } + } + } + + /// Returns the identifier of the contract in the item, if present. + pub fn contract_identifier(&self) -> Option { + match self { + ExecutableItem::Wasm { .. } + | ExecutableItem::ByPackageHash { .. } + | ExecutableItem::ByPackageName { .. } => None, + ExecutableItem::ByHash { hash, .. } => Some(AddressableEntityIdentifier::Hash(*hash)), + ExecutableItem::ByAddress { address, .. } => { + Some(AddressableEntityIdentifier::Addr(*address)) + } + ExecutableItem::ByName { name, .. } => { + Some(AddressableEntityIdentifier::Name(name.clone())) + } + } + } + + /// Returns the identifier of the contract package in the item, if present. + pub fn contract_package_identifier(&self) -> Option { + match self { + ExecutableItem::Wasm { .. } + | ExecutableItem::ByAddress { .. } + | ExecutableItem::ByName { .. } + | ExecutableItem::ByHash { .. } => None, + + ExecutableItem::ByPackageHash { hash, version, .. } => Some(PackageIdentifier::Hash { + package_hash: *hash, + version: *version, + }), + ExecutableItem::ByPackageName { name, version, .. } => Some(PackageIdentifier::Name { + name: name.clone(), + version: *version, + }), + } + } + + /// Returns the runtime arguments. + pub fn args(&self) -> &RuntimeArgs { + match self { + ExecutableItem::Wasm { args, .. } + | ExecutableItem::ByAddress { args, .. } + | ExecutableItem::ByName { args, .. } + | ExecutableItem::ByHash { args, .. } + | ExecutableItem::ByPackageHash { args, .. } + | ExecutableItem::ByPackageName { args, .. } => args, + } + } + + /// Returns the payment amount from args (if any) as Gas. + pub fn payment_amount(&self, conv_rate: u64) -> Option { + let cl_value = self.args().get(ARG_AMOUNT)?; + let motes = cl_value.clone().into_t::().ok()?; + Gas::from_motes(Motes::new(motes), conv_rate) + } + + /// Returns `true` if this item is a native transfer. + pub fn is_transfer(&self) -> bool { + false + } + + /// Returns `true` if this item is a standard payment. + pub fn is_standard_payment(&self, phase: Phase) -> bool { + if phase != Phase::Payment { + return false; + } + + if let ExecutableItem::Wasm { module_bytes, .. } = self { + return module_bytes.is_empty(); + } + + false + } + + /// Returns `true` if the item is a contract identified by its name. + pub fn is_by_name(&self) -> bool { + matches!(self, ExecutableItem::ByPackageName { .. }) + || matches!(self, ExecutableItem::ByName { .. }) + } + + /// Returns the name of the contract or contract package, if the item is identified by + /// name. + pub fn by_name(&self) -> Option { + match self { + ExecutableItem::ByName { name, .. } | ExecutableItem::ByPackageName { name, .. } => { + Some(name.clone()) + } + ExecutableItem::Wasm { .. } + | ExecutableItem::ByAddress { .. } + | ExecutableItem::ByPackageHash { .. } + | ExecutableItem::ByHash { .. } => None, + } + } + + /// Returns `true` if the item is a stored contract. + pub fn is_addressable_entity(&self) -> bool { + matches!(self, ExecutableItem::ByAddress { .. }) + || matches!(self, ExecutableItem::ByName { .. }) + || matches!(self, ExecutableItem::ByAddress { .. }) + } + + /// Returns `true` if the item is a stored contract package. + pub fn is_package(&self) -> bool { + matches!(self, ExecutableItem::ByPackageHash { .. }) + || matches!(self, ExecutableItem::ByPackageName { .. }) + } + + /// Returns `true` if the item is [`ModuleBytes`]. + /// + /// [`ModuleBytes`]: ExecutableItem::Wasm + pub fn is_module_bytes(&self) -> bool { + matches!(self, Self::Wasm { .. }) + } + + /// Returns a random `ExecutableItem`. + #[cfg(test)] + pub fn random(rng: &mut TestRng) -> Self { + rng.gen() + } +} + +impl ToBytes for ExecutableItem { + fn to_bytes(&self) -> Result, bytesrepr::Error> { + let mut buffer = bytesrepr::allocate_buffer(self)?; + self.write_bytes(&mut buffer)?; + Ok(buffer) + } + + fn serialized_length(&self) -> usize { + TAG_LENGTH + + match self { + ExecutableItem::Wasm { module_bytes, args } => { + module_bytes.serialized_length() + args.serialized_length() + } + ExecutableItem::ByHash { + hash, + entry_point, + args, + } => { + hash.serialized_length() + + entry_point.serialized_length() + + args.serialized_length() + } + ExecutableItem::ByAddress { + address, + entry_point, + args, + } => { + address.serialized_length() + + entry_point.serialized_length() + + args.serialized_length() + } + ExecutableItem::ByName { + name, + entry_point, + args, + } => { + name.serialized_length() + + entry_point.serialized_length() + + args.serialized_length() + } + ExecutableItem::ByPackageHash { + hash, + version, + entry_point, + args, + } => { + hash.serialized_length() + + version.serialized_length() + + entry_point.serialized_length() + + args.serialized_length() + } + ExecutableItem::ByPackageName { + name, + version, + entry_point, + args, + } => { + name.serialized_length() + + version.serialized_length() + + entry_point.serialized_length() + + args.serialized_length() + } + } + } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + match self { + ExecutableItem::Wasm { module_bytes, args } => { + writer.push(MODULE_BYTES_TAG); + module_bytes.write_bytes(writer)?; + args.write_bytes(writer) + } + ExecutableItem::ByHash { + hash, + entry_point, + args, + } => { + writer.push(BY_HASH_TAG); + hash.write_bytes(writer)?; + entry_point.write_bytes(writer)?; + args.write_bytes(writer) + } + ExecutableItem::ByAddress { + address, + entry_point, + args, + } => { + writer.push(BY_ADDR_TAG); + address.write_bytes(writer)?; + entry_point.write_bytes(writer)?; + args.write_bytes(writer) + } + ExecutableItem::ByName { + name, + entry_point, + args, + } => { + writer.push(BY_NAME_TAG); + name.write_bytes(writer)?; + entry_point.write_bytes(writer)?; + args.write_bytes(writer) + } + ExecutableItem::ByPackageHash { + hash, + version, + entry_point, + args, + } => { + writer.push(BY_PACKAGE_HASH); + hash.write_bytes(writer)?; + version.write_bytes(writer)?; + entry_point.write_bytes(writer)?; + args.write_bytes(writer) + } + ExecutableItem::ByPackageName { + name, + version, + entry_point, + args, + } => { + writer.push(BY_PACKAGE_NAME); + name.write_bytes(writer)?; + version.write_bytes(writer)?; + entry_point.write_bytes(writer)?; + args.write_bytes(writer) + } + } + } +} + +impl FromBytes for ExecutableItem { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (tag, remainder) = u8::from_bytes(bytes)?; + match tag { + MODULE_BYTES_TAG => { + let (module_bytes, remainder) = Bytes::from_bytes(remainder)?; + let (args, remainder) = RuntimeArgs::from_bytes(remainder)?; + Ok((ExecutableItem::Wasm { module_bytes, args }, remainder)) + } + BY_ADDR_TAG => { + let (address, remainder) = EntityAddr::from_bytes(remainder)?; + let (entry_point, remainder) = String::from_bytes(remainder)?; + let (args, remainder) = RuntimeArgs::from_bytes(remainder)?; + Ok(( + ExecutableItem::ByAddress { + address, + entry_point, + args, + }, + remainder, + )) + } + BY_HASH_TAG => { + let (hash, remainder) = AddressableEntityHash::from_bytes(remainder)?; + let (entry_point, remainder) = String::from_bytes(remainder)?; + let (args, remainder) = RuntimeArgs::from_bytes(remainder)?; + Ok(( + ExecutableItem::ByHash { + hash, + entry_point, + args, + }, + remainder, + )) + } + BY_NAME_TAG => { + let (name, remainder) = String::from_bytes(remainder)?; + let (entry_point, remainder) = String::from_bytes(remainder)?; + let (args, remainder) = RuntimeArgs::from_bytes(remainder)?; + Ok(( + ExecutableItem::ByName { + name, + entry_point, + args, + }, + remainder, + )) + } + BY_PACKAGE_HASH => { + let (hash, remainder) = PackageHash::from_bytes(remainder)?; + let (version, remainder) = Option::::from_bytes(remainder)?; + let (entry_point, remainder) = String::from_bytes(remainder)?; + let (args, remainder) = RuntimeArgs::from_bytes(remainder)?; + Ok(( + ExecutableItem::ByPackageHash { + hash, + version, + entry_point, + args, + }, + remainder, + )) + } + BY_PACKAGE_NAME => { + let (name, remainder) = String::from_bytes(remainder)?; + let (version, remainder) = Option::::from_bytes(remainder)?; + let (entry_point, remainder) = String::from_bytes(remainder)?; + let (args, remainder) = RuntimeArgs::from_bytes(remainder)?; + Ok(( + ExecutableItem::ByPackageName { + name, + version, + entry_point, + args, + }, + remainder, + )) + } + _ => Err(bytesrepr::Error::Formatting), + } + } +} + +impl Display for ExecutableItem { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + ExecutableItem::Wasm { module_bytes, .. } => { + write!(f, "module-bytes [{} bytes]", module_bytes.len()) + } + ExecutableItem::ByHash { + hash, entry_point, .. + } => write!( + f, + "by-hash: {:10}, entry-point: {}", + HexFmt(hash), + entry_point, + ), + ExecutableItem::ByAddress { + address, + entry_point, + .. + } => write!(f, "by-address: {}, entry-point: {}", address, entry_point,), + ExecutableItem::ByName { + name, entry_point, .. + } => write!(f, "by-name: {}, entry-point: {}", name, entry_point,), + ExecutableItem::ByPackageHash { + hash, + version: Some(ver), + entry_point, + .. + } => write!( + f, + "by-package-hash-and-version: {:10}, version: {}, entry-point: {}", + HexFmt(hash), + ver, + entry_point, + ), + ExecutableItem::ByPackageHash { + hash, entry_point, .. + } => write!( + f, + "by-package-hash: {:10}, version: latest, entry-point: {}", + HexFmt(hash), + entry_point, + ), + ExecutableItem::ByPackageName { + name, + version: Some(ver), + entry_point, + .. + } => write!( + f, + "by-package-name-and-version: {}, version: {}, entry-point: {}", + name, ver, entry_point, + ), + ExecutableItem::ByPackageName { + name, entry_point, .. + } => write!( + f, + "by-package-name: {}, version: latest, entry-point: {}", + name, entry_point, + ), + } + } +} + +impl Debug for ExecutableItem { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + ExecutableItem::Wasm { module_bytes, args } => f + .debug_struct("Wasm") + .field("module_bytes", &format!("[{} bytes]", module_bytes.len())) + .field("args", args) + .finish(), + ExecutableItem::ByHash { + hash, + entry_point, + args, + } => f + .debug_struct("ByHash") + .field("hash", &base16::encode_lower(hash)) + .field("entry_point", &entry_point) + .field("args", args) + .finish(), + ExecutableItem::ByAddress { + address, + entry_point, + args, + } => f + .debug_struct("ByAddress") + .field("address", &address) + .field("entry_point", &entry_point) + .field("args", args) + .finish(), + ExecutableItem::ByName { + name, + entry_point, + args, + } => f + .debug_struct("StoredContractByName") + .field("name", &name) + .field("entry_point", &entry_point) + .field("args", args) + .finish(), + ExecutableItem::ByPackageHash { + hash, + version, + entry_point, + args, + } => f + .debug_struct("ByPackageHash") + .field("hash", &base16::encode_lower(hash)) + .field("version", version) + .field("entry_point", &entry_point) + .field("args", args) + .finish(), + ExecutableItem::ByPackageName { + name, + version, + entry_point, + args, + } => f + .debug_struct("ByPackageName") + .field("name", &name) + .field("version", version) + .field("entry_point", &entry_point) + .field("args", args) + .finish(), + } + } +} + +impl TryFrom for ExecutableItem { + type Error = (); + + fn try_from(deploy_item: ExecutableDeployItem) -> Result { + let ret = match deploy_item { + ExecutableDeployItem::ModuleBytes { module_bytes, args } => { + ExecutableItem::Wasm { module_bytes, args } + } + ExecutableDeployItem::StoredContractByHash { + hash, + entry_point, + args, + } => ExecutableItem::ByHash { + hash, + entry_point, + args, + }, + ExecutableDeployItem::StoredContractByName { + name, + entry_point, + args, + } => ExecutableItem::ByName { + name, + entry_point, + args, + }, + ExecutableDeployItem::StoredVersionedContractByHash { + hash, + version, + entry_point, + args, + } => ExecutableItem::ByPackageHash { + hash, + version, + entry_point, + args, + }, + ExecutableDeployItem::StoredVersionedContractByName { + name, + version, + entry_point, + args, + } => ExecutableItem::ByPackageName { + name, + version, + entry_point, + args, + }, + _ => return Err(()), + }; + + Ok(ret) + } +} + +impl TryFrom for ExecutableItem { + type Error = (); + + fn try_from(transaction: Transaction) -> Result { + match transaction { + Transaction::Deploy(deploy) => Ok(ExecutableItem::try_from(deploy.session().clone())?), + Transaction::V1(v1) => match v1.body().target() { + TransactionTarget::Native => Err(()), + TransactionTarget::Stored { id, runtime } => { + if &TransactionRuntime::VmCasperV1 != runtime { + return Err(()); + } + match id { + TransactionInvocationTarget::InvocableEntity(hash_addr) => { + Ok(ExecutableItem::ByHash { + hash: AddressableEntityHash::new(*hash_addr), + args: v1.body().args().clone(), + entry_point: v1.body().entry_point().to_string(), + }) + } + TransactionInvocationTarget::InvocableEntityAlias(name) => { + Ok(ExecutableItem::ByName { + name: name.clone(), + args: v1.body().args().clone(), + entry_point: v1.body().entry_point().to_string(), + }) + } + TransactionInvocationTarget::Package { addr, version } => { + Ok(ExecutableItem::ByPackageHash { + hash: PackageHash::new(*addr), + args: v1.body().args().clone(), + entry_point: v1.body().entry_point().to_string(), + version: *version, + }) + } + TransactionInvocationTarget::PackageAlias { alias, version } => { + Ok(ExecutableItem::ByPackageName { + name: alias.clone(), + args: v1.body().args().clone(), + entry_point: v1.body().entry_point().to_string(), + version: *version, + }) + } + } + } + TransactionTarget::Session { + module_bytes, + runtime, + .. + } => { + if &TransactionRuntime::VmCasperV1 != runtime { + return Err(()); + } + Ok(ExecutableItem::Wasm { + module_bytes: module_bytes.clone(), + args: v1.body().args().clone(), + }) + } + }, + } + } +} + +#[cfg(test)] +impl Distribution for Standard { + fn sample(&self, rng: &mut R) -> ExecutableItem { + fn random_bytes(rng: &mut R) -> Vec { + let mut bytes = vec![0u8; rng.gen_range(0..100)]; + rng.fill_bytes(bytes.as_mut()); + bytes + } + + fn random_string(rng: &mut R) -> String { + rng.sample_iter(&Alphanumeric) + .take(20) + .map(char::from) + .collect() + } + + let mut args = RuntimeArgs::new(); + let _ = args.insert(random_string(rng), Bytes::from(random_bytes(rng))); + + match rng.gen_range(0..5) { + 0 => ExecutableItem::Wasm { + module_bytes: random_bytes(rng).into(), + args, + }, + 1 => ExecutableItem::ByHash { + hash: AddressableEntityHash::new(rng.gen()), + entry_point: random_string(rng), + args, + }, + 2 => ExecutableItem::ByName { + name: random_string(rng), + entry_point: random_string(rng), + args, + }, + 3 => ExecutableItem::ByPackageHash { + hash: PackageHash::new(rng.gen()), + version: rng.gen(), + entry_point: random_string(rng), + args, + }, + 4 => ExecutableItem::ByPackageName { + name: random_string(rng), + version: rng.gen(), + entry_point: random_string(rng), + args, + }, + 5 => ExecutableItem::ByAddress { + address: EntityAddr::new_with_tag(rng.gen(), rng.gen()), + entry_point: random_string(rng), + args, + }, + _ => unreachable!(), + } + } +} + +/// The various types which can be used as the `target` runtime argument of a native transfer. +#[derive(Clone, Ord, PartialOrd, Eq, PartialEq)] +pub enum TransferTarget { + /// A public key. + PublicKey(PublicKey), + /// An account hash. + AccountHash(AccountHash), + /// A URef. + URef(URef), +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn serialization_roundtrip() { + let rng = &mut TestRng::new(); + for _ in 0..10 { + let executable_deploy_item = ExecutableItem::random(rng); + bytesrepr::test_serialization_roundtrip(&executable_deploy_item); + } + } +} diff --git a/execution_engine/src/engine_state/execution_kind.rs b/execution_engine/src/engine_state/execution_kind.rs index a6ea6eb01c..fd08f1061d 100644 --- a/execution_engine/src/engine_state/execution_kind.rs +++ b/execution_engine/src/engine_state/execution_kind.rs @@ -11,7 +11,10 @@ use casper_types::{ ExecutableDeployItem, Key, Package, PackageHash, Phase, ProtocolVersion, StoredValue, }; -use crate::{engine_state::error::Error, execution::ExecError}; +use crate::{ + engine_state::{error::Error, executable_item::ExecutableItem}, + execution::ExecError, +}; /// The type of execution about to be performed. #[derive(Clone, Debug)] @@ -47,7 +50,7 @@ impl ExecutionKind { /// Returns all the details necessary for execution. /// /// This object is generated based on information provided by [`ExecutableDeployItem`]. - pub fn new( + pub fn from_executable_deploy_item( tracking_copy: Rc>>, named_keys: &NamedKeys, executable_deploy_item: ExecutableDeployItem, @@ -63,12 +66,12 @@ impl ExecutionKind { match executable_deploy_item { ExecutableDeployItem::Transfer { .. } => { - Err(Error::InvalidDeployItemVariant("Transfer".into())) + Err(Error::InvalidItemVariant("Transfer".into())) } ExecutableDeployItem::ModuleBytes { module_bytes, .. } if module_bytes.is_empty() && is_payment_phase => { - Err(Error::InvalidDeployItemVariant( + Err(Error::InvalidItemVariant( "Empty module bytes for custom payment".into(), )) } @@ -174,6 +177,160 @@ impl ExecutionKind { ))); } + let looked_up_entity_hash = + *package + .lookup_entity_hash(entity_version_key) + .ok_or(Error::Exec(ExecError::MissingEntityVersion( + entity_version_key, + )))?; + + Ok(ExecutionKind::new_addressable_entity( + looked_up_entity_hash, + entry_point, + )) + } + } + } + /// Returns all the details necessary for execution. + /// + /// This object is generated based on information provided by [`ExecutableItem`]. + pub fn from_executable_item( + tracking_copy: Rc>>, + named_keys: &NamedKeys, + executable_item: ExecutableItem, + protocol_version: &ProtocolVersion, + phase: Phase, + ) -> Result + where + R: StateReader, + { + let package: Package; + + let is_payment_phase = phase == Phase::Payment; + + match executable_item { + ExecutableItem::Wasm { module_bytes, .. } + if module_bytes.is_empty() && is_payment_phase => + { + Err(Error::InvalidItemVariant( + "Empty module bytes for custom payment".into(), + )) + } + ExecutableItem::Wasm { module_bytes, .. } => { + Ok(ExecutionKind::new_module(module_bytes)) + } + ExecutableItem::ByHash { + hash, entry_point, .. + } => Ok(ExecutionKind::new_addressable_entity(hash, entry_point)), + ExecutableItem::ByName { + name, entry_point, .. + } => { + let entity_key = named_keys + .get(&name) + .cloned() + .ok_or_else(|| Error::Exec(ExecError::NamedKeyNotFound(name.to_string())))?; + + let entity_hash = match entity_key { + Key::Hash(hash) => AddressableEntityHash::new(hash), + Key::AddressableEntity(entity_addr) => { + AddressableEntityHash::new(entity_addr.value()) + } + _ => return Err(Error::InvalidKeyVariant), + }; + + Ok(ExecutionKind::new_addressable_entity( + entity_hash, + entry_point, + )) + } + ExecutableItem::ByAddress { + address, + entry_point, + .. + } => { + let entity_hash = AddressableEntityHash::new(address.value()); + // TODO: we should be using entity addr, no enity hash. + // let entity_key = Key::AddressableEntity(address); + Ok(ExecutionKind::new_addressable_entity( + entity_hash, + entry_point, + )) + } + ExecutableItem::ByPackageName { + name, + version, + entry_point, + .. + } => { + let package_key = named_keys + .get(&name) + .cloned() + .ok_or_else(|| Error::Exec(ExecError::NamedKeyNotFound(name.to_string())))?; + + let package_hash = match package_key { + Key::Hash(hash) | Key::Package(hash) => PackageHash::new(hash), + _ => return Err(Error::InvalidKeyVariant), + }; + + package = tracking_copy.borrow_mut().get_package(package_hash)?; + + let maybe_version_key = + version.map(|ver| EntityVersionKey::new(protocol_version.value().major, ver)); + + let entity_version_key = maybe_version_key + .or_else(|| package.current_entity_version()) + .ok_or(Error::Exec(ExecError::NoActiveEntityVersions(package_hash)))?; + + if package.is_version_missing(entity_version_key) { + return Err(Error::Exec(ExecError::MissingEntityVersion( + entity_version_key, + ))); + } + if !package.is_version_enabled(entity_version_key) { + return Err(Error::Exec(ExecError::DisabledEntityVersion( + entity_version_key, + ))); + } + + let looked_up_entity_hash: AddressableEntityHash = package + .lookup_entity_hash(entity_version_key) + .ok_or(Error::Exec(ExecError::MissingEntityVersion( + entity_version_key, + )))? + .to_owned(); + + Ok(ExecutionKind::new_addressable_entity( + looked_up_entity_hash, + entry_point, + )) + } + ExecutableItem::ByPackageHash { + hash: package_hash, + version, + entry_point, + .. + } => { + package = tracking_copy.borrow_mut().get_package(package_hash)?; + + let maybe_version_key = + version.map(|ver| EntityVersionKey::new(protocol_version.value().major, ver)); + + let entity_version_key = maybe_version_key + .or_else(|| package.current_entity_version()) + .ok_or(Error::Exec(ExecError::NoActiveEntityVersions(package_hash)))?; + + if package.is_version_missing(entity_version_key) { + return Err(Error::Exec(ExecError::MissingEntityVersion( + entity_version_key, + ))); + } + + if !package.is_version_enabled(entity_version_key) { + return Err(Error::Exec(ExecError::DisabledEntityVersion( + entity_version_key, + ))); + } + let looked_up_entity_hash = *package .lookup_entity_hash(entity_version_key) diff --git a/execution_engine/src/engine_state/execution_result.rs b/execution_engine/src/engine_state/execution_result.rs index 366519cc91..26a8534baa 100644 --- a/execution_engine/src/engine_state/execution_result.rs +++ b/execution_engine/src/engine_state/execution_result.rs @@ -364,7 +364,7 @@ impl ExecutionResult { err, ExecError::WasmPreprocessing(_) | ExecError::UnsupportedWasmStart ), - Error::WasmPreprocessing(_) | Error::WasmSerialization(_) => true, + Error::WasmPreprocessing(_) => true, _ => false, }, ExecutionResult::Success { .. } => false, diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index b1a6fccc6a..f661a4dbff 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -2,36 +2,52 @@ pub mod deploy_item; pub mod engine_config; mod error; +pub mod executable_item; pub mod execute_request; pub(crate) mod execution_kind; pub mod execution_result; +mod wasm_v1; -use std::{cell::RefCell, rc::Rc}; +use std::{cell::RefCell, convert::TryFrom, rc::Rc}; use num_traits::Zero; + use once_cell::sync::Lazy; + use tracing::error; use casper_storage::{ - data_access_layer::TransferRequest, + data_access_layer::TransferRequest, system::runtime_native::TransferConfig, + tracking_copy::FeesPurseHandling, +}; + +use casper_storage::{ global_state::state::StateProvider, - system::runtime_native::TransferConfig, - tracking_copy::{FeesPurseHandling, TrackingCopyEntityExt, TrackingCopyExt}, + tracking_copy::{TrackingCopyEntityExt, TrackingCopyError, TrackingCopyExt}, }; use casper_types::{ - system::{ - handle_payment::{self}, - HANDLE_PAYMENT, - }, - BlockTime, DeployInfo, Digest, EntityAddr, ExecutableDeployItem, FeeHandling, Gas, Key, Motes, - Phase, ProtocolVersion, PublicKey, RuntimeArgs, StoredValue, TransactionHash, U512, + DeployInfo, EntityAddr, FeeHandling, Key, Motes, PublicKey, RuntimeArgs, StoredValue, + TransactionHash, }; +use casper_types::{Phase, U512}; + +use casper_types::{BlockTime, Digest, Gas, ProtocolVersion}; + +use crate::engine_state::execution_result::ExecutionResults; + +use casper_types::system::{ + handle_payment::{self}, + HANDLE_PAYMENT, +}; + +use casper_types::ExecutableDeployItem; + +use crate::execution::{DirectSystemContractCall, ExecError}; + use crate::{ - engine_state::{execution_kind::ExecutionKind, execution_result::ExecutionResults}, - execution::{DirectSystemContractCall, ExecError, Executor}, - runtime::RuntimeStack, + engine_state::execution_kind::ExecutionKind, execution::Executor, runtime::RuntimeStack, }; pub use self::{ @@ -41,9 +57,11 @@ pub use self::{ DEFAULT_MAX_RUNTIME_CALL_STACK_HEIGHT, }, error::Error, + executable_item::{ExecutableItem, ExecutableItemIdentifier}, execute_request::ExecuteRequest, execution_result::{ExecutionResult, ForcedTransferResult}, }; +pub use wasm_v1::{WasmV1Request, WasmV1Result}; /// The maximum amount of motes that payment code execution can cost. pub const MAX_PAYMENT_AMOUNT: u64 = 2_500_000_000; @@ -69,7 +87,7 @@ pub struct ExecutionEngineV1 { } impl ExecutionEngineV1 { - /// Creates new engine state. + /// Creates new execution engine. pub fn new(config: EngineConfig) -> ExecutionEngineV1 { ExecutionEngineV1 { config } } @@ -79,6 +97,121 @@ impl ExecutionEngineV1 { &self.config } + /// Executes wasm, and that's all. Does not commit or handle payment or anything else. + pub fn execute( + &self, + state_provider: &impl StateProvider, + request: WasmV1Request, + ) -> WasmV1Result { + let executable_item = match ExecutableItem::try_from(request.transaction().clone()) { + Ok(executable_item) => executable_item, + Err(_) => return WasmV1Result::invalid_executable_item(request), + }; + let phase = request.phase(); + match phase { + Phase::System | Phase::FinalizePayment => { + return WasmV1Result::precondition_failure( + request, + Error::Deprecated(format!( + "execution of phase {:?} is no longer supported", + phase + )), + ); + } + Phase::Payment => { + if !executable_item.is_module_bytes() { + return WasmV1Result::precondition_failure( + request, + Error::Deprecated(format!( + "direct execution in phase {:?} is no longer supported", + phase + )), + ); + } + // module bytes is allowed + } + Phase::Session => { + // noop + } + }; + + let state_hash = request.state_hash(); + let tc = match state_provider.tracking_copy(state_hash) { + Ok(Some(tracking_copy)) => Rc::new(RefCell::new(tracking_copy)), + Ok(None) => return WasmV1Result::root_not_found(request, state_hash), + Err(gse) => { + return WasmV1Result::precondition_failure( + request, + Error::TrackingCopy(TrackingCopyError::Storage(gse)), + ) + } + }; + let protocol_version = request.protocol_version(); + let transaction = request.transaction(); + let account_hash = transaction.initiator_addr().account_hash(); + let authorization_keys = &transaction.authorization_keys(); + let (entity, entity_hash) = { + match tc.borrow_mut().get_authorized_addressable_entity( + protocol_version, + account_hash, + authorization_keys, + &self.config().administrative_accounts, + ) { + Ok((addressable_entity, entity_hash)) => (addressable_entity, entity_hash), + Err(tce) => { + return WasmV1Result::precondition_failure(request, Error::TrackingCopy(tce)) + } + } + }; + let mut named_keys = match tc + .borrow_mut() + .get_named_keys(entity.entity_addr(entity_hash)) + .map_err(Into::into) + { + Ok(named_keys) => named_keys, + Err(tce) => { + return WasmV1Result::precondition_failure(request, Error::TrackingCopy(tce)) + } + }; + let execution_kind = match ExecutionKind::from_executable_item( + tc.clone(), + &named_keys, + executable_item.clone(), + &protocol_version, + phase, + ) { + Ok(execution_kind) => execution_kind, + Err(ese) => return WasmV1Result::precondition_failure(request, ese), + }; + + let access_rights = entity.extract_access_rights(entity_hash, &named_keys); + let runtime_args = executable_item.args().clone(); + let transaction_hash = transaction.hash(); + + let execution_result = Executor::new(self.config().clone()).exec( + execution_kind, + runtime_args, + entity_hash, + &entity, + &mut named_keys, + access_rights, + authorization_keys.clone(), + account_hash, + request.blocktime(), + transaction_hash, + request.gas_limit(), + protocol_version, + Rc::clone(&tc), + phase, + RuntimeStack::from_account_hash( + account_hash, + self.config.max_runtime_call_stack_height() as usize, + ), + ); + + WasmV1Result::execution_result(request, execution_result) + } + /// Runs a deploy execution request. /// /// For each deploy stored in the request it will execute it. @@ -86,6 +219,8 @@ impl ExecutionEngineV1 { /// Currently a special shortcut is taken to distinguish a native transfer, from a deploy. /// /// Return execution results which contains results from each deploy ran. + + #[deprecated(since = "6.0.0", note = "please use `execute` instead")] pub fn exec( &self, state_provider: &impl StateProvider, @@ -129,6 +264,7 @@ impl ExecutionEngineV1 { /// Therefore this is the fastest and cheapest way to transfer tokens from account to account. /// /// Returns an [`ExecutionResult`] for a successful native transfer. + #[allow(clippy::too_many_arguments)] fn transfer( &self, @@ -203,6 +339,7 @@ impl ExecutionEngineV1 { /// in the request. /// /// Returns [`ExecutionResult`], or an error condition. + #[allow(clippy::too_many_arguments)] fn deploy( &self, @@ -214,7 +351,11 @@ impl ExecutionEngineV1 { proposer: PublicKey, ) -> Result { let tracking_copy = match state_provider.tracking_copy(prestate_hash) { - Err(gse) => return Ok(ExecutionResult::precondition_failure(Error::Storage(gse))), + Err(gse) => { + return Ok(ExecutionResult::precondition_failure(Error::TrackingCopy( + TrackingCopyError::Storage(gse), + ))) + } Ok(None) => return Err(Error::RootNotFound(prestate_hash)), Ok(Some(tracking_copy)) => Rc::new(RefCell::new(tracking_copy)), }; @@ -270,7 +411,7 @@ impl ExecutionEngineV1 { // Create session code `A` from provided session bytes // validation_spec_1: valid wasm bytes // we do this upfront as there is no reason to continue if session logic is invalid - let session_execution_kind = match ExecutionKind::new( + let session_execution_kind = match ExecutionKind::from_executable_deploy_item( Rc::clone(&tracking_copy), &entity_named_keys, session, @@ -454,7 +595,7 @@ impl ExecutionEngineV1 { } } } else { - let payment_execution_kind = match ExecutionKind::new( + let payment_execution_kind = match ExecutionKind::from_executable_deploy_item( Rc::clone(&tracking_copy), &entity_named_keys, payment, @@ -476,7 +617,7 @@ impl ExecutionEngineV1 { authorization_keys.clone(), account_hash, blocktime, - deploy_hash, + deploy_hash.into(), payment_gas_limit, protocol_version, Rc::clone(&tracking_copy), @@ -642,7 +783,7 @@ impl ExecutionEngineV1 { authorization_keys.clone(), account_hash, blocktime, - deploy_hash, + deploy_hash.into(), session_gas_limit, protocol_version, Rc::clone(&session_tracking_copy), @@ -656,17 +797,16 @@ impl ExecutionEngineV1 { { let transfers = session_result.transfers(); let cost = payment_result_cost.value() + session_result.cost().value(); - let deploy_info = DeployInfo::new( + let info = DeployInfo::new( deploy_hash, transfers, account_hash, entity.main_purse(), cost, ); - session_tracking_copy.borrow_mut().write( - Key::DeployInfo(deploy_hash), - StoredValue::DeployInfo(deploy_info), - ); + session_tracking_copy + .borrow_mut() + .write(Key::DeployInfo(deploy_hash), StoredValue::DeployInfo(info)); } // Session execution was zero cost or provided wasm was malformed. @@ -790,7 +930,7 @@ impl ExecutionEngineV1 { authorization_keys, system_account_hash, blocktime, - deploy_hash, + deploy_hash.into(), gas_limit, protocol_version, finalization_tc, diff --git a/execution_engine/src/engine_state/wasm_v1.rs b/execution_engine/src/engine_state/wasm_v1.rs new file mode 100644 index 0000000000..e9b3f77cdd --- /dev/null +++ b/execution_engine/src/engine_state/wasm_v1.rs @@ -0,0 +1,238 @@ +use casper_types::{ + bytesrepr, + bytesrepr::{FromBytes, ToBytes}, + contract_messages::Messages, + execution::Effects, + BlockTime, Digest, Gas, Phase, ProtocolVersion, Transaction, TransferAddr, +}; +use num_traits::Zero; + +use crate::engine_state::{Error as EngineError, ExecutionResult}; + +/// Wasm v1 request. +pub struct WasmV1Request { + state_hash: Digest, + protocol_version: ProtocolVersion, + blocktime: BlockTime, + transaction: Transaction, + gas_limit: Gas, + phase: Phase, +} + +impl WasmV1Request { + /// Returns new instance of PayRequest. + pub fn new( + state_hash: Digest, + protocol_version: ProtocolVersion, + blocktime: BlockTime, + transaction: Transaction, + gas_limit: Gas, + phase: Phase, + ) -> Self { + WasmV1Request { + state_hash, + protocol_version, + blocktime, + transaction, + gas_limit, + phase, + } + } + + /// State hash. + pub fn state_hash(&self) -> Digest { + self.state_hash + } + + /// Protocol version. + pub fn protocol_version(&self) -> ProtocolVersion { + self.protocol_version + } + + /// Blocktime. + pub fn blocktime(&self) -> BlockTime { + self.blocktime + } + + /// Transaction. + pub fn transaction(&self) -> &Transaction { + &self.transaction + } + + /// Gas limit. + pub fn gas_limit(&self) -> Gas { + self.gas_limit + } + + /// Phase. + pub fn phase(&self) -> Phase { + self.phase + } +} + +impl ToBytes for WasmV1Request { + fn to_bytes(&self) -> Result, bytesrepr::Error> { + let mut buffer = bytesrepr::allocate_buffer(self)?; + self.write_bytes(&mut buffer)?; + Ok(buffer) + } + + fn serialized_length(&self) -> usize { + ToBytes::serialized_length(&self.state_hash) + + ToBytes::serialized_length(&self.protocol_version) + + ToBytes::serialized_length(&self.blocktime) + + ToBytes::serialized_length(&self.protocol_version) + + ToBytes::serialized_length(&self.transaction) + + ToBytes::serialized_length(&self.gas_limit) + + ToBytes::serialized_length(&self.phase) + } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + self.state_hash.write_bytes(writer)?; + self.protocol_version.write_bytes(writer)?; + self.blocktime.write_bytes(writer)?; + self.transaction.write_bytes(writer)?; + self.gas_limit.write_bytes(writer)?; + self.phase.write_bytes(writer) + } +} + +impl FromBytes for WasmV1Request { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (state_hash, bytes) = Digest::from_bytes(bytes)?; + let (protocol_version, bytes) = ProtocolVersion::from_bytes(bytes)?; + let (blocktime, bytes) = BlockTime::from_bytes(bytes)?; + let (transaction, bytes) = Transaction::from_bytes(bytes)?; + let (gas_limit, bytes) = Gas::from_bytes(bytes)?; + let (phase, bytes) = Phase::from_bytes(bytes)?; + Ok(( + WasmV1Request { + state_hash, + protocol_version, + blocktime, + transaction, + gas_limit, + phase, + }, + bytes, + )) + } +} + +/// Wasm v1 result. +#[derive(Debug)] +pub struct WasmV1Result { + /// List of transfers that happened during execution. + transfers: Vec, + /// Gas limit. + limit: Gas, + /// Gas consumed. + consumed: Gas, + /// Execution effects. + effects: Effects, + /// Messages emitted during execution. + messages: Messages, + /// Did the wasm execute successfully? + error: Option, +} + +impl WasmV1Result { + /// Error, if any. + pub fn error(&self) -> &Option { + &self.error + } + + /// List of transfers that happened during execution. + pub fn transfers(&self) -> &Vec { + &self.transfers + } + + /// Gas limit. + pub fn limit(&self) -> Gas { + self.limit + } + + /// Gas consumed. + pub fn consumed(&self) -> Gas { + self.consumed + } + + /// Execution effects. + pub fn effects(&self) -> &Effects { + &self.effects + } + + /// Messages emitted during execution. + pub fn messages(&self) -> &Messages { + &self.messages + } + + /// Root not found. + pub fn root_not_found(request: WasmV1Request, state_hash: Digest) -> Self { + WasmV1Result { + transfers: Vec::default(), + effects: Effects::new(), + messages: Vec::default(), + limit: request.gas_limit, + consumed: Gas::zero(), + error: Some(EngineError::RootNotFound(state_hash)), + } + } + + /// Precondition failure. + pub fn precondition_failure(request: WasmV1Request, error: EngineError) -> Self { + WasmV1Result { + transfers: Vec::default(), + effects: Effects::new(), + messages: Vec::default(), + limit: request.gas_limit, + consumed: Gas::zero(), + error: Some(error), + } + } + + /// Failed to transform transaction into an executable item. + pub fn invalid_executable_item(request: WasmV1Request) -> Self { + WasmV1Result { + transfers: Vec::default(), + effects: Effects::new(), + messages: Vec::default(), + limit: request.gas_limit, + consumed: Gas::zero(), + error: Some(EngineError::InvalidExecutableItem), + } + } + + /// From an execution result. + pub fn execution_result(request: WasmV1Request, execution_result: ExecutionResult) -> Self { + match execution_result { + ExecutionResult::Failure { + error, + transfers, + cost, + effects, + messages, + } => WasmV1Result { + error: Some(error), + transfers, + effects, + messages, + limit: request.gas_limit, + consumed: cost, + }, + ExecutionResult::Success { + transfers, + cost, + effects, + messages, + } => WasmV1Result { + transfers, + effects, + messages, + limit: request.gas_limit, + consumed: cost, + error: None, + }, + } + } +} diff --git a/execution_engine/src/execution/error.rs b/execution_engine/src/execution/error.rs index 7dad976f30..34a809ada5 100644 --- a/execution_engine/src/execution/error.rs +++ b/execution_engine/src/execution/error.rs @@ -5,9 +5,7 @@ use thiserror::Error; use casper_storage::{global_state, tracking_copy::TrackingCopyError}; use casper_types::{ - addressable_entity::{ - AddKeyFailure, EntityKind, RemoveKeyFailure, SetThresholdFailure, UpdateKeyFailure, - }, + addressable_entity::{AddKeyFailure, RemoveKeyFailure, SetThresholdFailure, UpdateKeyFailure}, bytesrepr, execution::TransformError, system, AccessRights, AddressableEntityHash, ApiError, ByteCodeHash, CLType, CLValueError, @@ -54,9 +52,6 @@ pub enum Error { /// Forged reference error. #[error("Forged reference: {}", _0)] ForgedReference(URef), - /// Unable to find a [`URef`]. - #[error("URef not found: {}", _0)] - URefNotFound(URef), /// Unable to find a function. #[error("Function not found: {}", _0)] FunctionNotFound(String), @@ -99,9 +94,6 @@ pub enum Error { /// Host buffer expected a value to be present. #[error("Expected return value")] ExpectedReturnValue, - /// Host buffer was not expected to contain a value. - #[error("Unexpected return value")] - UnexpectedReturnValue, /// Error calling a host function in a wrong context. #[error("Invalid context")] InvalidContext, @@ -116,9 +108,6 @@ pub enum Error { /// Error converting a CLValue. #[error("{0}")] CLValue(CLValueError), - /// Unable to access host buffer. - #[error("Host buffer is empty")] - HostBufferEmpty, /// WASM bytes contains an unsupported "start" section. #[error("Unsupported WASM start")] UnsupportedWasmStart, @@ -126,9 +115,6 @@ pub enum Error { #[error("No active contract versions for contract package")] NoActiveEntityVersions(PackageHash), /// Invalid entity version supplied. - #[error("Invalid entity version: {}", _0)] - InvalidEntityVersion(EntityVersionKey), - /// Invalid entity version supplied. #[error("Disabled entity version: {}", _0)] DisabledEntityVersion(EntityVersionKey), /// Invalid entity version supplied. @@ -138,23 +124,17 @@ pub enum Error { #[error("No such method: {}", _0)] NoSuchMethod(String), /// Contract does - #[error("Error calling an abstract entry point: {}", _0)] + #[error("Error calling a template entry point: {}", _0)] TemplateMethod(String), /// Error processing WASM bytes. #[error("Wasm preprocessing error: {}", _0)] WasmPreprocessing(PreprocessingError), - /// Unable to convert a [`Key`] into an [`URef`]. - #[error("Key is not a URef: {}", _0)] - KeyIsNotAURef(Key), /// Unexpected variant of a stored value. #[error("Unexpected variant of a stored value")] UnexpectedStoredValueVariant, /// Error upgrading a locked contract package. #[error("A locked contract cannot be upgraded")] LockedEntity(PackageHash), - /// Unable to find a contract package by a specified hash address. - #[error("Invalid package: {}", _0)] - InvalidPackage(PackageHash), /// Unable to find a contract by a specified hash address. #[error("Invalid contract: {}", _0)] InvalidEntity(AddressableEntityHash), @@ -170,18 +150,12 @@ pub enum Error { /// Error writing a dictionary item key which exceeded maximum allowed length. #[error("Dictionary item key exceeded maximum length")] DictionaryItemKeyExceedsLength, - /// Missing system contract registry. - #[error("Missing system contract registry")] - MissingSystemContractRegistry, /// Missing system contract hash. #[error("Missing system contract hash: {0}")] MissingSystemContractHash(String), /// An attempt to push to the runtime stack which is already at the maximum height. #[error("Runtime stack overflow")] RuntimeStackOverflow, - /// An attempt to write a value to global state where its serialized size is too large. - #[error("Value too large")] - ValueTooLarge, /// The runtime stack is `None`. #[error("Runtime stack missing")] MissingRuntimeStack, @@ -194,9 +168,6 @@ pub enum Error { /// Invalid key #[error("Invalid key {0}")] UnexpectedKeyVariant(Key), - /// Invalid AddressableEntity kind. - #[error("Invalid entity kind: {0}")] - InvalidEntityKind(EntityKind), /// Failed to transfer tokens on a private chain. #[error("Failed to transfer with unrestricted transfers disabled")] DisabledUnrestrictedTransfers, diff --git a/execution_engine/src/execution/executor.rs b/execution_engine/src/execution/executor.rs index e853c7ef7d..fa57b1f65a 100644 --- a/execution_engine/src/execution/executor.rs +++ b/execution_engine/src/execution/executor.rs @@ -13,7 +13,7 @@ use casper_types::{ system::{handle_payment, mint, HANDLE_PAYMENT, MINT}, AddressableEntity, AddressableEntityHash, ApiError, BlockTime, CLTyped, ContextAccessRights, DeployHash, EntryPointType, Gas, Key, Phase, ProtocolVersion, RuntimeArgs, StoredValue, Tagged, - URef, U512, + TransactionHash, URef, U512, }; use crate::{ @@ -60,7 +60,7 @@ impl Executor { authorization_keys: BTreeSet, account_hash: AccountHash, blocktime: BlockTime, - deploy_hash: DeployHash, + transaction_hash: TransactionHash, gas_limit: Gas, protocol_version: ProtocolVersion, tracking_copy: Rc>>, @@ -78,7 +78,7 @@ impl Executor { }; let address_generator = { - let generator = AddressGenerator::new(deploy_hash.as_ref(), phase); + let generator = AddressGenerator::new(transaction_hash.as_ref(), phase); Rc::new(RefCell::new(generator)) }; @@ -95,7 +95,7 @@ impl Executor { tracking_copy, blocktime, protocol_version, - deploy_hash, + transaction_hash, phase, args.clone(), gas_limit, @@ -148,7 +148,7 @@ impl Executor { authorization_keys: BTreeSet, account_hash: AccountHash, blocktime: BlockTime, - deploy_hash: DeployHash, + transaction_hash: TransactionHash, gas_limit: Gas, protocol_version: ProtocolVersion, tracking_copy: Rc>>, @@ -161,7 +161,7 @@ impl Executor { T: FromBytes + CLTyped, { let address_generator = { - let generator = AddressGenerator::new(deploy_hash.as_ref(), phase); + let generator = AddressGenerator::new(transaction_hash.as_ref(), phase); Rc::new(RefCell::new(generator)) }; @@ -224,7 +224,7 @@ impl Executor { tracking_copy, blocktime, protocol_version, - deploy_hash, + transaction_hash, phase, runtime_args.clone(), gas_limit, @@ -285,7 +285,7 @@ impl Executor { tracking_copy: Rc>>, blocktime: BlockTime, protocol_version: ProtocolVersion, - deploy_hash: DeployHash, + transaction_hash: TransactionHash, phase: Phase, runtime_args: RuntimeArgs, gas_limit: Gas, @@ -310,7 +310,7 @@ impl Executor { self.config.clone(), blocktime, protocol_version, - deploy_hash, + transaction_hash, phase, runtime_args, gas_limit, @@ -447,7 +447,7 @@ impl Executor { authorization_keys, account_hash, blocktime, - deploy_hash, + TransactionHash::Deploy(deploy_hash), payment_gas_limit, protocol_version, Rc::clone(&tracking_copy), @@ -483,7 +483,7 @@ impl Executor { authorization_keys, account_hash, blocktime, - deploy_hash, + TransactionHash::Deploy(deploy_hash), gas_limit, protocol_version, Rc::clone(&tracking_copy), diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index 157fbe6ade..a77527fb38 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -50,7 +50,7 @@ use casper_types::{ STANDARD_PAYMENT, }, AccessRights, ApiError, BlockTime, ByteCode, ByteCodeAddr, ByteCodeHash, ByteCodeKind, CLTyped, - CLValue, ContextAccessRights, ContractWasm, DeployHash, EntityAddr, EntityKind, EntityVersion, + CLValue, ContextAccessRights, ContractWasm, EntityAddr, EntityKind, EntityVersion, EntityVersionKey, EntityVersions, Gas, GrantedAccess, Group, Groups, HostFunction, HostFunctionCost, Key, NamedArg, Package, PackageHash, Phase, PublicKey, RuntimeArgs, StoredValue, Tagged, Transfer, TransferResult, TransferredTo, URef, @@ -2116,10 +2116,19 @@ where let transfer_addr = self.context.new_transfer_addr()?; let transfer = { - let deploy_hash: DeployHash = self.context.get_deploy_hash(); + let transaction_hash = self.context.get_transaction_hash(); let from: AccountHash = self.context.get_caller(); let fee: U512 = U512::zero(); // TODO - Transfer::new(deploy_hash, from, maybe_to, source, target, amount, fee, id) + Transfer::new( + transaction_hash, + from, + maybe_to, + source, + target, + amount, + fee, + id, + ) }; { let transfers = self.context.transfers_mut(); diff --git a/execution_engine/src/runtime/stack.rs b/execution_engine/src/runtime/stack.rs index 18fc1deac9..fbc13d1373 100644 --- a/execution_engine/src/runtime/stack.rs +++ b/execution_engine/src/runtime/stack.rs @@ -1,5 +1,4 @@ //! Runtime stacks. - use casper_types::{account::AccountHash, system::Caller, PublicKey}; /// A runtime stack frame. diff --git a/execution_engine/src/runtime_context/mod.rs b/execution_engine/src/runtime_context/mod.rs index 046aa74e9b..bd6da5c1d6 100644 --- a/execution_engine/src/runtime_context/mod.rs +++ b/execution_engine/src/runtime_context/mod.rs @@ -31,9 +31,9 @@ use casper_types::{ handle_stored_dictionary_value, system::auction::EraInfo, AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, CLType, CLValue, - CLValueDictionary, ContextAccessRights, DeployHash, EntityAddr, EntryPointType, Gas, - GrantedAccess, Key, KeyTag, Motes, Package, PackageHash, Phase, ProtocolVersion, PublicKey, - RuntimeArgs, StoredValue, StoredValueTypeMismatch, SystemEntityRegistry, Transfer, + CLValueDictionary, ContextAccessRights, EntityAddr, EntryPointType, Gas, GrantedAccess, Key, + KeyTag, Motes, Package, PackageHash, Phase, ProtocolVersion, PublicKey, RuntimeArgs, + StoredValue, StoredValueTypeMismatch, SystemEntityRegistry, TransactionHash, Transfer, TransferAddr, URef, URefAddr, DICTIONARY_ITEM_KEY_MAX_LENGTH, KEY_HASH_LENGTH, U512, }; @@ -52,7 +52,7 @@ pub struct RuntimeContext<'a, R> { args: RuntimeArgs, authorization_keys: BTreeSet, blocktime: BlockTime, - deploy_hash: DeployHash, + transaction_hash: TransactionHash, gas_limit: Gas, gas_counter: Gas, address_generator: Rc>, @@ -92,7 +92,7 @@ where engine_config: EngineConfig, blocktime: BlockTime, protocol_version: ProtocolVersion, - deploy_hash: DeployHash, + transaction_hash: TransactionHash, phase: Phase, runtime_args: RuntimeArgs, gas_limit: Gas, @@ -118,7 +118,7 @@ where authorization_keys, account_hash, blocktime, - deploy_hash, + transaction_hash, gas_limit, gas_counter, address_generator, @@ -151,7 +151,7 @@ where let blocktime = self.blocktime; let protocol_version = self.protocol_version; - let deploy_hash = self.deploy_hash; + let transaction_hash = self.transaction_hash; let phase = self.phase; let gas_limit = self.gas_limit; @@ -171,7 +171,7 @@ where authorization_keys, account_hash, blocktime, - deploy_hash, + transaction_hash, gas_limit, gas_counter, address_generator, @@ -253,9 +253,9 @@ where self.blocktime } - /// Returns the deploy hash. - pub fn get_deploy_hash(&self) -> DeployHash { - self.deploy_hash + /// Returns the transaction hash. + pub fn get_transaction_hash(&self) -> TransactionHash { + self.transaction_hash } /// Extends access rights with a new map. @@ -312,7 +312,7 @@ where self.entity_key } - /// Returns the initiater of the call chain. + /// Returns the initiator of the call chain. pub fn get_caller(&self) -> AccountHash { self.account_hash } diff --git a/execution_engine/src/runtime_context/tests.rs b/execution_engine/src/runtime_context/tests.rs index 0bb1b11319..db832e83d8 100644 --- a/execution_engine/src/runtime_context/tests.rs +++ b/execution_engine/src/runtime_context/tests.rs @@ -20,7 +20,7 @@ use casper_types::{ AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, ByteCodeHash, CLValue, ContextAccessRights, DeployHash, EntityAddr, EntityKind, EntryPointType, EntryPoints, Gas, Key, PackageHash, Phase, ProtocolVersion, PublicKey, RuntimeArgs, SecretKey, StoredValue, - SystemEntityRegistry, Tagged, URef, KEY_HASH_LENGTH, U256, U512, + SystemEntityRegistry, Tagged, TransactionHash, URef, KEY_HASH_LENGTH, U256, U512, }; use tempfile::TempDir; @@ -153,7 +153,7 @@ fn new_runtime_context<'a>( TEST_ENGINE_CONFIG.clone(), BlockTime::new(0), ProtocolVersion::V1_0_0, - DeployHash::from_raw([1u8; 32]), + TransactionHash::Deploy(DeployHash::from_raw([1u8; 32])), Phase::Session, RuntimeArgs::new(), Gas::new(U512::from(GAS_LIMIT)), @@ -419,7 +419,7 @@ fn contract_key_addable_valid() { EngineConfig::default(), BlockTime::new(0), ProtocolVersion::V1_0_0, - DeployHash::from_raw(DEPLOY_HASH), + TransactionHash::Deploy(DeployHash::from_raw(DEPLOY_HASH)), PHASE, RuntimeArgs::new(), Gas::new(U512::from(GAS_LIMIT)), @@ -476,7 +476,7 @@ fn contract_key_addable_invalid() { EngineConfig::default(), BlockTime::new(0), ProtocolVersion::V1_0_0, - DeployHash::from_raw(DEPLOY_HASH), + TransactionHash::Deploy(DeployHash::from_raw(DEPLOY_HASH)), PHASE, RuntimeArgs::new(), Gas::new(U512::from(GAS_LIMIT)), diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index e6402b1eaa..8589da84b8 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -168,6 +168,7 @@ impl WasmTestBuilder { /// Execute and commit transforms from an ExecuteRequest into a scratch global state. /// You MUST call write_scratch_to_lmdb to flush these changes to LmdbGlobalState. + #[allow(deprecated)] pub fn scratch_exec_and_commit(&mut self, mut exec_request: ExecuteRequest) -> &mut Self { if self.scratch_global_state.is_none() { self.scratch_global_state = Some(self.data_access_layer.get_scratch_global_state()); @@ -796,6 +797,7 @@ where } /// Runs an [`ExecuteRequest`]. + #[allow(deprecated)] pub fn exec(&mut self, mut exec_request: ExecuteRequest) -> &mut Self { let exec_request = { let hash = self.post_state_hash.expect("expected post_state_hash"); diff --git a/execution_engine_testing/tests/src/test/deploy/receipts.rs b/execution_engine_testing/tests/src/test/deploy/receipts.rs index bcdb3eaf4a..c9341f3374 100644 --- a/execution_engine_testing/tests/src/test/deploy/receipts.rs +++ b/execution_engine_testing/tests/src/test/deploy/receipts.rs @@ -7,7 +7,7 @@ use casper_engine_test_support::{ }; use casper_types::{ account::AccountHash, runtime_args, system::mint, AccessRights, DeployHash, PublicKey, - SecretKey, Transfer, TransferAddr, U512, + SecretKey, TransactionHash, Transfer, TransferAddr, U512, }; const CONTRACT_TRANSFER_PURSE_TO_ACCOUNT: &str = "transfer_purse_to_account.wasm"; @@ -105,7 +105,7 @@ fn should_record_wasmless_transfer() { .get_transfer(transfers[0]) .expect("should have transfer"); - assert_eq!(transfer.deploy_hash, deploy_hash); + assert_eq!(transfer.transaction_hash, deploy_hash.into()); assert_eq!(transfer.from, *DEFAULT_ACCOUNT_ADDR); assert_eq!(transfer.to, Some(*ALICE_ADDR)); assert_eq!(transfer.source, default_account.main_purse()); @@ -170,7 +170,7 @@ fn should_record_wasm_transfer() { .get_transfer(transfers[0]) .expect("should have transfer"); - assert_eq!(transfer.deploy_hash, deploy_hash); + assert_eq!(transfer.transaction_hash, deploy_hash.into()); assert_eq!(transfer.from, *DEFAULT_ACCOUNT_ADDR); assert_eq!(transfer.source, default_account.main_purse()); assert_eq!(transfer.target, alice_attenuated_main_purse); @@ -236,7 +236,7 @@ fn should_record_wasm_transfer_with_id() { .get_transfer(transfers[0]) .expect("should have transfer"); - assert_eq!(transfer.deploy_hash, deploy_hash); + assert_eq!(transfer.transaction_hash, deploy_hash.into()); assert_eq!(transfer.from, *DEFAULT_ACCOUNT_ADDR); assert_eq!(transfer.source, default_account.main_purse()); assert_eq!(transfer.target, alice_attenuated_main_purse); @@ -347,7 +347,7 @@ fn should_record_wasm_transfers() { assert_eq!(transfers.len(), EXPECTED_LENGTH); assert!(transfers.contains(&Transfer { - deploy_hash, + transaction_hash: deploy_hash.into(), from: *DEFAULT_ACCOUNT_ADDR, to: Some(*ALICE_ADDR), source: default_account.main_purse(), @@ -358,7 +358,7 @@ fn should_record_wasm_transfers() { })); assert!(transfers.contains(&Transfer { - deploy_hash, + transaction_hash: deploy_hash.into(), from: *DEFAULT_ACCOUNT_ADDR, to: Some(*BOB_ADDR), source: default_account.main_purse(), @@ -369,7 +369,7 @@ fn should_record_wasm_transfers() { })); assert!(transfers.contains(&Transfer { - deploy_hash, + transaction_hash: deploy_hash.into(), from: *DEFAULT_ACCOUNT_ADDR, to: Some(*CAROL_ADDR), source: default_account.main_purse(), @@ -510,7 +510,7 @@ fn should_record_wasm_transfers_with_subcall() { }; let session_expected_alice = Transfer { - deploy_hash: transfer_deploy_hash, + transaction_hash: transfer_deploy_hash.into(), from: *DEFAULT_ACCOUNT_ADDR, to: Some(*ALICE_ADDR), source: default_account.main_purse(), @@ -521,7 +521,7 @@ fn should_record_wasm_transfers_with_subcall() { }; let session_expected_bob = Transfer { - deploy_hash: transfer_deploy_hash, + transaction_hash: transfer_deploy_hash.into(), from: *DEFAULT_ACCOUNT_ADDR, to: Some(*BOB_ADDR), source: default_account.main_purse(), @@ -532,7 +532,7 @@ fn should_record_wasm_transfers_with_subcall() { }; let session_expected_carol = Transfer { - deploy_hash: transfer_deploy_hash, + transaction_hash: transfer_deploy_hash.into(), from: *DEFAULT_ACCOUNT_ADDR, to: Some(*CAROL_ADDR), source: default_account.main_purse(), @@ -560,7 +560,7 @@ fn should_record_wasm_transfers_with_subcall() { } let stored_expected_alice = Transfer { - deploy_hash: transfer_deploy_hash, + transaction_hash: TransactionHash::Deploy(transfer_deploy_hash), from: *DEFAULT_ACCOUNT_ADDR, to: Some(*ALICE_ADDR), source: contract_purse, @@ -571,7 +571,7 @@ fn should_record_wasm_transfers_with_subcall() { }; let stored_expected_bob = Transfer { - deploy_hash: transfer_deploy_hash, + transaction_hash: TransactionHash::Deploy(transfer_deploy_hash), from: *DEFAULT_ACCOUNT_ADDR, to: Some(*BOB_ADDR), source: contract_purse, @@ -582,7 +582,7 @@ fn should_record_wasm_transfers_with_subcall() { }; let stored_expected_carol = Transfer { - deploy_hash: transfer_deploy_hash, + transaction_hash: transfer_deploy_hash.into(), from: *DEFAULT_ACCOUNT_ADDR, to: Some(*CAROL_ADDR), source: contract_purse, diff --git a/node/Cargo.toml b/node/Cargo.toml index cbcd67db16..854076df73 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -23,6 +23,7 @@ base16 = "0.2.1" base64 = "0.13.0" bincode = "1" bytes = "1.0.1" +casper-binary-port = { version = "1.0.0", path = "../binary_port" } casper-execution-engine = { version = "6.0.0", path = "../execution_engine" } casper-json-rpc = { version = "1.1.0", path = "../json_rpc" } casper-storage = { version = "1.4.3", path = "../storage" } diff --git a/node/src/components/binary_port.rs b/node/src/components/binary_port.rs index c56acad4df..e9ad3510c0 100644 --- a/node/src/components/binary_port.rs +++ b/node/src/components/binary_port.rs @@ -9,23 +9,24 @@ mod tests; use std::{convert::TryFrom, net::SocketAddr, sync::Arc}; use bytes::Bytes; +use casper_binary_port::{ + BinaryRequest, BinaryRequestHeader, BinaryRequestTag, BinaryResponse, BinaryResponseAndRequest, + ErrorCode, GetRequest, GetTrieFullResult, GlobalStateQueryResult, GlobalStateRequest, + InformationRequest, InformationRequestTag, NodeStatus, ReactorStateName, + TransactionWithExecutionInfo, +}; use casper_storage::{ data_access_layer::{ tagged_values::{TaggedValuesRequest, TaggedValuesResult, TaggedValuesSelection}, QueryRequest, QueryResult, TrieRequest, }, global_state::trie::TrieRaw, + DbRawBytesSpec, RecordId, }; use casper_types::{ - binary_port::{ - self, BinaryRequest, BinaryRequestHeader, BinaryRequestTag, BinaryResponse, - BinaryResponseAndRequest, DbRawBytesSpec, GetRequest, GetTrieFullResult, - GlobalStateQueryResult, GlobalStateRequest, InformationRequest, InformationRequestTag, - NodeStatus, ReactorStateName, RecordId, TransactionWithExecutionInfo, - }, bytesrepr::{self, FromBytes, ToBytes}, - BlockHeader, BlockIdentifier, Digest, GlobalStateIdentifier, Peers, ProtocolVersion, - SignedBlock, TimeDiff, Timestamp, Transaction, + BlockIdentifier, Digest, GlobalStateIdentifier, Peers, ProtocolVersion, SignedBlock, TimeDiff, + Transaction, }; use datasize::DataSize; use futures::{future::BoxFuture, FutureExt}; @@ -46,7 +47,6 @@ use tokio::{ use tracing::{debug, error, info, warn}; use crate::{ - contract_runtime::SpeculativeExecutionState, effect::{ requests::{ AcceptTransactionRequest, BlockSynchronizerRequest, ChainspecRawBytesRequest, @@ -63,6 +63,7 @@ use crate::{ use self::{error::Error, metrics::Metrics}; use super::{Component, ComponentState, InitializedComponent, PortBoundComponent}; +use crate::contract_runtime::SpeculativeExecutionResult; pub(crate) use config::Config; pub(crate) use event::Event; @@ -106,135 +107,6 @@ impl BinaryPort { } } -impl Component for BinaryPort -where - REv: From - + From - + From - + From - + From - + From - + From - + From - + From - + From - + Send, -{ - type Event = Event; - - fn handle_event( - &mut self, - effect_builder: EffectBuilder, - _rng: &mut NodeRng, - event: Self::Event, - ) -> Effects { - match &self.state { - ComponentState::Uninitialized => { - warn!( - ?event, - name = >::name(self), - "should not handle this event when component is uninitialized" - ); - Effects::new() - } - ComponentState::Initializing => match event { - Event::Initialize => { - let (effects, state) = self.bind(self.config.enable_server, effect_builder); - >::set_state(self, state); - effects - } - _ => { - warn!( - ?event, - name = >::name(self), - "binary port is initializing, ignoring event" - ); - Effects::new() - } - }, - ComponentState::Initialized => match event { - Event::Initialize => { - error!( - ?event, - name = >::name(self), - "component already initialized" - ); - Effects::new() - } - Event::AcceptConnection { - stream, - peer, - responder, - } => { - if let Ok(permit) = Arc::clone(&self.connection_limit).try_acquire_owned() { - self.metrics.binary_port_connections_count.inc(); - let config = Arc::clone(&self.config); - tokio::spawn(handle_client(peer, stream, effect_builder, config, permit)); - } else { - warn!( - "connection limit reached, dropping connection from {}", - peer - ); - } - responder.respond(()).ignore() - } - Event::HandleRequest { request, responder } => { - let config = Arc::clone(&self.config); - let metrics = Arc::clone(&self.metrics); - async move { - let response = - handle_request(request, effect_builder, &config, &metrics).await; - responder.respond(response).await - } - .ignore() - } - }, - ComponentState::Fatal(msg) => { - error!( - msg, - ?event, - name = >::name(self), - "should not handle this event when this component has fatal error" - ); - Effects::new() - } - } - } - - fn name(&self) -> &str { - COMPONENT_NAME - } -} - -impl InitializedComponent for BinaryPort -where - REv: From - + From - + From - + From - + From - + From - + From - + From - + From - + From - + Send, -{ - fn state(&self) -> &ComponentState { - &self.state - } - - fn set_state(&mut self, new_state: ComponentState) { - info!( - ?new_state, - name = >::name(self), - "component state changed" - ); - - self.state = new_state; - } -} - async fn handle_request( req: BinaryRequest, effect_builder: EffectBuilder, @@ -254,47 +126,27 @@ where + From + Send, { - let version = effect_builder.get_protocol_version().await; + let protocol_version = effect_builder.get_protocol_version().await; match req { BinaryRequest::TryAcceptTransaction { transaction } => { metrics.binary_port_try_accept_transaction_count.inc(); - try_accept_transaction(effect_builder, transaction, None, version).await + try_accept_transaction(effect_builder, transaction, false, protocol_version).await } - BinaryRequest::TrySpeculativeExec { - transaction, - state_root_hash, - block_time, - protocol_version, - speculative_exec_at_block, - } => { + BinaryRequest::TrySpeculativeExec { transaction } => { metrics.binary_port_try_speculative_exec_count.inc(); if !config.allow_request_speculative_exec { - return BinaryResponse::new_error( - binary_port::ErrorCode::FunctionDisabled, - protocol_version, - ); + return BinaryResponse::new_error(ErrorCode::FunctionDisabled, protocol_version); } - let response = try_accept_transaction( - effect_builder, - transaction.clone(), - Some(speculative_exec_at_block), - version, - ) - .await; + let response = + try_accept_transaction(effect_builder, transaction.clone(), true, protocol_version) + .await; if !response.is_success() { return response; } - try_speculative_execution( - effect_builder, - state_root_hash, - block_time, - protocol_version, - transaction, - ) - .await + try_speculative_execution(effect_builder, transaction, protocol_version).await } BinaryRequest::Get(get_req) => { - handle_get_request(get_req, effect_builder, config, metrics, version).await + handle_get_request(get_req, effect_builder, config, metrics, protocol_version).await } } } @@ -326,7 +178,7 @@ where } if RecordId::try_from(record_type_tag) == Ok(RecordId::Transfer) => { metrics.binary_port_get_record_count.inc(); let Ok(block_hash) = bytesrepr::deserialize_from_slice(&key) else { - return BinaryResponse::new_error(binary_port::ErrorCode::BadRequest, protocol_version); + return BinaryResponse::new_error(ErrorCode::BadRequest, protocol_version); }; let Some(transfers) = effect_builder .get_block_transfers_from_storage(block_hash) @@ -334,7 +186,7 @@ where return BinaryResponse::new_empty(protocol_version); }; let Ok(serialized) = bincode::serialize(&transfers) else { - return BinaryResponse::new_error(binary_port::ErrorCode::InternalError, protocol_version); + return BinaryResponse::new_error(ErrorCode::InternalError, protocol_version); }; let bytes = DbRawBytesSpec::new_current(&serialized); BinaryResponse::from_db_raw_bytes(RecordId::Transfer, Some(bytes), protocol_version) @@ -349,19 +201,18 @@ where let maybe_raw_bytes = effect_builder.get_raw_data(record_id, key).await; BinaryResponse::from_db_raw_bytes(record_id, maybe_raw_bytes, protocol_version) } - Err(_) => BinaryResponse::new_error( - binary_port::ErrorCode::UnsupportedRequest, - protocol_version, - ), + Err(_) => { + BinaryResponse::new_error(ErrorCode::UnsupportedRequest, protocol_version) + } } } GetRequest::Information { info_type_tag, key } => { metrics.binary_port_get_info_count.inc(); let Ok(tag) = InformationRequestTag::try_from(info_type_tag) else { - return BinaryResponse::new_error(binary_port::ErrorCode::UnsupportedRequest, protocol_version); + return BinaryResponse::new_error(ErrorCode::UnsupportedRequest, protocol_version); }; let Ok(req) = InformationRequest::try_from((tag, &key[..])) else { - return BinaryResponse::new_error(binary_port::ErrorCode::BadRequest, protocol_version); + return BinaryResponse::new_error(ErrorCode::BadRequest, protocol_version); }; handle_info_request(req, effect_builder, protocol_version).await } @@ -390,11 +241,11 @@ where BinaryResponse::from_value(values, protocol_version) } TaggedValuesResult::RootNotFound => { - let error_code = binary_port::ErrorCode::RootNotFound; + let error_code = ErrorCode::RootNotFound; BinaryResponse::new_error(error_code, protocol_version) } TaggedValuesResult::Failure(_err) => { - BinaryResponse::new_error(binary_port::ErrorCode::InternalError, protocol_version) + BinaryResponse::new_error(ErrorCode::InternalError, protocol_version) } } } @@ -428,10 +279,7 @@ where key_tag, } => { if !config.allow_request_get_all_values { - BinaryResponse::new_error( - binary_port::ErrorCode::FunctionDisabled, - protocol_version, - ) + BinaryResponse::new_error(ErrorCode::FunctionDisabled, protocol_version) } else { handle_get_all_items(state_identifier, key_tag, effect_builder, protocol_version) .await @@ -439,10 +287,7 @@ where } GlobalStateRequest::Trie { trie_key } => { let response = if !config.allow_request_get_trie { - BinaryResponse::new_error( - binary_port::ErrorCode::FunctionDisabled, - protocol_version, - ) + BinaryResponse::new_error(ErrorCode::FunctionDisabled, protocol_version) } else { let req = TrieRequest::new(trie_key, None); match effect_builder.get_trie(req).await.into_legacy() { @@ -450,10 +295,9 @@ where GetTrieFullResult::new(result.map(TrieRaw::into_inner)), protocol_version, ), - Err(_err) => BinaryResponse::new_error( - binary_port::ErrorCode::InternalError, - protocol_version, - ), + Err(_err) => { + BinaryResponse::new_error(ErrorCode::InternalError, protocol_version) + } } }; response @@ -484,15 +328,15 @@ where protocol_version, ), QueryResult::RootNotFound => { - let error_code = binary_port::ErrorCode::RootNotFound; + let error_code = ErrorCode::RootNotFound; BinaryResponse::new_error(error_code, protocol_version) } QueryResult::ValueNotFound(_) => { - let error_code = binary_port::ErrorCode::NotFound; + let error_code = ErrorCode::NotFound; BinaryResponse::new_error(error_code, protocol_version) } QueryResult::Failure(_) => { - let error_code = binary_port::ErrorCode::QueryFailedToExecute; + let error_code = ErrorCode::FailedQuery; BinaryResponse::new_error(error_code, protocol_version) } } @@ -635,7 +479,7 @@ where let Ok(uptime) = TimeDiff::try_from(node_uptime) else { return BinaryResponse::new_error( - binary_port::ErrorCode::InternalError, + ErrorCode::InternalError, protocol_version, ) }; @@ -663,14 +507,14 @@ where async fn try_accept_transaction( effect_builder: EffectBuilder, transaction: Transaction, - speculative_exec_at: Option, + is_speculative: bool, protocol_version: ProtocolVersion, ) -> BinaryResponse where REv: From, { effect_builder - .try_accept_transaction(transaction, speculative_exec_at.map(Box::new)) + .try_accept_transaction(transaction, is_speculative) .await .map_or_else( |err| BinaryResponse::new_error(err.into(), protocol_version), @@ -680,28 +524,36 @@ where async fn try_speculative_execution( effect_builder: EffectBuilder, - state_root_hash: Digest, - block_time: Timestamp, - protocol_version: ProtocolVersion, transaction: Transaction, + protocol_version: ProtocolVersion, ) -> BinaryResponse where - REv: From + From, + REv: From + From + From, { - effect_builder - .speculatively_execute( - SpeculativeExecutionState { - state_root_hash, - block_time, - protocol_version, - }, - Box::new(transaction), - ) + let tip = match effect_builder + .get_highest_complete_block_header_from_storage() .await - .map_or_else( - |err| BinaryResponse::new_error(err.into(), protocol_version), - |val| BinaryResponse::from_value(val, protocol_version), - ) + { + Some(tip) => tip, + None => return BinaryResponse::new_error(ErrorCode::NoCompleteBlocks, protocol_version), + }; + + let result = effect_builder + .speculatively_execute(Box::new(tip), Box::new(transaction)) + .await; + + match result { + SpeculativeExecutionResult::InvalidTransaction(ite) => { + BinaryResponse::new_error(ite.into(), protocol_version) + } + SpeculativeExecutionResult::WasmV1(v1) => match v1.error() { + Some(_) => BinaryResponse::new_error(ErrorCode::InternalError, protocol_version), + None => BinaryResponse::from_value( + casper_binary_port::SpeculativeExecutionResult::from(v1), + protocol_version, + ), + }, + } } async fn client_loop( @@ -749,26 +601,23 @@ where REv: From, { let Ok((header, remainder)) = BinaryRequestHeader::from_bytes(payload) else { - return BinaryResponse::new_error(binary_port::ErrorCode::BadRequest, protocol_version); + return BinaryResponse::new_error(ErrorCode::BadRequest, protocol_version); }; if !header .protocol_version() .is_compatible_with(&protocol_version) { - return BinaryResponse::new_error( - binary_port::ErrorCode::UnsupportedProtocolVersion, - protocol_version, - ); + return BinaryResponse::new_error(ErrorCode::UnsupportedProtocolVersion, protocol_version); } // we might receive a request added in a minor version if we're behind let Ok(tag) = BinaryRequestTag::try_from(header.type_tag()) else { - return BinaryResponse::new_error(binary_port::ErrorCode::UnsupportedRequest, protocol_version); + return BinaryResponse::new_error(ErrorCode::UnsupportedRequest, protocol_version); }; let Ok(request) = BinaryRequest::try_from((tag, remainder)) else { - return BinaryResponse::new_error(binary_port::ErrorCode::BadRequest, protocol_version); + return BinaryResponse::new_error(ErrorCode::BadRequest, protocol_version); }; effect_builder @@ -871,42 +720,6 @@ async fn run_server( } } -impl PortBoundComponent for BinaryPort -where - REv: From - + From - + From - + From - + From - + From - + From - + From - + From - + From - + Send, -{ - type Error = ListeningError; - type ComponentEvent = Event; - - fn listen( - &mut self, - effect_builder: EffectBuilder, - ) -> Result, Self::Error> { - let local_addr = Arc::clone(&self.local_addr); - let server_join_handle = tokio::spawn(run_server( - local_addr, - effect_builder, - Arc::clone(&self.config), - Arc::clone(&self.shutdown_trigger), - )); - self.server_join_handle - .set(server_join_handle) - .expect("server join handle should not be set elsewhere"); - - Ok(Effects::new()) - } -} - impl Finalize for BinaryPort { fn finalize(mut self) -> BoxFuture<'static, ()> { self.shutdown_trigger.notify_one(); @@ -974,3 +787,168 @@ where .map(|header| *header.state_root_hash()), } } + +impl Component for BinaryPort +where + REv: From + + From + + From + + From + + From + + From + + From + + From + + From + + From + + Send, +{ + type Event = Event; + + fn name(&self) -> &str { + COMPONENT_NAME + } + + fn handle_event( + &mut self, + effect_builder: EffectBuilder, + _rng: &mut NodeRng, + event: Self::Event, + ) -> Effects { + match &self.state { + ComponentState::Uninitialized => { + warn!( + ?event, + name = >::name(self), + "should not handle this event when component is uninitialized" + ); + Effects::new() + } + ComponentState::Initializing => match event { + Event::Initialize => { + let (effects, state) = self.bind(self.config.enable_server, effect_builder); + >::set_state(self, state); + effects + } + _ => { + warn!( + ?event, + name = >::name(self), + "binary port is initializing, ignoring event" + ); + Effects::new() + } + }, + ComponentState::Initialized => match event { + Event::Initialize => { + error!( + ?event, + name = >::name(self), + "component already initialized" + ); + Effects::new() + } + Event::AcceptConnection { + stream, + peer, + responder, + } => { + if let Ok(permit) = Arc::clone(&self.connection_limit).try_acquire_owned() { + self.metrics.binary_port_connections_count.inc(); + let config = Arc::clone(&self.config); + tokio::spawn(handle_client(peer, stream, effect_builder, config, permit)); + } else { + warn!( + "connection limit reached, dropping connection from {}", + peer + ); + } + responder.respond(()).ignore() + } + Event::HandleRequest { request, responder } => { + let config = Arc::clone(&self.config); + let metrics = Arc::clone(&self.metrics); + async move { + let response = + handle_request(request, effect_builder, &config, &metrics).await; + responder.respond(response).await + } + .ignore() + } + }, + ComponentState::Fatal(msg) => { + error!( + msg, + ?event, + name = >::name(self), + "should not handle this event when this component has fatal error" + ); + Effects::new() + } + } + } +} + +impl InitializedComponent for BinaryPort +where + REv: From + + From + + From + + From + + From + + From + + From + + From + + From + + From + + Send, +{ + fn state(&self) -> &ComponentState { + &self.state + } + + fn set_state(&mut self, new_state: ComponentState) { + info!( + ?new_state, + name = >::name(self), + "component state changed" + ); + + self.state = new_state; + } +} + +impl PortBoundComponent for BinaryPort +where + REv: From + + From + + From + + From + + From + + From + + From + + From + + From + + From + + Send, +{ + type Error = ListeningError; + type ComponentEvent = Event; + + fn listen( + &mut self, + effect_builder: EffectBuilder, + ) -> Result, Self::Error> { + let local_addr = Arc::clone(&self.local_addr); + let server_join_handle = tokio::spawn(run_server( + local_addr, + effect_builder, + Arc::clone(&self.config), + Arc::clone(&self.shutdown_trigger), + )); + self.server_join_handle + .set(server_join_handle) + .expect("server join handle should not be set elsewhere"); + + Ok(Effects::new()) + } +} diff --git a/node/src/components/binary_port/event.rs b/node/src/components/binary_port/event.rs index 7201fe2a9e..c4fde1f5b1 100644 --- a/node/src/components/binary_port/event.rs +++ b/node/src/components/binary_port/event.rs @@ -3,7 +3,7 @@ use std::{ net::SocketAddr, }; -use casper_types::binary_port::{BinaryRequest, BinaryResponse, GetRequest, GlobalStateRequest}; +use casper_binary_port::{BinaryRequest, BinaryResponse, GetRequest, GlobalStateRequest}; use tokio::net::TcpStream; use crate::effect::Responder; diff --git a/node/src/components/binary_port/tests.rs b/node/src/components/binary_port/tests.rs index 1302b191f2..933e26925e 100644 --- a/node/src/components/binary_port/tests.rs +++ b/node/src/components/binary_port/tests.rs @@ -4,11 +4,9 @@ use derive_more::From; use rand::Rng; use serde::Serialize; -use casper_types::{ - binary_port::{BinaryRequest, BinaryResponse, GetRequest, GlobalStateRequest}, - BlockHeader, Digest, GlobalStateIdentifier, KeyTag, TestBlockBuilder, Timestamp, Transaction, - TransactionV1Builder, -}; +use casper_binary_port::{BinaryRequest, BinaryResponse, GetRequest, GlobalStateRequest}; + +use casper_types::{Digest, GlobalStateIdentifier, KeyTag, Transaction, TransactionV1Builder}; use crate::{ components::binary_port::event::Event as BinaryPortEvent, @@ -28,9 +26,8 @@ use futures::channel::oneshot::{self, Receiver}; use prometheus::Registry; use thiserror::Error as ThisError; -use casper_types::{ - binary_port::ErrorCode, testing::TestRng, Chainspec, ChainspecRawBytes, ProtocolVersion, -}; +use casper_binary_port::ErrorCode; +use casper_types::{testing::TestRng, Chainspec, ChainspecRawBytes, ProtocolVersion}; use crate::{ components::{ @@ -373,12 +370,6 @@ fn trie_request() -> BinaryRequest { fn try_speculative_exec_request(rng: &mut TestRng) -> BinaryRequest { BinaryRequest::TrySpeculativeExec { transaction: Transaction::V1(TransactionV1Builder::new_random(rng).build().unwrap()), - state_root_hash: Digest::hash([1u8; 32]), - block_time: Timestamp::random(rng), - protocol_version: ProtocolVersion::from_parts(2, 0, 0), - speculative_exec_at_block: BlockHeader::V2( - TestBlockBuilder::new().build(rng).take_header(), - ), } } diff --git a/node/src/components/consensus/era_supervisor.rs b/node/src/components/consensus/era_supervisor.rs index cbbc4f8a4c..7b14f6ed98 100644 --- a/node/src/components/consensus/era_supervisor.rs +++ b/node/src/components/consensus/era_supervisor.rs @@ -30,8 +30,9 @@ use rand::Rng; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use tracing::{debug, error, info, trace, warn}; +use casper_binary_port::{ConsensusStatus, ConsensusValidatorChanges}; + use casper_types::{ - binary_port::{ConsensusStatus, ConsensusValidatorChanges}, Approval, AsymmetricType, BlockHash, BlockHeader, Chainspec, ConsensusProtocolName, Digest, DisplayIter, EraId, PublicKey, RewardedSignatures, Timestamp, Transaction, TransactionHash, ValidatorChange, diff --git a/node/src/components/contract_runtime.rs b/node/src/components/contract_runtime.rs index 4c7bcb9e40..7abe1b5d9b 100644 --- a/node/src/components/contract_runtime.rs +++ b/node/src/components/contract_runtime.rs @@ -26,7 +26,7 @@ use lmdb::DatabaseFlags; use prometheus::Registry; use tracing::{debug, error, info, trace}; -use casper_execution_engine::engine_state::{DeployItem, EngineConfigBuilder, ExecutionEngineV1}; +use casper_execution_engine::engine_state::{EngineConfigBuilder, ExecutionEngineV1}; use casper_storage::{ data_access_layer::{ @@ -42,9 +42,7 @@ use casper_storage::{ system::{genesis::GenesisError, protocol_upgrade::ProtocolUpgradeError}, tracking_copy::TrackingCopyError, }; -use casper_types::{ - Chainspec, ChainspecRawBytes, ChainspecRegistry, ProtocolUpgradeConfig, Transaction, -}; +use casper_types::{Chainspec, ChainspecRawBytes, ChainspecRegistry, ProtocolUpgradeConfig}; use crate::{ components::{fetcher::FetchResponse, Component, ComponentState}, @@ -73,7 +71,7 @@ pub use operations::execute_finalized_block; use operations::speculatively_execute; pub(crate) use types::{ BlockAndExecutionArtifacts, ExecutionArtifact, ExecutionArtifacts, ExecutionPreState, - SpeculativeExecutionState, StepOutcome, + SpeculativeExecutionResult, StepOutcome, }; use utils::{exec_or_requeue, run_intensive_task}; @@ -557,30 +555,27 @@ impl ContractRuntime { effects } ContractRuntimeRequest::SpeculativelyExecute { - execution_prestate, + block_header, transaction, responder, } => { - if let Transaction::Deploy(deploy) = *transaction { - let execution_engine_v1 = Arc::clone(&self.execution_engine_v1); - let data_access_layer = Arc::clone(&self.data_access_layer); - async move { - let result = run_intensive_task(move || { - speculatively_execute( - data_access_layer.as_ref(), - execution_engine_v1.as_ref(), - execution_prestate, - DeployItem::from(deploy.clone()), - ) - }) - .await; - responder.respond(result).await - } - .ignore() - } else { - unreachable!() - //async move { responder.respond(Ok(None)).await }.ignore() + let chainspec = Arc::clone(&self.chainspec); + let data_access_layer = Arc::clone(&self.data_access_layer); + let execution_engine_v1 = Arc::clone(&self.execution_engine_v1); + async move { + let result = run_intensive_task(move || { + speculatively_execute( + data_access_layer.as_ref(), + chainspec.as_ref(), + execution_engine_v1.as_ref(), + *block_header, + *transaction, + ) + }) + .await; + responder.respond(result).await } + .ignore() } } } diff --git a/node/src/components/contract_runtime/metrics.rs b/node/src/components/contract_runtime/metrics.rs index f93517442d..67fc2fe6a0 100644 --- a/node/src/components/contract_runtime/metrics.rs +++ b/node/src/components/contract_runtime/metrics.rs @@ -17,8 +17,8 @@ const EXPONENTIAL_BUCKET_COUNT: usize = 10; const RUN_EXECUTE_NAME: &str = "contract_runtime_run_execute"; const RUN_EXECUTE_HELP: &str = "time in seconds to execute but not commit a contract"; -const APPLY_EFFECT_NAME: &str = "contract_runtime_apply_commit"; -const APPLY_EFFECT_HELP: &str = "time in seconds to commit the execution effects of a contract"; +const COMMIT_EFFECT_NAME: &str = "contract_runtime_commit_effects"; +const COMMIT_EFFECT_HELP: &str = "time in seconds to commit the effects of a tranasction execution"; const COMMIT_GENESIS_NAME: &str = "contract_runtime_commit_genesis"; const COMMIT_GENESIS_HELP: &str = "time in seconds to commit an genesis"; @@ -76,7 +76,7 @@ const EXEC_QUEUE_SIZE_HELP: &str = #[derive(Debug)] pub struct Metrics { pub(super) run_execute: Histogram, - pub(super) apply_effect: Histogram, + pub(super) commit_effects: Histogram, pub(super) commit_genesis: Histogram, pub(super) commit_upgrade: Histogram, pub(super) run_query: Histogram, @@ -124,10 +124,10 @@ impl Metrics { RUN_EXECUTE_HELP, common_buckets.clone(), )?, - apply_effect: utils::register_histogram_metric( + commit_effects: utils::register_histogram_metric( registry, - APPLY_EFFECT_NAME, - APPLY_EFFECT_HELP, + COMMIT_EFFECT_NAME, + COMMIT_EFFECT_HELP, common_buckets.clone(), )?, run_query: utils::register_histogram_metric( @@ -224,7 +224,7 @@ impl Metrics { impl Drop for Metrics { fn drop(&mut self) { unregister_metric!(self.registry, self.run_execute); - unregister_metric!(self.registry, self.apply_effect); + unregister_metric!(self.registry, self.commit_effects); unregister_metric!(self.registry, self.commit_genesis); unregister_metric!(self.registry, self.commit_upgrade); unregister_metric!(self.registry, self.run_query); diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 90594b695b..8bb59144b1 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -3,11 +3,7 @@ use std::{collections::BTreeMap, convert::TryInto, sync::Arc, time::Instant}; use itertools::Itertools; use tracing::{debug, error, info, trace, warn}; -use casper_execution_engine::engine_state::{ - self, - execution_result::{ExecutionResultAndMessages, ExecutionResults}, - DeployItem, ExecuteRequest, ExecutionEngineV1, ExecutionResult as EngineExecutionResult, -}; +use casper_execution_engine::engine_state::{ExecutionEngineV1, WasmV1Request}; use casper_storage::{ block_store::types::ApprovalsHashes, data_access_layer::{ @@ -17,40 +13,37 @@ use casper_storage::{ InsufficientBalanceHandling, PruneRequest, PruneResult, StepRequest, StepResult, TransferRequest, }, - global_state::{ - error::Error as GlobalStateError, - state::{ - lmdb::LmdbGlobalState, scratch::ScratchGlobalState, CommitProvider, ScratchProvider, - StateProvider, StateReader, - }, + global_state::state::{ + lmdb::LmdbGlobalState, scratch::ScratchGlobalState, CommitProvider, ScratchProvider, + StateProvider, StateReader, }, system::runtime_native::Config as NativeRuntimeConfig, }; use casper_types::{ - binary_port::SpeculativeExecutionResult, bytesrepr::{self, ToBytes, U32_SERIALIZED_LENGTH}, - contract_messages::Messages, execution::{Effects, ExecutionResult, TransformKindV2, TransformV2}, system::mint::BalanceHoldAddrTag, - BlockTime, BlockV2, CLValue, CategorizedTransaction, Chainspec, ChecksumRegistry, DeployHash, - Digest, EraEndV2, EraId, FeeHandling, GasLimited, Key, ProtocolVersion, PublicKey, Transaction, - TransactionCategory, U512, + BlockHeader, BlockTime, BlockV2, CLValue, CategorizedTransaction, Chainspec, ChecksumRegistry, + Digest, EraEndV2, EraId, FeeHandling, Gas, GasLimited, Key, Phase, ProtocolVersion, PublicKey, + Transaction, TransactionCategory, U512, }; use crate::{ components::{ contract_runtime::{ error::BlockExecutionError, types::StepOutcome, BlockAndExecutionArtifacts, - ExecutionPreState, Metrics, SpeculativeExecutionState, APPROVALS_CHECKSUM_NAME, - EXECUTION_RESULTS_CHECKSUM_NAME, + ExecutionPreState, Metrics, APPROVALS_CHECKSUM_NAME, EXECUTION_RESULTS_CHECKSUM_NAME, }, fetcher::FetchItem, }, - contract_runtime::{types::ExecutionArtifactOutcome, utils::calculate_prune_eras}, + contract_runtime::{ + types::{ExecutionArtifactOutcome, SpeculativeExecutionResult}, + utils::calculate_prune_eras, + }, types::{self, Chunkable, ExecutableBlock, InternalEraReport}, }; -use super::{ExecutionArtifact, ExecutionArtifacts}; +use super::ExecutionArtifacts; /// Executes a finalized block. #[allow(clippy::too_many_arguments)] @@ -81,9 +74,9 @@ pub fn execute_finalized_block( let mut state_root_hash = pre_state_root_hash; let mut artifacts = ExecutionArtifacts::with_capacity(executable_block.transactions.len()); - let block_time = executable_block.timestamp.millis(); + let block_time = BlockTime::new(executable_block.timestamp.millis()); let balance_handling = BalanceHandling::Available { - block_time, + block_time: executable_block.timestamp.millis(), hold_interval: chainspec.core_config.balance_hold_interval.millis(), }; let holds_epoch = Some(chainspec.balance_holds_epoch(executable_block.timestamp)); @@ -91,21 +84,35 @@ pub fn execute_finalized_block( let start = Instant::now(); let scratch_state = data_access_layer.get_scratch_global_state(); - let mut effects = Effects::new(); let system_costs = chainspec.system_costs_config; let insufficient_balance_handling = InsufficientBalanceHandling::HoldRemaining; let gas_price = Some(1); // < --TODO: this is where Karan's calculated gas price needs to be used for transaction in &executable_block.transactions { + let mut effects = Effects::new(); + let initiator_addr = transaction.initiator_addr(); let transaction_hash = transaction.hash(); let transaction_header = transaction.header(); let runtime_args = transaction.session_args().clone(); let entry_point = transaction.entry_point(); - let balance_identifier: BalanceIdentifier = transaction.initiator_addr().into(); + let authorization_keys = transaction.authorization_keys(); + + // NOTE: this is the allowed computation limit (gas limit) + let gas_limit = match transaction.gas_limit(&system_costs, None) { + Ok(gas) => gas, + Err(ite) => { + artifacts.push_invalid_transaction( + transaction_hash, + transaction_header.clone(), + ite.clone(), + ); + debug!(%ite, "invalid transaction"); + continue; + } + }; // NOTE: this is the actual adjusted cost (gas limit * gas price) - // NOT the allowed computation limit (gas limit) let cost = match transaction.gas_limit(&system_costs, gas_price) { Ok(gas) => gas.value(), Err(ite) => { @@ -119,6 +126,48 @@ pub fn execute_finalized_block( } }; + let balance_identifier = { + if !transaction.is_standard_payment() { + // execute custom payment logic, which is expected to + // interact with the handle payment contract to deposit + // sufficient token to cover the cost + + // this is the limit on how much gas we will allow custom payment code to consume + // this notion was originally referred to as the "leash" in the early design of the + // system. + let custom_payment_gas_limit = Gas::new(U512::from( + // TODO: this should have it's own chainspec value; in the meantime + // using a multiple of a small value. + chainspec.transaction_config.native_transfer_minimum_motes * 5, + )); + let pay_request = WasmV1Request::new( + state_root_hash, + protocol_version, + block_time, + transaction.clone(), + custom_payment_gas_limit, + Phase::Payment, + ); + let pay_result = execution_engine_v1.execute(&scratch_state, pay_request); + match artifacts.push_wasm_v1_result( + transaction_hash, + transaction_header.clone(), + pay_result, + ) { + ExecutionArtifactOutcome::RootNotFound => { + return Err(BlockExecutionError::RootNotFound(state_root_hash)) + } + ExecutionArtifactOutcome::Effects(custom_pay_effects) => { + effects.append(custom_pay_effects); + } + } + // balance request should check the handle payment purse, not initiator's purse + BalanceIdentifier::Payment + } else { + initiator_addr.into() + } + }; + let initial_balance_result = scratch_state.balance(BalanceRequest::new( state_root_hash, protocol_version, @@ -127,7 +176,6 @@ pub fn execute_finalized_block( )); let is_sufficient_balance = initial_balance_result.is_sufficient(cost); - let authorization_keys = transaction.authorization_keys(); match (transaction.category(), is_sufficient_balance) { (_, false) => { @@ -157,10 +205,7 @@ pub fn execute_finalized_block( ExecutionArtifactOutcome::RootNotFound => { return Err(BlockExecutionError::RootNotFound(state_root_hash)) } - ExecutionArtifactOutcome::Failure => { - continue; - } - ExecutionArtifactOutcome::Success(transfer_effects) => { + ExecutionArtifactOutcome::Effects(transfer_effects) => { effects.append(transfer_effects.clone()); } } @@ -185,7 +230,7 @@ pub fn execute_finalized_block( let bidding_result = scratch_state.bidding(BiddingRequest::new( native_runtime_config.clone(), state_root_hash, - block_time, + block_time.value(), protocol_version, transaction_hash, transaction.initiator_addr().account_hash(), @@ -201,59 +246,38 @@ pub fn execute_finalized_block( ExecutionArtifactOutcome::RootNotFound => { return Err(BlockExecutionError::RootNotFound(state_root_hash)) } - ExecutionArtifactOutcome::Failure => { - continue; - } - ExecutionArtifactOutcome::Success(bidding_effects) => { + ExecutionArtifactOutcome::Effects(bidding_effects) => { effects.append(bidding_effects.clone()); } } } (TransactionCategory::Standard, _) | (TransactionCategory::InstallUpgrade, _) => { - // TODO: i think fraser is doing the Transaction::V1(_) fixing here, but either way - // it needs to get done soonish to complete this work. All of this section needs - // a bit of a re-work to allow the rest of this logic to move further away from - // the legacy notions. - let (deploy_hash, deploy) = match transaction { - Transaction::Deploy(deploy) => { - let deploy_hash = *deploy.hash(); - (deploy_hash, deploy) - } - Transaction::V1(_) => continue, - }; - - let deploy_header = deploy.header().clone(); - let execute_request = ExecuteRequest::new( + let wasm_1_request = WasmV1Request::new( state_root_hash, - block_time, - vec![DeployItem::from(deploy.clone())], protocol_version, - PublicKey::clone(&executable_block.proposer), + block_time, + transaction.clone(), + gas_limit, + Phase::Session, ); - - let exec_result = execute( - &scratch_state, - execution_engine_v1, - metrics.clone(), - execute_request, - )?; - - trace!(?deploy_hash, ?exec_result, "transaction execution result"); - // As for now a given state is expected to exist. - let (state_hash, execution_result, messages) = commit_execution_results( - &scratch_state, - metrics.clone(), - state_root_hash, - deploy_hash, - exec_result, - )?; - artifacts.push(ExecutionArtifact::deploy( - deploy_hash, - deploy_header, - execution_result, - messages, - )); - state_root_hash = state_hash; + let wasm_1_result = execution_engine_v1.execute(&scratch_state, wasm_1_request); + trace!( + ?transaction_hash, + ?wasm_1_result, + "transaction execution result" + ); + match artifacts.push_wasm_v1_result( + transaction_hash, + transaction_header.clone(), + wasm_1_result, + ) { + ExecutionArtifactOutcome::RootNotFound => { + return Err(BlockExecutionError::RootNotFound(state_root_hash)) + } + ExecutionArtifactOutcome::Effects(wasm_effects) => { + effects.append(wasm_effects.clone()); + } + } } } @@ -268,7 +292,7 @@ pub fn execute_finalized_block( balance_identifier.clone(), BalanceHoldAddrTag::Gas, cost, - BlockTime::new(block_time), + block_time, chainspec.core_config.balance_hold_interval, insufficient_balance_handling, )); @@ -280,10 +304,7 @@ pub fn execute_finalized_block( ExecutionArtifactOutcome::RootNotFound => { return Err(BlockExecutionError::RootNotFound(state_root_hash)) } - ExecutionArtifactOutcome::Failure => { - continue; - } - ExecutionArtifactOutcome::Success(hold_effects) => { + ExecutionArtifactOutcome::Effects(hold_effects) => { effects.append(hold_effects.clone()) } } @@ -292,6 +313,8 @@ pub fn execute_finalized_block( // this is the current mainnet mechanism...pay up front // finalize at the end // we have the proposer of this block...just deposit to them + // call handle_payment and done + // add data_provider.fee(.. pay_to_proposer), get effects and done } FeeHandling::Accumulate => { // this is a variation on PayToProposer that was added for @@ -299,13 +322,23 @@ pub fn execute_finalized_block( // and distributed to administrative accounts as part of fee // distribution. So, we just send the payment to the accumulator // purse and move on. + // add data_provider.fee(.. accumulate), get effects and done } FeeHandling::Burn => { // this is a new variation that is not currently supported. // this is for future use...but it is very simple...the // fees are simply burned, lowering total supply. + // add data_provider.fee(.. burn), get effects and done } } + + // commit effects + scratch_state.commit(state_root_hash, effects)?; + if let Some(metrics) = metrics.as_ref() { + metrics + .commit_effects + .observe(start.elapsed().as_secs_f64()); + } } // calculate and store checksums for approvals and execution effects across the transactions in @@ -331,6 +364,7 @@ pub fn execute_finalized_block( compute_execution_results_checksum(artifacts.execution_results().into_iter())?; checksum_registry.insert(EXECUTION_RESULTS_CHECKSUM_NAME, execution_results_checksum); + let mut effects = Effects::new(); effects.push(TransformV2::new( Key::ChecksumRegistry, TransformKindV2::Write( @@ -339,14 +373,11 @@ pub fn execute_finalized_block( .into(), ), )); - + scratch_state.commit(state_root_hash, effects)?; txn_ids.into_iter().map(|id| id.approvals_hash()).collect() }; - // After all transaction processing has been completed, commit all of the effects. - scratch_state.commit(state_root_hash, effects)?; - - // Pay out block fees, if relevant. + // Pay out block fees, if relevant. This auto-commits { let fee_req = FeeRequest::new( native_runtime_config.clone(), @@ -385,12 +416,13 @@ pub fn execute_finalized_block( // at one point, they were going to be paid out per block (and might be in the future) // but it ended up settling on per era. the behavior is driven by Some / None // thus if in future the calling logic passes rewards per block it should just work as is. + // This auto-commits. if let Some(rewards) = &executable_block.rewards { let rewards_req = BlockRewardsRequest::new( native_runtime_config.clone(), state_root_hash, protocol_version, - block_time, + block_time.value(), rewards.clone(), ); match scratch_state.distribute_block_rewards(rewards_req) { @@ -467,7 +499,8 @@ pub fn execute_finalized_block( None }; - // Pruning + // Pruning -- this is orthogonal to the contents of the block, but we deliberately do it + // at the end to avoid an read ordering issue during block execution. if let Some(previous_block_height) = executable_block.height.checked_sub(1) { if let Some(keys_to_prune) = calculate_prune_eras( activation_point_era_id, @@ -535,6 +568,7 @@ pub fn execute_finalized_block( return Err(BlockExecutionError::Lmdb(gse)); } + // the rest of this is post process, picking out data bits to return to caller let maybe_next_era_validator_weights: Option> = { let next_era_id = executable_block.era_id.successor(); step_outcome.as_ref().and_then( @@ -600,6 +634,8 @@ pub fn execute_finalized_block( executable_block.rewarded_signatures, )); + // TODO: this should just use the data_access_layer.query mechanism to avoid + // leaking data provisioning abstraction let tc = match data_access_layer.tracking_copy(state_root_hash) { Ok(Some(tc)) => tc, Ok(None) => return Err(BlockExecutionError::RootNotFound(state_root_hash)), @@ -630,133 +666,40 @@ pub fn execute_finalized_block( }) } -/// Commits the execution results. -fn commit_execution_results( - scratch_state: &ScratchGlobalState, - metrics: Option>, - state_root_hash: Digest, - deploy_hash: DeployHash, - execution_results: ExecutionResults, -) -> Result<(Digest, ExecutionResult, Messages), BlockExecutionError> { - let ee_execution_result = execution_results - .into_iter() - .exactly_one() - .map_err(|_| BlockExecutionError::MoreThanOneExecutionResult)?; - - let effects = match &ee_execution_result { - EngineExecutionResult::Success { effects, cost, .. } => { - // We do want to see the deploy hash and cost in the logs. - // We don't need to see the effects in the logs. - debug!(?deploy_hash, %cost, "execution succeeded"); - effects.clone() - } - EngineExecutionResult::Failure { - error, - effects, - cost, - .. - } => { - // Failure to execute a contract is a user error, not a system error. - // We do want to see the deploy hash, error, and cost in the logs. - // We don't need to see the effects in the logs. - debug!(?deploy_hash, ?error, %cost, "execution failure"); - effects.clone() - } - }; - let new_state_root = commit_transforms(scratch_state, metrics, state_root_hash, effects)?; - let ExecutionResultAndMessages { - execution_result, - messages, - } = ExecutionResultAndMessages::from(ee_execution_result); - let versioned_execution_result = ExecutionResult::from(execution_result); - Ok((new_state_root, versioned_execution_result, messages)) -} - -fn commit_transforms( - scratch_state: &ScratchGlobalState, - metrics: Option>, - state_root_hash: Digest, - effects: Effects, -) -> Result { - trace!(?state_root_hash, ?effects, "commit"); - let start = Instant::now(); - let result = scratch_state.commit(state_root_hash, effects); - if let Some(metrics) = metrics { - metrics.apply_effect.observe(start.elapsed().as_secs_f64()); - } - trace!(?result, "commit result"); - result -} - /// Execute the transaction without committing the effects. /// Intended to be used for discovery operations on read-only nodes. /// /// Returns effects of the execution. pub fn speculatively_execute( state_provider: &S, + chainspec: &Chainspec, execution_engine_v1: &ExecutionEngineV1, - execution_state: SpeculativeExecutionState, - deploy: DeployItem, -) -> Result + block_header: BlockHeader, + transaction: Transaction, +) -> SpeculativeExecutionResult where S: StateProvider, { - let SpeculativeExecutionState { - state_root_hash, - block_time, - protocol_version, - } = execution_state; - let deploy_hash = deploy.deploy_hash; - let execute_request = ExecuteRequest::new( - state_root_hash, - block_time.millis(), - vec![deploy], + let state_root_hash = block_header.state_root_hash(); + let protocol_version = block_header.protocol_version(); + let block_time = block_header + .timestamp() + .saturating_add(chainspec.core_config.minimum_block_time); + let gas_limit = match transaction.gas_limit(&chainspec.system_costs_config, None) { + Ok(gas_limit) => gas_limit, + Err(_) => { + return SpeculativeExecutionResult::invalid_gas_limit(transaction); + } + }; + let request = WasmV1Request::new( + *state_root_hash, protocol_version, - PublicKey::System, + block_time.into(), + transaction, + gas_limit, + Phase::Session, ); - let results = execute(state_provider, execution_engine_v1, None, execute_request); - results.map(|mut execution_results| { - let len = execution_results.len(); - if len != 1 { - warn!( - ?deploy_hash, - "got more ({}) execution results from a single transaction", len - ); - SpeculativeExecutionResult::new(None) - } else { - // We know it must be 1, we could unwrap and then wrap - // with `Some(_)` but `pop_front` already returns an `Option`. - // We need to transform the `engine_state::ExecutionResult` into - // `casper_types::ExecutionResult` as well. - SpeculativeExecutionResult::new(execution_results.pop_front().map(|result| { - let ExecutionResultAndMessages { - execution_result, - messages, - } = result.into(); - - (execution_result, messages) - })) - } - }) -} - -fn execute( - state_provider: &S, - execution_engine_v1: &ExecutionEngineV1, - metrics: Option>, - execute_request: ExecuteRequest, -) -> Result -where - S: StateProvider, -{ - trace!(?execute_request, "execute"); - let start = Instant::now(); - let result = execution_engine_v1.exec(state_provider, execute_request); - if let Some(metrics) = metrics { - metrics.run_execute.observe(start.elapsed().as_secs_f64()); - } - trace!(?result, "execute result"); - result + SpeculativeExecutionResult::WasmV1(execution_engine_v1.execute(state_provider, request)) } #[allow(clippy::too_many_arguments)] diff --git a/node/src/components/contract_runtime/tests.rs b/node/src/components/contract_runtime/tests.rs index 857dba407c..4c83e7ee8b 100644 --- a/node/src/components/contract_runtime/tests.rs +++ b/node/src/components/contract_runtime/tests.rs @@ -8,7 +8,8 @@ use tempfile::TempDir; use casper_types::{ bytesrepr::Bytes, runtime_args, BlockHash, Chainspec, ChainspecRawBytes, Deploy, Digest, EraId, - ExecutableDeployItem, PublicKey, SecretKey, TimeDiff, Timestamp, TransactionCategory, U512, + ExecutableDeployItem, PublicKey, SecretKey, TimeDiff, Timestamp, Transaction, + TransactionCategory, U512, }; use super::*; diff --git a/node/src/components/contract_runtime/types.rs b/node/src/components/contract_runtime/types.rs index ffa6ccf01a..6429a31342 100644 --- a/node/src/components/contract_runtime/types.rs +++ b/node/src/components/contract_runtime/types.rs @@ -1,5 +1,6 @@ use std::{collections::BTreeMap, sync::Arc}; +use casper_execution_engine::engine_state::WasmV1Result; use datasize::DataSize; use serde::Serialize; use tracing::{debug, trace}; @@ -11,9 +12,9 @@ use casper_storage::{ use casper_types::{ contract_messages::Messages, execution::{Effects, ExecutionResult, ExecutionResultV2}, - BlockHash, BlockHeaderV2, BlockV2, DeployHash, DeployHeader, Digest, EraId, InvalidTransaction, - ProtocolVersion, PublicKey, Timestamp, TransactionHash, TransactionHeader, TransactionV1Hash, - TransactionV1Header, U512, + BlockHash, BlockHeaderV2, BlockV2, DeployHash, DeployHeader, Digest, EraId, InvalidDeploy, + InvalidTransaction, InvalidTransactionV1, ProtocolVersion, PublicKey, Transaction, + TransactionHash, TransactionHeader, TransactionV1Hash, TransactionV1Header, U512, }; /// Request for validator weights for a specific era. @@ -71,8 +72,7 @@ pub(crate) struct ExecutionArtifacts { pub(crate) enum ExecutionArtifactOutcome { RootNotFound, - Failure, - Success(Effects), + Effects(Effects), } impl ExecutionArtifacts { @@ -81,43 +81,41 @@ impl ExecutionArtifacts { ExecutionArtifacts { artifacts } } - pub fn push(&mut self, execution_artifact: ExecutionArtifact) { - self.artifacts.push(execution_artifact); - } - - pub fn push_invalid_transaction( + pub fn push_wasm_v1_result( &mut self, transaction_hash: TransactionHash, transaction_header: TransactionHeader, - invalid_transaction: InvalidTransaction, - ) { - self.push_failure( + wasm_v1_result: WasmV1Result, + ) -> ExecutionArtifactOutcome { + trace!(?transaction_hash, ?wasm_v1_result, "native transfer result"); + let effects = wasm_v1_result.effects().clone(); + let result = { + if let Some(error) = wasm_v1_result.error() { + if let casper_execution_engine::engine_state::Error::RootNotFound(_) = error { + return ExecutionArtifactOutcome::RootNotFound; + } + ExecutionResultV2::Failure { + effects: effects.clone(), + transfers: wasm_v1_result.transfers().clone(), + cost: wasm_v1_result.consumed().value(), + error_message: format!("{:?}", error), + } + } else { + ExecutionResultV2::Success { + effects: effects.clone(), + transfers: wasm_v1_result.transfers().clone(), + cost: wasm_v1_result.consumed().value(), + } + } + }; + self.artifacts.push(ExecutionArtifact::new( transaction_hash, transaction_header, - format!("{:?}", invalid_transaction), - ); - } + ExecutionResult::V2(result), + wasm_v1_result.messages().clone(), + )); - pub fn push_auction_method_failure( - &mut self, - transaction_hash: TransactionHash, - transaction_header: TransactionHeader, - cost: U512, - ) { - let msg = "failed to resolve auction method".to_string(); - let artifact = ExecutionArtifact::new( - transaction_hash, - transaction_header, - ExecutionResult::V2(ExecutionResultV2::Failure { - effects: Effects::new(), - transfers: vec![], - error_message: msg.clone(), - cost, - }), - Messages::default(), - ); - debug!(%transaction_hash, "{:?}", msg); - self.artifacts.push(artifact); + ExecutionArtifactOutcome::Effects(effects) } pub fn push_transfer_result( @@ -141,7 +139,7 @@ impl ExecutionArtifacts { format!("{:?}", transfer_error), ); debug!(%transfer_error); - ExecutionArtifactOutcome::Failure + ExecutionArtifactOutcome::Effects(Effects::new()) } TransferResult::Success { effects: transfer_effects, @@ -157,7 +155,7 @@ impl ExecutionArtifacts { }), Messages::default(), )); - ExecutionArtifactOutcome::Success(transfer_effects) + ExecutionArtifactOutcome::Effects(transfer_effects) } } } @@ -185,7 +183,7 @@ impl ExecutionArtifacts { Messages::default(), )); debug!(%tce); - ExecutionArtifactOutcome::Failure + ExecutionArtifactOutcome::Effects(Effects::new()) } BiddingResult::Success { effects: bidding_effects, @@ -201,7 +199,7 @@ impl ExecutionArtifacts { }), Messages::default(), )); - ExecutionArtifactOutcome::Success(bidding_effects) + ExecutionArtifactOutcome::Effects(bidding_effects) } } } @@ -216,14 +214,23 @@ impl ExecutionArtifacts { if hold_result.is_root_not_found() { return ExecutionArtifactOutcome::RootNotFound; } + let hold_cost = U512::zero(); // we don't charge for the hold itself. + let hold_effects = hold_result.effects(); if !hold_result.is_fully_covered() { let error_message = hold_result.error_message(); - self.push_failure(transaction_hash, transaction_header, error_message.clone()); + self.artifacts.push(ExecutionArtifact::new( + transaction_hash, + transaction_header, + ExecutionResult::V2(ExecutionResultV2::Failure { + effects: hold_effects.clone(), + transfers: vec![], + cost: hold_cost, + error_message: error_message.clone(), + }), + Messages::default(), + )); debug!(%error_message); - ExecutionArtifactOutcome::Failure } else { - let hold_cost = U512::zero(); // we don't charge for the hold itself. - let hold_effects = hold_result.effects(); self.artifacts.push(ExecutionArtifact::new( transaction_hash, transaction_header, @@ -234,8 +241,43 @@ impl ExecutionArtifacts { }), Messages::default(), )); - ExecutionArtifactOutcome::Success(hold_effects) } + ExecutionArtifactOutcome::Effects(hold_effects) + } + + pub fn push_invalid_transaction( + &mut self, + transaction_hash: TransactionHash, + transaction_header: TransactionHeader, + invalid_transaction: InvalidTransaction, + ) { + self.push_failure( + transaction_hash, + transaction_header, + format!("{:?}", invalid_transaction), + ); + } + + pub fn push_auction_method_failure( + &mut self, + transaction_hash: TransactionHash, + transaction_header: TransactionHeader, + cost: U512, + ) { + let msg = "failed to resolve auction method".to_string(); + let artifact = ExecutionArtifact::new( + transaction_hash, + transaction_header, + ExecutionResult::V2(ExecutionResultV2::Failure { + effects: Effects::new(), + transfers: vec![], + error_message: msg.clone(), + cost, + }), + Messages::default(), + ); + debug!(%transaction_hash, "{:?}", msg); + self.artifacts.push(artifact); } fn push_failure( @@ -293,6 +335,7 @@ impl ExecutionArtifact { } } + #[allow(unused)] pub(crate) fn deploy( deploy_hash: DeployHash, header: DeployHeader, @@ -338,15 +381,24 @@ pub struct BlockAndExecutionArtifacts { pub(crate) step_outcome: Option, } -#[derive(DataSize, Debug, Clone, Serialize)] -/// Wrapper for speculative execution prestate. -pub struct SpeculativeExecutionState { - /// State root on top of which to execute deploy. - pub state_root_hash: Digest, - /// Block time. - pub block_time: Timestamp, - /// Protocol version used when creating the original block. - pub protocol_version: ProtocolVersion, +/// Type representing results of the speculative execution. +#[derive(Debug)] +pub enum SpeculativeExecutionResult { + InvalidTransaction(InvalidTransaction), + WasmV1(WasmV1Result), +} + +impl SpeculativeExecutionResult { + pub fn invalid_gas_limit(transaction: Transaction) -> Self { + match transaction { + Transaction::Deploy(_) => SpeculativeExecutionResult::InvalidTransaction( + InvalidTransaction::Deploy(InvalidDeploy::UnableToCalculateGasLimit), + ), + Transaction::V1(_) => SpeculativeExecutionResult::InvalidTransaction( + InvalidTransaction::V1(InvalidTransactionV1::UnableToCalculateGasLimit), + ), + } + } } /// State to use to construct the next block in the blockchain. Includes the state root hash for the diff --git a/node/src/components/fetcher.rs b/node/src/components/fetcher.rs index 07b1bd351f..4f84f78273 100644 --- a/node/src/components/fetcher.rs +++ b/node/src/components/fetcher.rs @@ -134,7 +134,7 @@ where Source::PeerGossiped(peer) | Source::Peer(peer) => { self.got_from_peer(effect_builder, peer, item) } - Source::Client | Source::SpeculativeExec(_) | Source::Ourself => Effects::new(), + Source::Client | Source::SpeculativeExec | Source::Ourself => Effects::new(), }, Event::GotInvalidRemotely { .. } => Effects::new(), Event::AbsentRemotely { id, peer } => { diff --git a/node/src/components/fetcher/tests.rs b/node/src/components/fetcher/tests.rs index 4d15e6f258..5ee80f61c9 100644 --- a/node/src/components/fetcher/tests.rs +++ b/node/src/components/fetcher/tests.rs @@ -223,10 +223,10 @@ impl ReactorTrait for Reactor { } Event::AcceptTransactionRequest(AcceptTransactionRequest { transaction, - speculative_exec_at_block, + is_speculative, responder, }) => { - assert!(speculative_exec_at_block.is_none()); + assert!(!is_speculative); let event = transaction_acceptor::Event::Accept { transaction, source: Source::Client, @@ -382,7 +382,9 @@ impl NetworkedReactor for Reactor { fn announce_transaction_received( txn: Transaction, ) -> impl FnOnce(EffectBuilder) -> Effects { - |effect_builder: EffectBuilder| effect_builder.try_accept_transaction(txn, None).ignore() + |effect_builder: EffectBuilder| { + effect_builder.try_accept_transaction(txn, false).ignore() + } } type FetchedTransactionResult = Arc>)>>; diff --git a/node/src/components/gossiper/tests.rs b/node/src/components/gossiper/tests.rs index ef9d98796b..a1954ee9f7 100644 --- a/node/src/components/gossiper/tests.rs +++ b/node/src/components/gossiper/tests.rs @@ -266,10 +266,10 @@ impl reactor::Reactor for Reactor { ), Event::AcceptTransactionRequest(AcceptTransactionRequest { transaction, - speculative_exec_at_block, + is_speculative, responder, }) => { - assert!(speculative_exec_at_block.is_none()); + assert!(!is_speculative); let event = transaction_acceptor::Event::Accept { transaction, source: Source::Client, @@ -335,7 +335,9 @@ fn announce_transaction_received( transaction: &Transaction, ) -> impl FnOnce(EffectBuilder) -> Effects { let txn = transaction.clone(); - |effect_builder: EffectBuilder| effect_builder.try_accept_transaction(txn, None).ignore() + |effect_builder: EffectBuilder| { + effect_builder.try_accept_transaction(txn, false).ignore() + } } async fn run_gossip(rng: &mut TestRng, network_size: usize, txn_count: usize) { diff --git a/node/src/components/rest_server/info.rs b/node/src/components/rest_server/info.rs index cbabc8a261..8b0bb2ddef 100644 --- a/node/src/components/rest_server/info.rs +++ b/node/src/components/rest_server/info.rs @@ -3,10 +3,9 @@ use std::str; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use casper_types::{ - binary_port::ConsensusValidatorChanges, ChainspecRawBytes, EraId, ProtocolVersion, PublicKey, - ValidatorChange, -}; +use casper_binary_port::ConsensusValidatorChanges; + +use casper_types::{ChainspecRawBytes, EraId, ProtocolVersion, PublicKey, ValidatorChange}; /// A single change to a validator's status in the given era. #[derive(PartialEq, Eq, Serialize, Deserialize, Debug, JsonSchema)] diff --git a/node/src/components/storage.rs b/node/src/components/storage.rs index 9b44a58caf..b2ebadf3bb 100644 --- a/node/src/components/storage.rs +++ b/node/src/components/storage.rs @@ -59,10 +59,10 @@ use std::{ sync::Arc, }; +use casper_storage::DbRawBytesSpec; #[cfg(test)] use casper_types::SignedBlock; use casper_types::{ - binary_port::DbRawBytesSpec, bytesrepr::{FromBytes, ToBytes}, execution::{ execution_result_v1, ExecutionResult, ExecutionResultV1, ExecutionResultV2, TransformKindV2, diff --git a/node/src/components/storage/error.rs b/node/src/components/storage/error.rs index f5c609bdd1..1a0cd88a1d 100644 --- a/node/src/components/storage/error.rs +++ b/node/src/components/storage/error.rs @@ -4,13 +4,12 @@ use thiserror::Error; use tracing::error; use casper_types::{ - binary_port::RecordId, bytesrepr, crypto, BlockBody, BlockHash, BlockHeader, - BlockValidationError, DeployHash, Digest, EraId, FinalitySignature, FinalitySignatureId, - TransactionHash, + bytesrepr, crypto, BlockBody, BlockHash, BlockHeader, BlockValidationError, DeployHash, Digest, + EraId, FinalitySignature, FinalitySignatureId, TransactionHash, }; use crate::types::VariantMismatch; -use casper_storage::block_store::BlockStoreError; +use casper_storage::{block_store::BlockStoreError, RecordId}; /// A fatal storage component error. /// diff --git a/node/src/components/storage/tests.rs b/node/src/components/storage/tests.rs index c7e1ec6b9d..3edbded66d 100644 --- a/node/src/components/storage/tests.rs +++ b/node/src/components/storage/tests.rs @@ -1356,7 +1356,7 @@ fn prepare_exec_result_with_transfer( deploy_hash: &DeployHash, ) -> (ExecutionResult, Transfer) { let transfer = Transfer::new( - *deploy_hash, + deploy_hash.into(), rng.gen(), Some(rng.gen()), rng.gen(), @@ -2896,13 +2896,18 @@ fn check_block_operations_with_node_1_5_2_storage() { let transfers = get_block_transfers(&mut harness, &mut storage, *hash); if !block_info.deploy_hashes.is_empty() { - let mut stored_transfers: Vec = transfers + let mut stored_transfers: Vec = transfers .unwrap() .iter() - .map(|transfer| transfer.deploy_hash) + .map(|transfer| transfer.transaction_hash) .collect(); stored_transfers.sort(); - let mut expected_deploys = block_info.deploy_hashes.clone(); + let mut expected_deploys: Vec = block_info + .deploy_hashes + .clone() + .iter() + .map(|dh| TransactionHash::Deploy(*dh)) + .collect(); expected_deploys.sort(); assert_eq!(stored_transfers, expected_deploys); } diff --git a/node/src/components/transaction_acceptor.rs b/node/src/components/transaction_acceptor.rs index eb5505dc91..6b3446850f 100644 --- a/node/src/components/transaction_acceptor.rs +++ b/node/src/components/transaction_acceptor.rs @@ -162,22 +162,22 @@ impl TransactionAcceptor { ); } - // If this has been received from the speculative exec server, use the block specified in - // the request, otherwise use the highest complete block. - if let Source::SpeculativeExec(block_header) = &event_metadata.source { - let account_key = match event_metadata.transaction.initiator_addr() { - InitiatorAddr::PublicKey(public_key) => Key::from(public_key.to_account_hash()), - InitiatorAddr::AccountHash(account_hash) => Key::from(account_hash), - }; - let block_header = block_header.clone(); - return effect_builder - .get_addressable_entity(*block_header.state_root_hash(), account_key) - .event(move |result| Event::GetAddressableEntityResult { - event_metadata, - maybe_entity: result.into_option(), - block_header, - }); - } + // // If this has been received from the speculative exec server, use the block specified in + // // the request, otherwise use the highest complete block. + // if let Source::SpeculativeExec = &event_metadata.source { + // let account_key = match event_metadata.transaction.initiator_addr() { + // InitiatorAddr::PublicKey(public_key) => Key::from(public_key.to_account_hash()), + // InitiatorAddr::AccountHash(account_hash) => Key::from(account_hash), + // }; + // + // return effect_builder + // .get_addressable_entity(*block_header.state_root_hash(), account_key) + // .event(move |result| Event::GetAddressableEntityResult { + // event_metadata, + // maybe_entity: result.into_option(), + // block_header, + // }); + // } effect_builder .get_highest_complete_block_header_from_storage() @@ -354,6 +354,18 @@ impl TransactionAcceptor { maybe_entity: result.into_option(), }) } + ExecutableDeployItemIdentifier::AddressableEntity( + AddressableEntityIdentifier::Addr(entity_addr), + ) => { + let query_key = Key::AddressableEntity(entity_addr); + effect_builder + .get_addressable_entity(*block_header.state_root_hash(), query_key) + .event(move |result| Event::GetAddressableEntityResult { + event_metadata, + block_header, + maybe_entity: result.into_option(), + }) + } ExecutableDeployItemIdentifier::Package( ref contract_package_identifier @ PackageIdentifier::Hash { package_hash, .. }, ) => { @@ -461,6 +473,18 @@ impl TransactionAcceptor { maybe_entity: result.into_option(), }) } + ExecutableDeployItemIdentifier::AddressableEntity( + AddressableEntityIdentifier::Addr(entity_addr), + ) => { + let key = Key::AddressableEntity(entity_addr); + effect_builder + .get_addressable_entity(*block_header.state_root_hash(), key) + .event(move |result| Event::GetAddressableEntityResult { + event_metadata, + block_header, + maybe_entity: result.into_option(), + }) + } ExecutableDeployItemIdentifier::Package( ref package_identifier @ PackageIdentifier::Hash { package_hash, .. }, ) => { @@ -709,7 +733,7 @@ impl TransactionAcceptor { // If this has been received from the speculative exec server, we just want to call the // responder and finish. Otherwise store the transaction and announce it if required. - if let Source::SpeculativeExec(_) = event_metadata.source { + if let Source::SpeculativeExec = event_metadata.source { if let Some(responder) = event_metadata.maybe_responder { return responder.respond(Ok(())).ignore(); } @@ -738,9 +762,7 @@ impl TransactionAcceptor { maybe_responder, verification_start_timestamp, } = event_metadata; - if !matches!(source, Source::SpeculativeExec(_)) { - self.metrics.observe_rejected(verification_start_timestamp); - } + self.metrics.observe_rejected(verification_start_timestamp); let mut effects = Effects::new(); if let Some(responder) = maybe_responder { // The client has submitted an invalid transaction @@ -748,14 +770,11 @@ impl TransactionAcceptor { effects.extend(responder.respond(Err(error)).ignore()); } - // If this has NOT been received from the speculative exec server, announce it. - if !matches!(source, Source::SpeculativeExec(_)) { - effects.extend( - effect_builder - .announce_invalid_transaction(transaction, source) - .ignore(), - ); - } + effects.extend( + effect_builder + .announce_invalid_transaction(transaction, source) + .ignore(), + ); effects } diff --git a/node/src/components/transaction_acceptor/error.rs b/node/src/components/transaction_acceptor/error.rs index c4fc8eb6fd..f3d76c6940 100644 --- a/node/src/components/transaction_acceptor/error.rs +++ b/node/src/components/transaction_acceptor/error.rs @@ -2,9 +2,10 @@ use datasize::DataSize; use serde::Serialize; use thiserror::Error; +use casper_binary_port::ErrorCode as BinaryPortErrorCode; use casper_types::{ - binary_port, AddressableEntityHash, BlockHash, BlockHeader, Digest, EntityVersion, - InitiatorAddr, InvalidTransaction, PackageHash, Timestamp, + AddressableEntityHash, BlockHash, BlockHeader, Digest, EntityVersion, InitiatorAddr, + InvalidTransaction, PackageHash, Timestamp, }; // `allow` can be removed once https://github.com/casper-network/casper-node/issues/3063 is fixed. @@ -64,7 +65,7 @@ impl Error { } } -impl From for binary_port::ErrorCode { +impl From for BinaryPortErrorCode { fn from(err: Error) -> Self { match err { Error::EmptyBlockchain @@ -72,7 +73,7 @@ impl From for binary_port::ErrorCode { | Error::Parameters { .. } | Error::Expired { .. } | Error::ExpectedDeploy - | Error::ExpectedTransactionV1 => binary_port::ErrorCode::InvalidTransaction, + | Error::ExpectedTransactionV1 => BinaryPortErrorCode::InvalidTransaction, } } } diff --git a/node/src/components/transaction_acceptor/tests.rs b/node/src/components/transaction_acceptor/tests.rs index 29522b35db..5f02959f6a 100644 --- a/node/src/components/transaction_acceptor/tests.rs +++ b/node/src/components/transaction_acceptor/tests.rs @@ -21,7 +21,10 @@ use thiserror::Error; use tokio::time; use casper_execution_engine::engine_state::MAX_PAYMENT_AMOUNT; -use casper_storage::data_access_layer::{AddressableEntityResult, BalanceResult, QueryResult}; +use casper_storage::{ + data_access_layer::{AddressableEntityResult, BalanceIdentifier, BalanceResult, QueryResult}, + tracking_copy::TrackingCopyError, +}; use casper_types::{ account::{Account, AccountHash, ActionThresholds, AssociatedKeys, Weight}, addressable_entity::{AddressableEntity, NamedKeys}, @@ -31,7 +34,7 @@ use casper_types::{ Block, BlockV2, CLValue, Chainspec, ChainspecRawBytes, Contract, Deploy, EraId, HashAddr, InvalidDeploy, InvalidTransaction, InvalidTransactionV1, Package, PublicKey, SecretKey, StoredValue, TestBlockBuilder, TimeDiff, Timestamp, Transaction, TransactionSessionKind, - TransactionV1, TransactionV1Builder, URef, URefAddr, U512, + TransactionV1, TransactionV1Builder, URef, U512, }; use super::*; @@ -730,11 +733,35 @@ impl reactor::Reactor for Reactor { request: balance_request, responder, } => { - let key = balance_request.identifier().as_key(); - + let key = match balance_request.identifier() { + BalanceIdentifier::Purse(uref) => Key::URef(*uref), + BalanceIdentifier::Public(public_key) => { + Key::Account(public_key.to_account_hash()) + } + BalanceIdentifier::Account(account_hash) => Key::Account(*account_hash), + BalanceIdentifier::Entity(entity_addr) => { + Key::AddressableEntity(*entity_addr) + } + BalanceIdentifier::Internal(addr) => Key::Balance(*addr), + BalanceIdentifier::Payment => { + responder + .respond(BalanceResult::Failure( + TrackingCopyError::NamedKeyNotFound("payment".to_string()), + )) + .ignore::(); + return Effects::new(); + } + }; let purse_addr = match balance_request.identifier().as_purse_addr() { - None => URefAddr::default(), Some(purse_addr) => purse_addr, + None => { + responder + .respond(BalanceResult::Failure( + TrackingCopyError::UnexpectedKeyVariant(key), + )) + .ignore::(); + return Effects::new(); + } }; let proof = TrieMerkleProof::new( diff --git a/node/src/effect.rs b/node/src/effect.rs index 6c46bd8252..076fea94d4 100644 --- a/node/src/effect.rs +++ b/node/src/effect.rs @@ -114,22 +114,20 @@ use smallvec::{smallvec, SmallVec}; use tokio::{sync::Semaphore, time}; use tracing::{debug, error, warn}; -use casper_execution_engine::engine_state::{self}; -use casper_storage::data_access_layer::{ - tagged_values::{TaggedValuesRequest, TaggedValuesResult}, - BalanceRequest, BalanceResult, QueryRequest, QueryResult, +use casper_binary_port::{ + ConsensusStatus, ConsensusValidatorChanges, LastProgress, NetworkName, Uptime, }; - -use casper_storage::data_access_layer::{ - AddressableEntityResult, EraValidatorsRequest, EraValidatorsResult, - ExecutionResultsChecksumResult, PutTrieRequest, PutTrieResult, RoundSeigniorageRateRequest, - RoundSeigniorageRateResult, TotalSupplyRequest, TotalSupplyResult, TrieRequest, TrieResult, +use casper_storage::{ + data_access_layer::{ + tagged_values::{TaggedValuesRequest, TaggedValuesResult}, + AddressableEntityResult, BalanceRequest, BalanceResult, EraValidatorsRequest, + EraValidatorsResult, ExecutionResultsChecksumResult, PutTrieRequest, PutTrieResult, + QueryRequest, QueryResult, RoundSeigniorageRateRequest, RoundSeigniorageRateResult, + TotalSupplyRequest, TotalSupplyResult, TrieRequest, TrieResult, + }, + DbRawBytesSpec, RecordId, }; use casper_types::{ - binary_port::{ - ConsensusStatus, ConsensusValidatorChanges, DbRawBytesSpec, LastProgress, NetworkName, - RecordId, SpeculativeExecutionResult, Uptime, - }, execution::{Effects as ExecutionEffects, ExecutionResult}, package::Package, Approval, AvailableBlockRange, Block, BlockHash, BlockHeader, BlockSignatures, @@ -152,7 +150,6 @@ use crate::{ network::{blocklist::BlocklistJustification, FromIncoming, NetworkInsights}, transaction_acceptor, }, - contract_runtime::SpeculativeExecutionState, failpoints::FailpointActivation, reactor::{main_reactor::ReactorState, EventQueueHandle, QueueKind}, types::{ @@ -164,7 +161,9 @@ use crate::{ }; use casper_storage::block_store::types::ApprovalsHashes; -use crate::effect::requests::TransactionBufferRequest; +use crate::{ + contract_runtime::SpeculativeExecutionResult, effect::requests::TransactionBufferRequest, +}; use announcements::{ BlockAccumulatorAnnouncement, ConsensusAnnouncement, ContractRuntimeAnnouncement, ControlAnnouncement, FatalAnnouncement, FetchedNewBlockAnnouncement, @@ -926,7 +925,7 @@ impl EffectBuilder { pub(crate) async fn try_accept_transaction( self, transaction: Transaction, - speculative_exec_at_block: Option>, + is_speculative: bool, ) -> Result<(), transaction_acceptor::Error> where REv: From, @@ -934,7 +933,7 @@ impl EffectBuilder { self.make_request( |responder| AcceptTransactionRequest { transaction, - speculative_exec_at_block, + is_speculative, responder, }, QueueKind::Api, @@ -2220,15 +2219,15 @@ impl EffectBuilder { /// used for debugging & discovery purposes. pub(crate) async fn speculatively_execute( self, - execution_prestate: SpeculativeExecutionState, + block_header: Box, transaction: Box, - ) -> Result + ) -> SpeculativeExecutionResult where REv: From, { self.make_request( |responder| ContractRuntimeRequest::SpeculativelyExecute { - execution_prestate, + block_header, transaction, responder, }, diff --git a/node/src/effect/requests.rs b/node/src/effect/requests.rs index 92c0f16b62..fc32aaa09f 100644 --- a/node/src/effect/requests.rs +++ b/node/src/effect/requests.rs @@ -15,24 +15,25 @@ use serde::Serialize; use smallvec::SmallVec; use static_assertions::const_assert; -use casper_execution_engine::engine_state::{self}; -use casper_storage::data_access_layer::{ - tagged_values::{TaggedValuesRequest, TaggedValuesResult}, - AddressableEntityResult, BalanceRequest, BalanceResult, EraValidatorsRequest, - EraValidatorsResult, ExecutionResultsChecksumResult, PutTrieRequest, PutTrieResult, - QueryRequest, QueryResult, RoundSeigniorageRateRequest, RoundSeigniorageRateResult, - TotalSupplyRequest, TotalSupplyResult, TrieRequest, TrieResult, +use casper_binary_port::{ + ConsensusStatus, ConsensusValidatorChanges, LastProgress, NetworkName, Uptime, +}; +use casper_storage::{ + data_access_layer::{ + tagged_values::{TaggedValuesRequest, TaggedValuesResult}, + AddressableEntityResult, BalanceRequest, BalanceResult, EraValidatorsRequest, + EraValidatorsResult, ExecutionResultsChecksumResult, PutTrieRequest, PutTrieResult, + QueryRequest, QueryResult, RoundSeigniorageRateRequest, RoundSeigniorageRateResult, + TotalSupplyRequest, TotalSupplyResult, TrieRequest, TrieResult, + }, + DbRawBytesSpec, RecordId, }; use casper_types::{ - binary_port::{ - ConsensusStatus, ConsensusValidatorChanges, DbRawBytesSpec, LastProgress, NetworkName, - RecordId, SpeculativeExecutionResult, Uptime, - }, - execution::ExecutionResult, - Approval, AvailableBlockRange, Block, BlockHash, BlockHeader, BlockSignatures, - BlockSynchronizerStatus, BlockV2, ChainspecRawBytes, DeployHash, Digest, DisplayIter, EraId, - ExecutionInfo, FinalitySignature, FinalitySignatureId, Key, NextUpgrade, ProtocolVersion, - PublicKey, Timestamp, Transaction, TransactionHash, TransactionHeader, TransactionId, Transfer, + execution::ExecutionResult, Approval, AvailableBlockRange, Block, BlockHash, BlockHeader, + BlockSignatures, BlockSynchronizerStatus, BlockV2, ChainspecRawBytes, DeployHash, Digest, + DisplayIter, EraId, ExecutionInfo, FinalitySignature, FinalitySignatureId, Key, NextUpgrade, + ProtocolVersion, PublicKey, Timestamp, Transaction, TransactionHash, TransactionHeader, + TransactionId, Transfer, }; use super::{AutoClosingResponder, GossipTarget, Responder}; @@ -49,7 +50,7 @@ use crate::{ network::NetworkInsights, transaction_acceptor, }, - contract_runtime::SpeculativeExecutionState, + contract_runtime::SpeculativeExecutionResult, reactor::main_reactor::ReactorState, types::{ appendable_block::AppendableBlock, BlockExecutionResultsOrChunk, @@ -815,12 +816,12 @@ pub(crate) enum ContractRuntimeRequest { }, /// Execute transaction without committing results SpeculativelyExecute { - /// Hash of a block on top of which to execute the transaction. - execution_prestate: SpeculativeExecutionState, + /// Pre-state. + block_header: Box, /// Transaction to execute. transaction: Box, /// Results - responder: Responder>, + responder: Responder, }, } @@ -896,15 +897,15 @@ impl Display for ContractRuntimeRequest { write!(formatter, "trie: {:?}", request) } ContractRuntimeRequest::SpeculativelyExecute { - execution_prestate, transaction, + block_header, .. } => { write!( formatter, "Execute {} on {}", transaction.hash(), - execution_prestate.state_root_hash + block_header.state_root_hash() ) } } @@ -1138,20 +1139,17 @@ impl Display for SetNodeStopRequest { #[derive(DataSize, Debug, Serialize)] pub(crate) struct AcceptTransactionRequest { pub(crate) transaction: Transaction, - pub(crate) speculative_exec_at_block: Option>, + pub(crate) is_speculative: bool, pub(crate) responder: Responder>, } impl Display for AcceptTransactionRequest { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - if self.speculative_exec_at_block.is_some() { - write!( - f, - "accept transaction {} for speculative exec", - self.transaction.hash() - ) - } else { - write!(f, "accept transaction {}", self.transaction.hash()) - } + write!( + f, + "accept transaction {} is_speculative: {}", + self.transaction.hash(), + self.is_speculative + ) } } diff --git a/node/src/reactor/main_reactor.rs b/node/src/reactor/main_reactor.rs index 43c41d7bfa..1820a5feb1 100644 --- a/node/src/reactor/main_reactor.rs +++ b/node/src/reactor/main_reactor.rs @@ -25,8 +25,8 @@ use memory_metrics::MemoryMetrics; use prometheus::Registry; use tracing::{debug, error, info, warn}; +use casper_binary_port::{LastProgress, NetworkName, Uptime}; use casper_types::{ - binary_port::{LastProgress, NetworkName, Uptime}, Block, BlockHash, BlockV2, Chainspec, ChainspecRawBytes, EraId, FinalitySignature, FinalitySignatureV2, PublicKey, TimeDiff, Timestamp, Transaction, U512, }; @@ -719,11 +719,11 @@ impl reactor::Reactor for MainReactor { ), MainEvent::AcceptTransactionRequest(AcceptTransactionRequest { transaction, - speculative_exec_at_block, + is_speculative, responder, }) => { - let source = if let Some(block) = speculative_exec_at_block { - Source::SpeculativeExec(block) + let source = if is_speculative { + Source::SpeculativeExec } else { Source::Client }; @@ -783,7 +783,7 @@ impl reactor::Reactor for MainReactor { ), )); } - Source::SpeculativeExec(_) => { + Source::SpeculativeExec => { error!( %transaction, "transaction acceptor should not announce speculative exec transactions" diff --git a/node/src/reactor/main_reactor/tests/binary_port.rs b/node/src/reactor/main_reactor/tests/binary_port.rs index be8411f5d6..6de6e0584e 100644 --- a/node/src/reactor/main_reactor/tests/binary_port.rs +++ b/node/src/reactor/main_reactor/tests/binary_port.rs @@ -1,12 +1,13 @@ use std::{collections::HashMap, convert::TryInto, sync::Arc, time::Duration}; +use casper_binary_port::{ + BinaryRequest, BinaryRequestHeader, BinaryResponse, BinaryResponseAndRequest, ConsensusStatus, + ConsensusValidatorChanges, ErrorCode, GetRequest, GetTrieFullResult, GlobalStateQueryResult, + GlobalStateRequest, InformationRequest, InformationRequestTag, LastProgress, NetworkName, + NodeStatus, PayloadType, ReactorStateName, Uptime, +}; +use casper_storage::RecordId; use casper_types::{ - binary_port::{ - BinaryRequest, BinaryRequestHeader, BinaryResponse, BinaryResponseAndRequest, - ConsensusStatus, ConsensusValidatorChanges, ErrorCode, GetRequest, GetTrieFullResult, - GlobalStateQueryResult, GlobalStateRequest, InformationRequest, InformationRequestTag, - LastProgress, NetworkName, NodeStatus, PayloadType, ReactorStateName, RecordId, Uptime, - }, bytesrepr::{FromBytes, ToBytes}, testing::TestRng, AvailableBlockRange, Block, BlockHash, BlockHeader, BlockIdentifier, BlockSynchronizerStatus, @@ -233,7 +234,7 @@ async fn binary_port_component() { get_era_summary(*highest_block.state_root_hash()), get_all_bids(*highest_block.state_root_hash()), get_trie(*highest_block.state_root_hash()), - try_spec_exec_invalid(&mut rng, highest_block.clone_header()), + try_spec_exec_invalid(&mut rng), try_accept_transaction_invalid(&mut rng), try_accept_transaction(&secret_signing_key), ]; @@ -627,17 +628,11 @@ fn try_accept_transaction_invalid(rng: &mut TestRng) -> TestCase { } } -fn try_spec_exec_invalid(rng: &mut TestRng, header: BlockHeader) -> TestCase { +fn try_spec_exec_invalid(rng: &mut TestRng) -> TestCase { let transaction = Transaction::V1(TransactionV1Builder::new_random(rng).build().unwrap()); TestCase { name: "try_spec_exec_invalid", - request: BinaryRequest::TrySpeculativeExec { - state_root_hash: *header.state_root_hash(), - block_time: header.timestamp(), - protocol_version: header.protocol_version(), - transaction, - speculative_exec_at_block: header, - }, + request: BinaryRequest::TrySpeculativeExec { transaction }, asserter: Box::new(|response| response.error_code() == ErrorCode::InvalidTransaction as u8), } } diff --git a/node/src/types/status_feed.rs b/node/src/types/status_feed.rs index 8f4eb55794..f90160b2d8 100644 --- a/node/src/types/status_feed.rs +++ b/node/src/types/status_feed.rs @@ -8,10 +8,10 @@ use once_cell::sync::Lazy; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +use casper_binary_port::ConsensusStatus; use casper_types::{ - binary_port::ConsensusStatus, ActivationPoint, AvailableBlockRange, Block, BlockHash, - BlockSynchronizerStatus, Digest, EraId, NextUpgrade, Peers, ProtocolVersion, PublicKey, - TimeDiff, Timestamp, + ActivationPoint, AvailableBlockRange, Block, BlockHash, BlockSynchronizerStatus, Digest, EraId, + NextUpgrade, Peers, ProtocolVersion, PublicKey, TimeDiff, Timestamp, }; use crate::{ diff --git a/node/src/utils.rs b/node/src/utils.rs index 41b6de2e24..42b124cefd 100644 --- a/node/src/utils.rs +++ b/node/src/utils.rs @@ -38,8 +38,6 @@ use serde::Serialize; use thiserror::Error; use tracing::{error, warn}; -use casper_types::BlockHeader; - use crate::types::NodeId; pub(crate) use block_signatures::{check_sufficient_block_signatures, BlockSignatureError}; pub(crate) use display_error::display_error; @@ -263,7 +261,7 @@ pub(crate) enum Source { /// A client. Client, /// A client via the speculative_exec server. - SpeculativeExec(Box), + SpeculativeExec, /// This node. Ourself, } @@ -272,7 +270,7 @@ impl Source { #[allow(clippy::wrong_self_convention)] pub(crate) fn is_client(&self) -> bool { match self { - Source::Client | Source::SpeculativeExec(_) => true, + Source::Client | Source::SpeculativeExec => true, Source::PeerGossiped(_) | Source::Peer(_) | Source::Ourself => false, } } @@ -281,7 +279,7 @@ impl Source { pub(crate) fn node_id(&self) -> Option { match self { Source::Peer(node_id) | Source::PeerGossiped(node_id) => Some(*node_id), - Source::Client | Source::SpeculativeExec(_) | Source::Ourself => None, + Source::Client | Source::SpeculativeExec | Source::Ourself => None, } } } @@ -292,7 +290,7 @@ impl Display for Source { Source::PeerGossiped(node_id) => Display::fmt(node_id, formatter), Source::Peer(node_id) => Display::fmt(node_id, formatter), Source::Client => write!(formatter, "client"), - Source::SpeculativeExec(_) => write!(formatter, "client (speculative exec)"), + Source::SpeculativeExec => write!(formatter, "client (speculative exec)"), Source::Ourself => write!(formatter, "ourself"), } } diff --git a/storage/README.md b/storage/README.md index 53433e99f6..cbcd18a26a 100644 --- a/storage/README.md +++ b/storage/README.md @@ -1,10 +1,10 @@ -# `casper-hashing` +# `casper-storage` [![LOGO](https://raw.githubusercontent.com/casper-network/casper-node/master/images/casper-association-logo-primary.svg)](https://casper.network/) [![Build Status](https://drone-auto-casper-network.casperlabs.io/api/badges/casper-network/casper-node/status.svg?branch=dev)](http://drone-auto-casper-network.casperlabs.io/casper-network/casper-node) -[![Crates.io](https://img.shields.io/crates/v/casper-hashing)](https://crates.io/crates/casper-hashing) -[![Documentation](https://docs.rs/casper-hashing/badge.svg)](https://docs.rs/casper-hashing) +[![Crates.io](https://img.shields.io/crates/v/casper-hashing)](https://crates.io/crates/casper-storage) +[![Documentation](https://docs.rs/casper-hashing/badge.svg)](https://docs.rs/casper-storage) [![License](https://img.shields.io/badge/license-Apache-blue)](https://github.com/CasperLabs/casper-node/blob/master/LICENSE) A library providing storage functionality for Casper nodes. diff --git a/storage/src/block_store/lmdb/indexed_lmdb_block_store.rs b/storage/src/block_store/lmdb/indexed_lmdb_block_store.rs index d275f4591d..7b4cefa3a2 100644 --- a/storage/src/block_store/lmdb/indexed_lmdb_block_store.rs +++ b/storage/src/block_store/lmdb/indexed_lmdb_block_store.rs @@ -14,17 +14,16 @@ use tracing::info; use super::versioned_databases::VersionedDatabases; use crate::block_store::{ block_provider::{BlockStoreTransaction, DataReader, DataWriter}, + record_id::RecordId, types::{ ApprovalsHashes, BlockExecutionResults, BlockHashHeightAndEra, BlockHeight, BlockTransfers, LatestSwitchBlock, StateStore, StateStoreKey, Tip, TransactionFinalizedApprovals, }, - BlockStoreError, BlockStoreProvider, + BlockStoreError, BlockStoreProvider, DbRawBytesSpec, }; use casper_types::{ - binary_port::{DbRawBytesSpec, RecordId}, - execution::ExecutionResult, - Approval, Block, BlockBody, BlockHash, BlockHeader, BlockSignatures, Digest, EraId, - ProtocolVersion, Transaction, TransactionHash, Transfer, + execution::ExecutionResult, Approval, Block, BlockBody, BlockHash, BlockHeader, + BlockSignatures, Digest, EraId, ProtocolVersion, Transaction, TransactionHash, Transfer, }; #[derive(DataSize, Debug)] diff --git a/storage/src/block_store/lmdb/versioned_databases.rs b/storage/src/block_store/lmdb/versioned_databases.rs index f9da9f6127..8cd291f53c 100644 --- a/storage/src/block_store/lmdb/versioned_databases.rs +++ b/storage/src/block_store/lmdb/versioned_databases.rs @@ -9,7 +9,6 @@ use serde::Serialize; use std::{collections::BTreeSet, marker::PhantomData}; use casper_types::{ - binary_port::DbRawBytesSpec, bytesrepr::{FromBytes, ToBytes}, execution::ExecutionResult, Approval, BlockBody, BlockBodyV1, BlockHash, BlockHeader, BlockHeaderV1, BlockSignatures, @@ -20,6 +19,7 @@ use super::lmdb_ext::{self, LmdbExtError, TransactionExt, WriteTransactionExt}; use crate::block_store::{ error::BlockStoreError, types::{ApprovalsHashes, DeployMetadataV1, LegacyApprovalsHashes}, + DbRawBytesSpec, }; pub(crate) trait VersionedKey: ToBytes { diff --git a/storage/src/block_store/mod.rs b/storage/src/block_store/mod.rs index 2b424d967c..4779e3e175 100644 --- a/storage/src/block_store/mod.rs +++ b/storage/src/block_store/mod.rs @@ -1,7 +1,45 @@ mod block_provider; mod error; pub mod lmdb; +pub mod record_id; pub mod types; pub use block_provider::{BlockStoreProvider, BlockStoreTransaction, DataReader, DataWriter}; pub use error::BlockStoreError; +pub use record_id::{RecordId, UnknownRecordId}; + +/// Stores raw bytes from the DB along with the flag indicating whether data come from legacy or +/// current version of the DB. +#[derive(Debug)] +pub struct DbRawBytesSpec { + is_legacy: bool, + raw_bytes: Vec, +} + +impl DbRawBytesSpec { + /// Creates a variant indicating that raw bytes are coming from the legacy database. + pub fn new_legacy(raw_bytes: &[u8]) -> Self { + Self { + is_legacy: true, + raw_bytes: raw_bytes.to_vec(), + } + } + + /// Creates a variant indicating that raw bytes are coming from the current database. + pub fn new_current(raw_bytes: &[u8]) -> Self { + Self { + is_legacy: false, + raw_bytes: raw_bytes.to_vec(), + } + } + + /// Is legacy? + pub fn is_legacy(&self) -> bool { + self.is_legacy + } + + /// Raw bytes. + pub fn raw_bytes(&self) -> Vec { + self.raw_bytes.clone() + } +} diff --git a/types/src/binary_port/record_id.rs b/storage/src/block_store/record_id.rs similarity index 96% rename from types/src/binary_port/record_id.rs rename to storage/src/block_store/record_id.rs index f7ef6dfe36..649a574fea 100644 --- a/types/src/binary_port/record_id.rs +++ b/storage/src/block_store/record_id.rs @@ -5,7 +5,7 @@ use rand::Rng; use serde::Serialize; #[cfg(test)] -use crate::testing::TestRng; +use casper_types::testing::TestRng; /// An identifier of a record type. #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)] @@ -31,7 +31,7 @@ pub enum RecordId { impl RecordId { #[cfg(test)] - pub(crate) fn random(rng: &mut TestRng) -> Self { + pub fn random(rng: &mut TestRng) -> Self { match rng.gen_range(0..8) { 0 => RecordId::BlockHeader, 1 => RecordId::BlockBody, @@ -92,7 +92,7 @@ pub struct UnknownRecordId(u16); #[cfg(test)] mod tests { use super::*; - use crate::testing::TestRng; + use casper_types::testing::TestRng; #[test] fn tag_roundtrip() { diff --git a/storage/src/data_access_layer/balance.rs b/storage/src/data_access_layer/balance.rs index 2263c259e1..230985c3b6 100644 --- a/storage/src/data_access_layer/balance.rs +++ b/storage/src/data_access_layer/balance.rs @@ -1,15 +1,18 @@ //! Types for balance queries. use crate::data_access_layer::BalanceHoldRequest; use casper_types::{ - account::AccountHash, global_state::TrieMerkleProof, system::mint::BalanceHoldAddrTag, + account::AccountHash, + global_state::TrieMerkleProof, + system::{handle_payment::PAYMENT_PURSE_KEY, mint::BalanceHoldAddrTag, HANDLE_PAYMENT}, AccessRights, BlockTime, Digest, EntityAddr, InitiatorAddr, Key, ProtocolVersion, PublicKey, StoredValue, URef, URefAddr, U512, }; use std::collections::BTreeMap; +use tracing::error; use crate::{ global_state::state::StateReader, - tracking_copy::{TrackingCopyEntityExt, TrackingCopyError}, + tracking_copy::{TrackingCopyEntityExt, TrackingCopyError, TrackingCopyExt}, TrackingCopy, }; @@ -31,28 +34,18 @@ pub enum BalanceIdentifier { Account(AccountHash), Entity(EntityAddr), Internal(URefAddr), + Payment, } impl BalanceIdentifier { - /// Self as key. - pub fn as_key(&self) -> Key { - match self { - BalanceIdentifier::Purse(uref) => Key::URef(*uref), - BalanceIdentifier::Public(public_key) => Key::Account(public_key.to_account_hash()), - BalanceIdentifier::Account(account_hash) => Key::Account(*account_hash), - BalanceIdentifier::Entity(entity_addr) => Key::AddressableEntity(*entity_addr), - BalanceIdentifier::Internal(addr) => Key::Balance(*addr), - } - } - - // #[cfg(test)] pub fn as_purse_addr(&self) -> Option { match self { BalanceIdentifier::Purse(uref) => Some(uref.addr()), BalanceIdentifier::Internal(addr) => Some(*addr), BalanceIdentifier::Public(_) | BalanceIdentifier::Account(_) - | BalanceIdentifier::Entity(_) => None, + | BalanceIdentifier::Entity(_) + | BalanceIdentifier::Payment => None, } } @@ -87,6 +80,27 @@ impl BalanceIdentifier { } } BalanceIdentifier::Internal(addr) => URef::new(*addr, AccessRights::READ), + BalanceIdentifier::Payment => { + let system_contract_registry = tc.get_system_entity_registry()?; + + let handle_payment_hash = + system_contract_registry + .get(HANDLE_PAYMENT) + .ok_or_else(|| { + error!("Missing system handle payment contract hash"); + TrackingCopyError::MissingSystemContractHash(HANDLE_PAYMENT.to_string()) + })?; + + let named_keys = + tc.get_named_keys(EntityAddr::System(handle_payment_hash.value()))?; + let named_key = named_keys.get(PAYMENT_PURSE_KEY).ok_or( + TrackingCopyError::NamedKeyNotFound(PAYMENT_PURSE_KEY.to_string()), + )?; + let uref = named_key + .as_uref() + .ok_or(TrackingCopyError::UnexpectedKeyVariant(*named_key))?; + *uref + } }; Ok(purse_uref) } diff --git a/storage/src/global_state/state/mod.rs b/storage/src/global_state/state/mod.rs index df258f4263..d39050e7ac 100644 --- a/storage/src/global_state/state/mod.rs +++ b/storage/src/global_state/state/mod.rs @@ -34,8 +34,8 @@ use casper_types::{ }, AUCTION, HANDLE_PAYMENT, MINT, }, - Account, AddressableEntity, CLValue, DeployHash, Digest, EntityAddr, Key, KeyTag, Phase, - PublicKey, RuntimeArgs, StoredValue, TransactionHash, TransactionV1Hash, U512, + Account, AddressableEntity, CLValue, Digest, EntityAddr, Key, KeyTag, Phase, PublicKey, + RuntimeArgs, StoredValue, TransactionHash, TransactionV1Hash, U512, }; use crate::{ @@ -662,11 +662,10 @@ pub trait StateProvider { }; let protocol_version = request.protocol_version(); let balance_identifier = request.identifier(); - let purse_uref = match balance_identifier.purse_uref(&mut tc, protocol_version) { - Ok(value) => value, + let purse_key = match balance_identifier.purse_uref(&mut tc, protocol_version) { + Ok(value) => value.into(), Err(tce) => return BalanceResult::Failure(tce), }; - let purse_key = purse_uref.into(); let (purse_balance_key, purse_addr) = match tc.get_purse_balance_key(purse_key) { Ok(key @ Key::Balance(addr)) => (key, addr), Ok(key) => return BalanceResult::Failure(TrackingCopyError::UnexpectedKeyVariant(key)), @@ -1438,21 +1437,21 @@ pub trait StateProvider { let transfers = runtime.into_transfers(); - { - // TODO: this lexical block needs to be updated with the new versioned transaction types - let deploy_hash = DeployHash::new(request.transaction_hash().digest()); - let deploy_info = casper_types::DeployInfo::new( - deploy_hash, - &transfers, - source_account_hash, - entity.main_purse(), - request.cost(), - ); - tc.borrow_mut().write( - Key::DeployInfo(deploy_hash), - StoredValue::DeployInfo(deploy_info), - ); - } + // TODO: i really don't want us to write this data into global state. + // perhaps we can put it into normal storage instead? + // { + // let transaction_info = casper_types::TransactionInfo::new( + // request.transaction_hash(), + // &transfers, + // source_account_hash, + // entity.main_purse(), + // request.cost(), + // ); + // tc.borrow_mut().write( + // Key::TransactionInfo(request.transaction_hash()), + // StoredValue::TransactionInfo(transaction_info), + // ); + // } let effects = tc.borrow_mut().effects(); diff --git a/storage/src/lib.rs b/storage/src/lib.rs index e60553da2b..734b405b8e 100644 --- a/storage/src/lib.rs +++ b/storage/src/lib.rs @@ -18,5 +18,7 @@ pub mod tracking_copy; pub use address_generator::{AddressGenerator, AddressGeneratorBuilder}; pub use tracking_copy::TrackingCopy; +pub use block_store::{DbRawBytesSpec, RecordId, UnknownRecordId}; + #[cfg(test)] pub use self::tracking_copy::new_temporary_tracking_copy; diff --git a/storage/src/system/auction.rs b/storage/src/system/auction.rs index 780661af65..933f133029 100644 --- a/storage/src/system/auction.rs +++ b/storage/src/system/auction.rs @@ -95,6 +95,9 @@ pub trait Auction: let (target, validator_bid) = if let Some(BidKind::Validator(mut validator_bid)) = self.read_bid(&validator_bid_key)? { + if validator_bid.inactive() { + validator_bid.activate(); + } validator_bid.increase_stake(amount)?; validator_bid.with_delegation_rate(delegation_rate); (*validator_bid.bonding_purse(), validator_bid) diff --git a/storage/src/system/mint/mint_native.rs b/storage/src/system/mint/mint_native.rs index 1f61d5ee50..acd506e8d8 100644 --- a/storage/src/system/mint/mint_native.rs +++ b/storage/src/system/mint/mint_native.rs @@ -16,8 +16,8 @@ use casper_types::{ account::AccountHash, bytesrepr::{FromBytes, ToBytes}, system::{mint::Error, Caller}, - AccessRights, AddressableEntity, CLTyped, CLValue, DeployHash, Digest, Key, Phase, PublicKey, - StoredValue, SystemEntityRegistry, TransactionHash, Transfer, TransferAddr, URef, U512, + AccessRights, AddressableEntity, CLTyped, CLValue, Key, Phase, PublicKey, StoredValue, + SystemEntityRegistry, Transfer, TransferAddr, URef, U512, }; impl RuntimeProvider for RuntimeNative @@ -217,28 +217,27 @@ where if self.phase() != Phase::Session { return Ok(()); } + let transaction_hash = match self.id() { + Id::Transaction(transaction_hash) => *transaction_hash, + Id::Seed(_) => return Err(Error::RecordTransferFailure), + }; + let transfer_addr = TransferAddr::new(self.address_generator().create_address()); let key = Key::Transfer(transfer_addr); // <-- a new key variant needed to deal w/ versioned transaction hash //let transaction_hash = self.transaction_hash(); let transfer = { - // the below line is incorrect; new transaction hash is not currently supported here - // ...the transfer struct needs to be upgraded to TransactionHash - let deploy_hash = match self.id() { - Id::Transaction(transaction) => { - match transaction { - TransactionHash::Deploy(deploy_hash) => *deploy_hash, - TransactionHash::V1(hash) => { - // TODO: this is bogus...update when new transfer record is available - let hash = hash.inner(); - DeployHash::new(*hash) - } - } - } - Id::Seed(seed) => DeployHash::new(Digest::hash(seed)), - }; let from: AccountHash = self.get_caller(); let fee: U512 = U512::zero(); - Transfer::new(deploy_hash, from, maybe_to, source, target, amount, fee, id) + Transfer::new( + transaction_hash, + from, + maybe_to, + source, + target, + amount, + fee, + id, + ) }; self.push_transfer(transfer_addr); diff --git a/storage/src/tracking_copy/error.rs b/storage/src/tracking_copy/error.rs index faf8557c24..c17f3d5ad1 100644 --- a/storage/src/tracking_copy/error.rs +++ b/storage/src/tracking_copy/error.rs @@ -78,6 +78,9 @@ pub enum Error { /// Not authorized. #[error("Authorization error")] Authorization, + /// The value wasn't found. + #[error("Value not found")] + ValueNotFound(String), } impl Error { diff --git a/storage/src/tracking_copy/mod.rs b/storage/src/tracking_copy/mod.rs index 1518394ee7..4fb6b20e88 100644 --- a/storage/src/tracking_copy/mod.rs +++ b/storage/src/tracking_copy/mod.rs @@ -62,6 +62,32 @@ pub enum TrackingCopyQueryResult { }, } +impl TrackingCopyQueryResult { + /// Is this a successful query? + pub fn is_success(&self) -> bool { + matches!(self, TrackingCopyQueryResult::Success { .. }) + } + + /// As result. + pub fn as_result(self) -> Result { + match self { + TrackingCopyQueryResult::RootNotFound => { + Err(TrackingCopyError::Storage(Error::RootNotFound)) + } + TrackingCopyQueryResult::ValueNotFound(msg) => { + Err(TrackingCopyError::ValueNotFound(msg)) + } + TrackingCopyQueryResult::CircularReference(msg) => { + Err(TrackingCopyError::CircularReference(msg)) + } + TrackingCopyQueryResult::DepthLimit { depth } => { + Err(TrackingCopyError::QueryDepthLimit { depth }) + } + TrackingCopyQueryResult::Success { value, .. } => Ok(value), + } + } +} + /// Struct containing state relating to a given query. struct Query { /// The key from where the search starts. @@ -893,9 +919,12 @@ pub fn validate_balance_proof( Ok(()) } -use crate::global_state::state::{ - lmdb::{make_temporary_global_state, LmdbGlobalStateView}, - StateProvider, +use crate::global_state::{ + error::Error, + state::{ + lmdb::{make_temporary_global_state, LmdbGlobalStateView}, + StateProvider, + }, }; use tempfile::TempDir; diff --git a/types/benches/bytesrepr_bench.rs b/types/benches/bytesrepr_bench.rs index 8099763e27..0954c23cc0 100644 --- a/types/benches/bytesrepr_bench.rs +++ b/types/benches/bytesrepr_bench.rs @@ -16,8 +16,8 @@ use casper_types::{ AccessRights, AddressableEntityHash, ByteCodeHash, CLType, CLTyped, CLValue, DeployHash, DeployInfo, EntityVersionKey, EntityVersions, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Group, Groups, Key, Package, PackageHash, Parameter, ProtocolVersion, PublicKey, - SecretKey, Transfer, TransferAddr, URef, KEY_HASH_LENGTH, TRANSFER_ADDR_LENGTH, U128, U256, - U512, UREF_ADDR_LENGTH, + SecretKey, TransactionHash, Transfer, TransferAddr, URef, KEY_HASH_LENGTH, + TRANSFER_ADDR_LENGTH, U128, U256, U512, UREF_ADDR_LENGTH, }; static KB: usize = 1024; @@ -622,7 +622,7 @@ fn deserialize_bid(delegators_len: u32, b: &mut Bencher) { fn sample_transfer() -> Transfer { Transfer::new( - DeployHash::default(), + TransactionHash::Deploy(DeployHash::default()), AccountHash::default(), None, URef::default(), diff --git a/types/src/block/available_block_range.rs b/types/src/block/available_block_range.rs index 99c2fe321e..5022d366c0 100644 --- a/types/src/block/available_block_range.rs +++ b/types/src/block/available_block_range.rs @@ -7,11 +7,10 @@ use serde::{Deserialize, Serialize}; use crate::bytesrepr::{self, FromBytes, ToBytes}; -#[cfg(test)] -use rand::Rng; - -#[cfg(test)] +#[cfg(any(feature = "testing", test))] use crate::testing::TestRng; +#[cfg(any(feature = "testing", test))] +use rand::Rng; /// An unbroken, inclusive range of blocks. #[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize, Debug)] @@ -52,8 +51,9 @@ impl AvailableBlockRange { self.high } - #[cfg(test)] - pub(crate) fn random(rng: &mut TestRng) -> Self { + /// Random. + #[cfg(any(feature = "testing", test))] + pub fn random(rng: &mut TestRng) -> Self { let low = rng.gen::() as u64; let high = low + rng.gen::() as u64; Self { low, high } diff --git a/types/src/block/block_identifier.rs b/types/src/block/block_identifier.rs index 02508bdd0a..dd8e1329e7 100644 --- a/types/src/block/block_identifier.rs +++ b/types/src/block/block_identifier.rs @@ -1,12 +1,13 @@ use alloc::vec::Vec; use core::num::ParseIntError; -#[cfg(test)] + +#[cfg(any(feature = "testing", test))] use rand::Rng; #[cfg(feature = "json-schema")] use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -#[cfg(test)] +#[cfg(any(feature = "testing", test))] use crate::testing::TestRng; use crate::{ bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, @@ -28,8 +29,9 @@ pub enum BlockIdentifier { } impl BlockIdentifier { - #[cfg(test)] - pub(crate) fn random(rng: &mut TestRng) -> Self { + /// Random. + #[cfg(any(feature = "testing", test))] + pub fn random(rng: &mut TestRng) -> Self { match rng.gen_range(0..1) { 0 => Self::Hash(BlockHash::random(rng)), 1 => Self::Height(rng.gen()), diff --git a/types/src/block/block_sync_status.rs b/types/src/block/block_sync_status.rs index 6c8428242b..36f201294b 100644 --- a/types/src/block/block_sync_status.rs +++ b/types/src/block/block_sync_status.rs @@ -10,11 +10,10 @@ use crate::{ BlockHash, }; -#[cfg(test)] -use rand::Rng; - -#[cfg(test)] +#[cfg(any(feature = "testing", test))] use crate::testing::TestRng; +#[cfg(any(feature = "testing", test))] +use rand::Rng; #[cfg(feature = "json-schema")] static BLOCK_SYNCHRONIZER_STATUS: Lazy = Lazy::new(|| { @@ -71,8 +70,9 @@ impl BlockSyncStatus { } } - #[cfg(test)] - pub(crate) fn random(rng: &mut TestRng) -> Self { + /// Random. + #[cfg(any(feature = "testing", test))] + pub fn random(rng: &mut TestRng) -> Self { Self { block_hash: BlockHash::random(rng), block_height: rng.gen::().then_some(rng.gen()), @@ -143,8 +143,9 @@ impl BlockSynchronizerStatus { &BLOCK_SYNCHRONIZER_STATUS } - #[cfg(test)] - pub(crate) fn random(rng: &mut TestRng) -> Self { + /// Random. + #[cfg(any(feature = "testing", test))] + pub fn random(rng: &mut TestRng) -> Self { let historical = rng.gen::().then_some(BlockSyncStatus::random(rng)); let forward = rng.gen::().then_some(BlockSyncStatus::random(rng)); Self { diff --git a/types/src/block_time.rs b/types/src/block_time.rs index 33fb3b3d00..8b420581e6 100644 --- a/types/src/block_time.rs +++ b/types/src/block_time.rs @@ -2,7 +2,7 @@ use alloc::vec::Vec; use crate::{ bytesrepr::{Error, FromBytes, ToBytes, U64_SERIALIZED_LENGTH}, - CLType, CLTyped, + CLType, CLTyped, Timestamp, }; #[cfg(feature = "datasize")] @@ -47,6 +47,18 @@ impl From for u64 { } } +impl From for Timestamp { + fn from(value: BlockTime) -> Self { + Timestamp::from(value.0) + } +} + +impl From for BlockTime { + fn from(value: Timestamp) -> Self { + BlockTime::new(value.millis()) + } +} + impl ToBytes for BlockTime { fn to_bytes(&self) -> Result, Error> { self.0.to_bytes() diff --git a/types/src/chainspec/next_upgrade.rs b/types/src/chainspec/next_upgrade.rs index 897755f9db..8bb645265e 100644 --- a/types/src/chainspec/next_upgrade.rs +++ b/types/src/chainspec/next_upgrade.rs @@ -11,10 +11,10 @@ use crate::{ ActivationPoint, ProtocolConfig, ProtocolVersion, }; -#[cfg(test)] +#[cfg(any(feature = "testing", test))] use rand::Rng; -#[cfg(test)] +#[cfg(any(feature = "testing", test))] use crate::testing::TestRng; /// Information about the next protocol upgrade. @@ -40,8 +40,9 @@ impl NextUpgrade { self.activation_point } - #[cfg(test)] - pub(crate) fn random(rng: &mut TestRng) -> Self { + /// Random. + #[cfg(any(feature = "testing", test))] + pub fn random(rng: &mut TestRng) -> Self { Self { activation_point: ActivationPoint::random(rng), protocol_version: ProtocolVersion::from_parts(rng.gen(), rng.gen(), rng.gen()), diff --git a/types/src/digest.rs b/types/src/digest.rs index 0548f300f7..a8c9640502 100644 --- a/types/src/digest.rs +++ b/types/src/digest.rs @@ -250,7 +250,6 @@ impl Digest { /// Returns a new `Digest` directly initialized with the provided bytes; no hashing is done. /// /// This is equivalent to `Digest::from`, but is a const function. - #[cfg(any(feature = "testing", test))] pub const fn from_raw(raw_digest: [u8; Self::LENGTH]) -> Self { Digest(raw_digest) } diff --git a/types/src/gas.rs b/types/src/gas.rs index 0d0d1a401c..cf3fcb61cd 100644 --- a/types/src/gas.rs +++ b/types/src/gas.rs @@ -1,5 +1,7 @@ //! The `gas` module is used for working with Gas including converting to and from Motes. +use alloc::vec::Vec; + use core::{ fmt, iter::Sum, @@ -11,7 +13,10 @@ use datasize::DataSize; use num::Zero; use serde::{Deserialize, Serialize}; -use crate::{Motes, U512}; +use crate::{ + bytesrepr::{self, Error, FromBytes, ToBytes}, + Motes, U512, +}; /// The `Gas` struct represents a `U512` amount of gas. #[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] @@ -128,6 +133,28 @@ impl From for Gas { } } +impl ToBytes for Gas { + fn to_bytes(&self) -> Result, Error> { + let mut buffer = bytesrepr::allocate_buffer(self)?; + self.write_bytes(&mut buffer)?; + Ok(buffer) + } + + fn serialized_length(&self) -> usize { + ToBytes::serialized_length(&self.0) + } + fn write_bytes(&self, writer: &mut Vec) -> Result<(), Error> { + self.0.write_bytes(writer) + } +} + +impl FromBytes for Gas { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> { + let (gas, bytes) = U512::from_bytes(bytes)?; + Ok((Gas::new(gas), bytes)) + } +} + #[cfg(test)] mod tests { use crate::U512; diff --git a/types/src/key.rs b/types/src/key.rs index 52c2d4146c..c593592b72 100644 --- a/types/src/key.rs +++ b/types/src/key.rs @@ -12,7 +12,7 @@ use core::{ str::FromStr, }; -#[cfg(test)] +#[cfg(any(feature = "testing", test))] use crate::testing::TestRng; #[cfg(doc)] @@ -157,8 +157,9 @@ pub enum KeyTag { } impl KeyTag { - #[cfg(test)] - pub(crate) fn random(rng: &mut TestRng) -> Self { + /// Random. + #[cfg(any(feature = "testing", test))] + pub fn random(rng: &mut TestRng) -> Self { match rng.gen_range(0..23) { 0 => KeyTag::Account, 1 => KeyTag::Hash, diff --git a/types/src/lib.rs b/types/src/lib.rs index f3f5056b87..a2856b9582 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -28,7 +28,6 @@ pub mod account; pub mod addressable_entity; pub mod api_error; mod auction_state; -pub mod binary_port; mod block; mod block_time; mod byte_code; diff --git a/types/src/peers_map.rs b/types/src/peers_map.rs index c7a2833463..1ac5da20a1 100644 --- a/types/src/peers_map.rs +++ b/types/src/peers_map.rs @@ -9,15 +9,13 @@ use alloc::{ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -#[cfg(test)] +#[cfg(any(feature = "testing", test))] +use crate::testing::TestRng; +#[cfg(any(feature = "testing", test))] use core::iter; - -#[cfg(test)] +#[cfg(any(feature = "testing", test))] use rand::Rng; -#[cfg(test)] -use crate::testing::TestRng; - /// Node peer entry. #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] @@ -30,7 +28,7 @@ pub struct PeerEntry { } impl PeerEntry { - #[cfg(test)] + #[cfg(any(feature = "testing", test))] pub(crate) fn random(rng: &mut TestRng) -> Self { Self { node_id: rng.random_string(10..20), @@ -76,8 +74,9 @@ impl Peers { self.0 } - #[cfg(test)] - pub(crate) fn random(rng: &mut TestRng) -> Self { + /// Random. + #[cfg(any(feature = "testing", test))] + pub fn random(rng: &mut TestRng) -> Self { let count = rng.gen_range(0..10); let peers = iter::repeat(()) .map(|_| PeerEntry::random(rng)) diff --git a/types/src/stored_value/global_state_identifier.rs b/types/src/stored_value/global_state_identifier.rs index e99cf27a25..a909f05f52 100644 --- a/types/src/stored_value/global_state_identifier.rs +++ b/types/src/stored_value/global_state_identifier.rs @@ -1,17 +1,17 @@ use alloc::vec::Vec; -#[cfg(test)] -use rand::Rng; #[cfg(feature = "json-schema")] use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -#[cfg(test)] +#[cfg(any(feature = "testing", test))] use crate::testing::TestRng; use crate::{ bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, BlockHash, BlockIdentifier, Digest, }; +#[cfg(any(feature = "testing", test))] +use rand::Rng; const BLOCK_HASH_TAG: u8 = 0; const BLOCK_HEIGHT_TAG: u8 = 1; @@ -31,8 +31,9 @@ pub enum GlobalStateIdentifier { } impl GlobalStateIdentifier { - #[cfg(test)] - pub(crate) fn random(rng: &mut TestRng) -> Self { + /// Random. + #[cfg(any(feature = "testing", test))] + pub fn random(rng: &mut TestRng) -> Self { match rng.gen_range(0..3) { 0 => Self::BlockHash(BlockHash::random(rng)), 1 => Self::BlockHeight(rng.gen()), diff --git a/types/src/transaction.rs b/types/src/transaction.rs index 76da0a449b..3f716edada 100644 --- a/types/src/transaction.rs +++ b/types/src/transaction.rs @@ -49,7 +49,7 @@ use crate::Gas; use crate::{ account::AccountHash, bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, - Digest, SecretKey, TimeDiff, Timestamp, + Digest, Phase, SecretKey, TimeDiff, Timestamp, }; #[cfg(feature = "json-schema")] use crate::{account::ACCOUNT_HASH_LENGTH, URef}; @@ -339,14 +339,24 @@ impl Transaction { pub fn is_v1_wasm(&self) -> bool { match self { Transaction::Deploy(deploy) => !deploy.is_transfer(), - Transaction::V1(v1) => match v1.target() { - TransactionTarget::Native => false, - TransactionTarget::Stored { runtime, .. } - | TransactionTarget::Session { runtime, .. } => { - matches!(runtime, TransactionRuntime::VmCasperV1) - && (v1.is_standard() || v1.is_install_or_upgrade()) + Transaction::V1(v1) => v1.is_v1_wasm(), + } + } + + /// Should this transaction use standard payment processing? + pub fn is_standard_payment(&self) -> bool { + match self { + Transaction::Deploy(deploy) => deploy.payment().is_standard_payment(Phase::Payment), + Transaction::V1(v1) => { + if let PricingMode::Classic { + standard_payment, .. + } = v1.pricing_mode() + { + *standard_payment + } else { + true } - }, + } } } diff --git a/types/src/transaction/addressable_entity_identifier.rs b/types/src/transaction/addressable_entity_identifier.rs index bf588473f0..e675e21394 100644 --- a/types/src/transaction/addressable_entity_identifier.rs +++ b/types/src/transaction/addressable_entity_identifier.rs @@ -15,11 +15,12 @@ use super::{ExecutableDeployItem, TransactionTarget}; use crate::testing::TestRng; use crate::{ bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, - AddressableEntityHash, + AddressableEntityHash, EntityAddr, }; const HASH_TAG: u8 = 0; const NAME_TAG: u8 = 1; +const ADDR_TAG: u8 = 2; /// Identifier for the contract object within a [`TransactionTarget::Stored`] or an /// [`ExecutableDeployItem`]. @@ -39,6 +40,8 @@ pub enum AddressableEntityIdentifier { Hash(AddressableEntityHash), /// The name identifying the addressable entity. Name(String), + /// The entity address + Addr(EntityAddr), } impl AddressableEntityIdentifier { @@ -46,7 +49,11 @@ impl AddressableEntityIdentifier { #[cfg(any(feature = "testing", test))] pub fn random(rng: &mut TestRng) -> Self { if rng.gen() { - AddressableEntityIdentifier::Hash(AddressableEntityHash::new(rng.gen())) + if rng.gen() { + AddressableEntityIdentifier::Hash(AddressableEntityHash::new(rng.gen())) + } else { + AddressableEntityIdentifier::Addr(EntityAddr::new_with_tag(rng.gen(), rng.gen())) + } } else { AddressableEntityIdentifier::Name(rng.random_string(1..21)) } @@ -58,6 +65,9 @@ impl Display for AddressableEntityIdentifier { match self { AddressableEntityIdentifier::Hash(hash) => write!(formatter, "entity-hash({})", hash), AddressableEntityIdentifier::Name(name) => write!(formatter, "entity-name({})", name), + AddressableEntityIdentifier::Addr(entity_addr) => { + write!(formatter, "entity-addr({})", entity_addr) + } } } } @@ -73,6 +83,10 @@ impl ToBytes for AddressableEntityIdentifier { NAME_TAG.write_bytes(writer)?; name.write_bytes(writer) } + AddressableEntityIdentifier::Addr(entity_addr) => { + ADDR_TAG.write_bytes(writer)?; + entity_addr.write_bytes(writer) + } } } @@ -87,6 +101,7 @@ impl ToBytes for AddressableEntityIdentifier { + match self { AddressableEntityIdentifier::Hash(hash) => hash.serialized_length(), AddressableEntityIdentifier::Name(name) => name.serialized_length(), + AddressableEntityIdentifier::Addr(addr) => addr.serialized_length(), } } } @@ -103,6 +118,10 @@ impl FromBytes for AddressableEntityIdentifier { let (name, remainder) = String::from_bytes(remainder)?; Ok((AddressableEntityIdentifier::Name(name), remainder)) } + ADDR_TAG => { + let (addr, remainder) = EntityAddr::from_bytes(remainder)?; + Ok((AddressableEntityIdentifier::Addr(addr), remainder)) + } _ => Err(bytesrepr::Error::Formatting), } } diff --git a/types/src/transaction/deploy.rs b/types/src/transaction/deploy.rs index 946b1dab6f..8187f88982 100644 --- a/types/src/transaction/deploy.rs +++ b/types/src/transaction/deploy.rs @@ -1223,14 +1223,6 @@ impl PartialOrd for Deploy { } impl ToBytes for Deploy { - fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - self.header.write_bytes(writer)?; - self.hash.write_bytes(writer)?; - self.payment.write_bytes(writer)?; - self.session.write_bytes(writer)?; - self.approvals.write_bytes(writer) - } - fn to_bytes(&self) -> Result, bytesrepr::Error> { let mut buffer = bytesrepr::allocate_buffer(self)?; self.write_bytes(&mut buffer)?; @@ -1244,6 +1236,14 @@ impl ToBytes for Deploy { + self.session.serialized_length() + self.approvals.serialized_length() } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + self.header.write_bytes(writer)?; + self.hash.write_bytes(writer)?; + self.payment.write_bytes(writer)?; + self.session.write_bytes(writer)?; + self.approvals.write_bytes(writer) + } } impl FromBytes for Deploy { diff --git a/types/src/transaction/deploy/error.rs b/types/src/transaction/deploy/error.rs index be11b024ef..c84208cd56 100644 --- a/types/src/transaction/deploy/error.rs +++ b/types/src/transaction/deploy/error.rs @@ -118,6 +118,8 @@ pub enum InvalidDeploy { /// The chainspec limit for max_associated_keys. max_associated_keys: u32, }, + /// Unable to calculate gas limit. + UnableToCalculateGasLimit, } impl Display for InvalidDeploy { @@ -229,6 +231,9 @@ impl Display for InvalidDeploy { got, max_associated_keys ) } + InvalidDeploy::UnableToCalculateGasLimit => { + write!(formatter, "unable to calculate gas limit",) + } } } } @@ -260,7 +265,8 @@ impl StdError for InvalidDeploy { | InvalidDeploy::MissingTransferAmount | InvalidDeploy::FailedToParseTransferAmount | InvalidDeploy::InsufficientTransferAmount { .. } - | InvalidDeploy::ExcessiveApprovals { .. } => None, + | InvalidDeploy::ExcessiveApprovals { .. } + | InvalidDeploy::UnableToCalculateGasLimit => None, } } } diff --git a/types/src/transaction/pricing_mode.rs b/types/src/transaction/pricing_mode.rs index 1feed947fb..0dfa3d7e60 100644 --- a/types/src/transaction/pricing_mode.rs +++ b/types/src/transaction/pricing_mode.rs @@ -39,6 +39,8 @@ pub enum PricingMode { payment_amount: u64, /// User-specified gas_price tolerance (minimum 1). gas_price: u64, + /// Standard payment. + standard_payment: bool, }, /// The cost of the transaction is determined by the cost table, per the /// transaction kind. @@ -66,6 +68,7 @@ impl PricingMode { 0 => PricingMode::Classic { payment_amount: rng.gen(), gas_price: 1, + standard_payment: true, }, 1 => PricingMode::Fixed { gas_price_tolerance: rng.gen(), @@ -85,11 +88,12 @@ impl Display for PricingMode { PricingMode::Classic { payment_amount, gas_price, + standard_payment, } => { write!( formatter, - "payment amount {}, gas price multiplier {}", - payment_amount, gas_price + "payment amount {}, gas price multiplier {} standard_payment {}", + payment_amount, gas_price, standard_payment ) } PricingMode::Reserved { @@ -113,10 +117,12 @@ impl ToBytes for PricingMode { PricingMode::Classic { payment_amount, gas_price, + standard_payment, } => { CLASSIC_TAG.write_bytes(writer)?; payment_amount.write_bytes(writer)?; - gas_price.write_bytes(writer) + gas_price.write_bytes(writer)?; + standard_payment.write_bytes(writer) } PricingMode::Reserved { receipt, @@ -147,7 +153,12 @@ impl ToBytes for PricingMode { PricingMode::Classic { payment_amount, gas_price, - } => payment_amount.serialized_length() + gas_price.serialized_length(), + standard_payment, + } => { + payment_amount.serialized_length() + + gas_price.serialized_length() + + standard_payment.serialized_length() + } PricingMode::Reserved { receipt, paid_amount, @@ -167,10 +178,12 @@ impl FromBytes for PricingMode { CLASSIC_TAG => { let (payment_amount, remainder) = u64::from_bytes(remainder)?; let (gas_price, remainder) = u64::from_bytes(remainder)?; + let (standard_payment, remainder) = bool::from_bytes(remainder)?; Ok(( PricingMode::Classic { payment_amount, gas_price, + standard_payment, }, remainder, )) diff --git a/types/src/transaction/transaction_hash.rs b/types/src/transaction/transaction_hash.rs index 8ae7631122..d471ac7a00 100644 --- a/types/src/transaction/transaction_hash.rs +++ b/types/src/transaction/transaction_hash.rs @@ -22,6 +22,7 @@ use rand::Rng; const DEPLOY_TAG: u8 = 0; const V1_TAG: u8 = 1; +const TAG_LENGTH: u8 = 1; /// A versioned wrapper for a transaction hash or deploy hash. #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize, Debug)] @@ -37,6 +38,8 @@ pub enum TransactionHash { } impl TransactionHash { + /// The number of bytes in a `DeployHash` digest. + pub const LENGTH: usize = TAG_LENGTH as usize + Digest::LENGTH; /// Digest representation of hash. pub fn digest(&self) -> Digest { match self { @@ -54,6 +57,12 @@ impl TransactionHash { _ => panic!(), } } + + /// Returns a new `TransactionHash` directly initialized with the provided bytes; no hashing + /// is done. + pub const fn from_raw(raw_digest: [u8; TransactionV1Hash::LENGTH]) -> Self { + TransactionHash::V1(TransactionV1Hash::from_raw(raw_digest)) + } } impl From for TransactionHash { @@ -80,6 +89,12 @@ impl From<&TransactionV1Hash> for TransactionHash { } } +impl Default for TransactionHash { + fn default() -> Self { + TransactionHash::V1(TransactionV1Hash::default()) + } +} + impl Display for TransactionHash { fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { match self { @@ -99,19 +114,6 @@ impl AsRef<[u8]> for TransactionHash { } impl ToBytes for TransactionHash { - fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - match self { - TransactionHash::Deploy(hash) => { - DEPLOY_TAG.write_bytes(writer)?; - hash.write_bytes(writer) - } - TransactionHash::V1(hash) => { - V1_TAG.write_bytes(writer)?; - hash.write_bytes(writer) - } - } - } - fn to_bytes(&self) -> Result, bytesrepr::Error> { let mut buffer = bytesrepr::allocate_buffer(self)?; self.write_bytes(&mut buffer)?; @@ -125,6 +127,19 @@ impl ToBytes for TransactionHash { TransactionHash::V1(hash) => hash.serialized_length(), } } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + match self { + TransactionHash::Deploy(hash) => { + DEPLOY_TAG.write_bytes(writer)?; + hash.write_bytes(writer) + } + TransactionHash::V1(hash) => { + V1_TAG.write_bytes(writer)?; + hash.write_bytes(writer) + } + } + } } impl FromBytes for TransactionHash { diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index c468250c65..845d9cedba 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -38,7 +38,7 @@ use crate::{Gas, Motes, SystemConfig, TransactionConfig, U512}; use crate::{ bytesrepr::{self, FromBytes, ToBytes}, - crypto, Digest, DisplayIter, RuntimeArgs, SecretKey, TimeDiff, Timestamp, + crypto, Digest, DisplayIter, RuntimeArgs, SecretKey, TimeDiff, Timestamp, TransactionRuntime, TransactionSessionKind, }; pub use errors_v1::{ @@ -219,6 +219,18 @@ impl TransactionV1 { self.body().is_standard() } + /// Does this transaction have wasm targeting the v1 vm. + pub fn is_v1_wasm(&self) -> bool { + match self.target() { + TransactionTarget::Native => false, + TransactionTarget::Stored { runtime, .. } + | TransactionTarget::Session { runtime, .. } => { + matches!(runtime, TransactionRuntime::VmCasperV1) + && (self.is_standard() || self.is_install_or_upgrade()) + } + } + } + /// Returns the approvals for this transaction. pub fn approvals(&self) -> &BTreeSet { &self.approvals @@ -552,6 +564,7 @@ impl GasLimited for TransactionV1 { PricingMode::Classic { payment_amount, gas_price: user_specified_price, + .. } => { let actual_price = match gas_price { Some(system_specified_price) => { diff --git a/types/src/transaction/transaction_v1/errors_v1.rs b/types/src/transaction/transaction_v1/errors_v1.rs index 5b7f12a6c5..0464dfcc35 100644 --- a/types/src/transaction/transaction_v1/errors_v1.rs +++ b/types/src/transaction/transaction_v1/errors_v1.rs @@ -135,6 +135,8 @@ pub enum InvalidTransaction { /// The attempted gas price. gas_price: u64, }, + /// Unable to calculate gas limit. + UnableToCalculateGasLimit, } impl Display for InvalidTransaction { @@ -248,6 +250,9 @@ impl Display for InvalidTransaction { amount, gas_price ) } + InvalidTransaction::UnableToCalculateGasLimit => { + write!(formatter, "unable to calculate gas limit",) + } } } } @@ -279,7 +284,8 @@ impl StdError for InvalidTransaction { | InvalidTransaction::EntryPointCannotBeCustom { .. } | InvalidTransaction::EntryPointMustBeCustom { .. } | InvalidTransaction::EmptyModuleBytes - | InvalidTransaction::GasPriceConversion { .. } => None, + | InvalidTransaction::GasPriceConversion { .. } + | InvalidTransaction::UnableToCalculateGasLimit => None, } } } diff --git a/types/src/transaction/transaction_v1/transaction_v1_hash.rs b/types/src/transaction/transaction_v1/transaction_v1_hash.rs index c7ba947d66..86908478d1 100644 --- a/types/src/transaction/transaction_v1/transaction_v1_hash.rs +++ b/types/src/transaction/transaction_v1/transaction_v1_hash.rs @@ -47,7 +47,6 @@ impl TransactionV1Hash { /// Returns a new `TransactionV1Hash` directly initialized with the provided bytes; no hashing /// is done. - #[cfg(any(feature = "testing", test))] pub const fn from_raw(raw_digest: [u8; Self::LENGTH]) -> Self { TransactionV1Hash(Digest::from_raw(raw_digest)) } diff --git a/types/src/transfer.rs b/types/src/transfer.rs index 60f859aa7d..2a9042f75a 100644 --- a/types/src/transfer.rs +++ b/types/src/transfer.rs @@ -19,7 +19,7 @@ use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Seria use crate::{ account::AccountHash, bytesrepr::{self, FromBytes, ToBytes}, - checksummed_hex, serde_helpers, CLType, CLTyped, DeployHash, URef, U512, + checksummed_hex, CLType, CLTyped, TransactionHash, URef, U512, }; /// The length of a transfer address. @@ -33,15 +33,7 @@ pub(super) const TRANSFER_ADDR_FORMATTED_STRING_PREFIX: &str = "transfer-"; #[serde(deny_unknown_fields)] pub struct Transfer { /// Deploy that created the transfer - #[serde(with = "serde_helpers::deploy_hash_as_array")] - #[cfg_attr( - feature = "json-schema", - schemars( - with = "DeployHash", - description = "Hex-encoded Deploy hash of Deploy that created the transfer." - ) - )] - pub deploy_hash: DeployHash, + pub transaction_hash: TransactionHash, /// Account from which transfer was executed pub from: AccountHash, /// Account to which funds are transferred @@ -62,7 +54,7 @@ impl Transfer { /// Creates a [`Transfer`]. #[allow(clippy::too_many_arguments)] pub fn new( - deploy_hash: DeployHash, + transaction_hash: TransactionHash, from: AccountHash, to: Option, source: URef, @@ -72,7 +64,7 @@ impl Transfer { id: Option, ) -> Self { Transfer { - deploy_hash, + transaction_hash, from, to, source, @@ -86,7 +78,7 @@ impl Transfer { impl FromBytes for Transfer { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (deploy_hash, rem) = FromBytes::from_bytes(bytes)?; + let (transaction_hash, rem) = FromBytes::from_bytes(bytes)?; let (from, rem) = AccountHash::from_bytes(rem)?; let (to, rem) = >::from_bytes(rem)?; let (source, rem) = URef::from_bytes(rem)?; @@ -96,7 +88,7 @@ impl FromBytes for Transfer { let (id, rem) = >::from_bytes(rem)?; Ok(( Transfer { - deploy_hash, + transaction_hash, from, to, source, @@ -113,7 +105,7 @@ impl FromBytes for Transfer { impl ToBytes for Transfer { fn to_bytes(&self) -> Result, bytesrepr::Error> { let mut result = bytesrepr::allocate_buffer(self)?; - self.deploy_hash.write_bytes(&mut result)?; + self.transaction_hash.write_bytes(&mut result)?; self.from.write_bytes(&mut result)?; self.to.write_bytes(&mut result)?; self.source.write_bytes(&mut result)?; @@ -125,7 +117,7 @@ impl ToBytes for Transfer { } fn serialized_length(&self) -> usize { - self.deploy_hash.serialized_length() + self.transaction_hash.serialized_length() + self.from.serialized_length() + self.to.serialized_length() + self.source.serialized_length() @@ -136,7 +128,7 @@ impl ToBytes for Transfer { } fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - self.deploy_hash.write_bytes(writer)?; + self.transaction_hash.write_bytes(writer)?; self.from.write_bytes(writer)?; self.to.write_bytes(writer)?; self.source.write_bytes(writer)?; @@ -326,7 +318,7 @@ pub mod gens { use crate::{ deploy_info::gens::{account_hash_arb, deploy_hash_arb}, gens::{u512_arb, uref_arb}, - Transfer, + TransactionHash, Transfer, }; /// Creates an arbitrary [`Transfer`] @@ -343,7 +335,7 @@ pub mod gens { ) .prop_map(|(deploy_hash, from, to, source, target, amount, gas, id)| { Transfer { - deploy_hash, + transaction_hash: TransactionHash::Deploy(deploy_hash), from, to, source, diff --git a/utils/validation/src/generators.rs b/utils/validation/src/generators.rs index def5ef9304..472e471762 100644 --- a/utils/validation/src/generators.rs +++ b/utils/validation/src/generators.rs @@ -22,7 +22,7 @@ use casper_types::{ AccessRights, AddressableEntityHash, BlockTime, ByteCode, ByteCodeHash, ByteCodeKind, CLType, CLTyped, CLValue, DeployHash, DeployInfo, EntityVersionKey, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, EraId, Group, Key, PackageHash, Parameter, ProtocolVersion, - PublicKey, SecretKey, StoredValue, Transfer, TransferAddr, URef, U512, + PublicKey, SecretKey, StoredValue, TransactionHash, Transfer, TransferAddr, URef, U512, }; use casper_validation::{ abi::{ABIFixture, ABITestCase}, @@ -70,7 +70,7 @@ pub fn make_abi_test_fixtures() -> Result { }; let transfer = Transfer::new( - DeployHash::from_raw([44; 32]), + TransactionHash::from_raw([44; 32]), AccountHash::new([100; 32]), Some(AccountHash::new([101; 32])), URef::new([10; 32], AccessRights::WRITE), From 4232609ca566884b952f706077785456a1b994e6 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Mon, 18 Mar 2024 04:10:31 -0700 Subject: [PATCH 21/70] stripped down wasm exec, binary port types extracted into own crate, etc --- binary_port/Cargo.toml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 binary_port/Cargo.toml diff --git a/binary_port/Cargo.toml b/binary_port/Cargo.toml new file mode 100644 index 0000000000..8697a9838e --- /dev/null +++ b/binary_port/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "casper-binary-port" +version = "1.0.0" +edition = "2018" +description = "Types for the casper node binary port" +documentation = "https://docs.rs/casper-binary-port" +readme = "README.md" +homepage = "https://casperlabs.io" +repository = "https://github.com/CasperLabs/casper-node/tree/master/binary_port" +license = "Apache-2.0" +exclude = ["proptest-regressions"] + +[dependencies] +casper-execution-engine = { version = "6.0.0", path = "../execution_engine" } +casper-storage = { version = "1.4.3", path = "../storage" } +casper-types = { version = "3.0.0", path = "../types", features = ["datasize", "json-schema", "std"] } +serde = { version = "1.0.183", features = ["derive"] } +thiserror = "1.0.45" +serde-map-to-array = "1.1.0" +once_cell = { version = "1.5.2", optional = true } +schemars = { version = "0.8.16", features = ["preserve_order", "impl_json_schema"] } +bincode = "1.3.3" + +[dev-dependencies] +casper-types = { path = "../types", features = ["datasize", "json-schema", "std", "testing"] } +rand = "0.8.3" +serde_json = "1" +serde_test = "1" + +[package.metadata.docs.rs] +all-features = true +rustc-args = ["--cfg", "docsrs"] From 255a5486a500358b050d0e79cf9756255636f22c Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Mon, 18 Mar 2024 15:28:29 -0700 Subject: [PATCH 22/70] tweaks --- binary_port/src/payload_type.rs | 10 ++--- node/src/components/binary_port/tests.rs | 3 +- node/src/components/block_synchronizer.rs | 2 +- node/src/components/contract_runtime/utils.rs | 38 ++++++++++--------- node/src/effect.rs | 2 +- storage/src/global_state/state/mod.rs | 8 ++-- storage/src/system/mint/mint_native.rs | 4 +- 7 files changed, 37 insertions(+), 30 deletions(-) diff --git a/binary_port/src/payload_type.rs b/binary_port/src/payload_type.rs index 73f0fc18fd..5e535e6ffa 100644 --- a/binary_port/src/payload_type.rs +++ b/binary_port/src/payload_type.rs @@ -277,11 +277,11 @@ const NEXT_UPGRADE_TAG: u8 = 25; const CONSENSUS_STATUS_TAG: u8 = 26; const CHAINSPEC_RAW_BYTES_TAG: u8 = 27; const HIGHEST_BLOCK_SEQUENCE_CHECK_RESULT_TAG: u8 = 28; -const SPECULATIVE_EXECUTION_RESULT_TAG: u8 = 29; -const GLOBAL_STATE_QUERY_RESULT_TAG: u8 = 30; -const STORED_VALUES_TAG: u8 = 31; -const GET_TRIE_FULL_RESULT_TAG: u8 = 32; -const NODE_STATUS_TAG: u8 = 33; +const GLOBAL_STATE_QUERY_RESULT_TAG: u8 = 29; +const STORED_VALUES_TAG: u8 = 30; +const GET_TRIE_FULL_RESULT_TAG: u8 = 31; +const NODE_STATUS_TAG: u8 = 32; +const SPECULATIVE_EXECUTION_RESULT_TAG: u8 = 33; const WASM_V1_RESULT_TAG: u8 = 34; impl ToBytes for PayloadType { diff --git a/node/src/components/binary_port/tests.rs b/node/src/components/binary_port/tests.rs index 933e26925e..b2ca2ebf54 100644 --- a/node/src/components/binary_port/tests.rs +++ b/node/src/components/binary_port/tests.rs @@ -316,7 +316,8 @@ impl From for Event { } impl From for Event { - fn from(_request: StorageRequest) -> Self { + fn from(request: StorageRequest) -> Self { + println!("{}", request); unreachable!() } } diff --git a/node/src/components/block_synchronizer.rs b/node/src/components/block_synchronizer.rs index 8d1c6b3a68..cbf7a1d76b 100644 --- a/node/src/components/block_synchronizer.rs +++ b/node/src/components/block_synchronizer.rs @@ -1141,7 +1141,7 @@ impl BlockSynchronizer { } }; return effect_builder - .put_execution_results_to_storage( + .put_execution_artifacts_to_storage( block_hash, block_height, era_id, diff --git a/node/src/components/contract_runtime/utils.rs b/node/src/components/contract_runtime/utils.rs index 5d1856c4dd..f8591a0bde 100644 --- a/node/src/components/contract_runtime/utils.rs +++ b/node/src/components/contract_runtime/utils.rs @@ -13,12 +13,14 @@ use crate::{ fatal, types::{ExecutableBlock, MetaBlock, MetaBlockState}, }; + use casper_execution_engine::engine_state::ExecutionEngineV1; use casper_storage::{ data_access_layer::DataAccessLayer, global_state::state::lmdb::LmdbGlobalState, }; use casper_types::{Chainspec, EraId, Key}; use once_cell::sync::Lazy; +use std::fmt::Debug; use std::{ cmp, collections::{BTreeMap, HashMap}, @@ -43,13 +45,18 @@ static INTENSIVE_TASKS_SEMAPHORE: Lazy = pub(super) async fn run_intensive_task(task: T) -> V where T: 'static + Send + FnOnce() -> V, - V: 'static + Send, + V: 'static + Send + Debug, { // This will never panic since the semaphore is never closed. let _permit = INTENSIVE_TASKS_SEMAPHORE.acquire().await.unwrap(); - tokio::task::spawn_blocking(task) - .await - .expect("task panicked") + let result = tokio::task::spawn_blocking(task).await; + match result { + Ok(ret) => ret, + Err(err) => { + error!("{:?}", err); + panic!("intensive contract runtime task errored: {:?}", err); + } + } } #[allow(clippy::too_many_arguments)] @@ -102,8 +109,8 @@ pub(super) async fn exec_or_requeue( let BlockAndExecutionArtifacts { block, approvals_hashes, - execution_artifacts: execution_results, - step_outcome: maybe_step_effects_and_upcoming_era_validators, + execution_artifacts, + step_outcome: maybe_step_outcome, } = match run_intensive_task(move || { debug!("ContractRuntime: execute_finalized_block"); execute_finalized_block( @@ -118,7 +125,7 @@ pub(super) async fn exec_or_requeue( }) .await { - Ok(block_and_execution_results) => block_and_execution_results, + Ok(ret) => ret, Err(error) => { error!(%error, "failed to execute block"); return fatal!(effect_builder, "{}", error).await; @@ -152,7 +159,7 @@ pub(super) async fn exec_or_requeue( if let Some(StepOutcome { step_effects, mut upcoming_era_validators, - }) = maybe_step_effects_and_upcoming_era_validators + }) = maybe_step_outcome { effect_builder .announce_commit_step_success(current_era_id, step_effects) @@ -185,29 +192,26 @@ pub(super) async fn exec_or_requeue( "executed block" ); - let execution_results_map: HashMap<_, _> = execution_results + let artifacts_map: HashMap<_, _> = execution_artifacts .iter() .cloned() .map(|artifact| (artifact.transaction_hash, artifact.execution_result)) .collect(); + if meta_block_state.register_as_stored().was_updated() { effect_builder - .put_executed_block_to_storage( - Arc::clone(&block), - approvals_hashes, - execution_results_map, - ) + .put_executed_block_to_storage(Arc::clone(&block), approvals_hashes, artifacts_map) .await; } else { effect_builder .put_approvals_hashes_to_storage(approvals_hashes) .await; effect_builder - .put_execution_results_to_storage( + .put_execution_artifacts_to_storage( *block.hash(), block.height(), block.era_id(), - execution_results_map, + artifacts_map, ) .await; } @@ -223,7 +227,7 @@ pub(super) async fn exec_or_requeue( ); } - let meta_block = MetaBlock::new_forward(block, execution_results, meta_block_state); + let meta_block = MetaBlock::new_forward(block, execution_artifacts, meta_block_state); effect_builder.announce_meta_block(meta_block).await; // If the child is already finalized, start execution. diff --git a/node/src/effect.rs b/node/src/effect.rs index 076fea94d4..c6ae7e57e5 100644 --- a/node/src/effect.rs +++ b/node/src/effect.rs @@ -1627,7 +1627,7 @@ impl EffectBuilder { /// Stores the given execution results for the transactions in the given block in the linear /// block store. - pub(crate) async fn put_execution_results_to_storage( + pub(crate) async fn put_execution_artifacts_to_storage( self, block_hash: BlockHash, block_height: u64, diff --git a/storage/src/global_state/state/mod.rs b/storage/src/global_state/state/mod.rs index d39050e7ac..612c5a1ad0 100644 --- a/storage/src/global_state/state/mod.rs +++ b/storage/src/global_state/state/mod.rs @@ -279,7 +279,7 @@ pub trait CommitProvider: StateProvider { } }; - crate::system::runtime_native::Id::Seed(bytes) + Id::Seed(bytes) }; let config = request.config(); @@ -376,7 +376,7 @@ pub trait CommitProvider: StateProvider { } }; - crate::system::runtime_native::Id::Seed(bytes) + Id::Seed(bytes) }; // this runtime uses the system's context @@ -540,7 +540,7 @@ pub trait CommitProvider: StateProvider { } }; - crate::system::runtime_native::Id::Seed(bytes) + Id::Seed(bytes) }; let config = request.config(); @@ -1376,7 +1376,7 @@ pub trait StateProvider { } }; - let id = crate::system::runtime_native::Id::Transaction(request.transaction_hash()); + let id = Id::Transaction(request.transaction_hash()); // IMPORTANT: this runtime _must_ use the payer's context. let mut runtime = RuntimeNative::new( protocol_version, diff --git a/storage/src/system/mint/mint_native.rs b/storage/src/system/mint/mint_native.rs index acd506e8d8..1b1aba9d04 100644 --- a/storage/src/system/mint/mint_native.rs +++ b/storage/src/system/mint/mint_native.rs @@ -219,7 +219,9 @@ where } let transaction_hash = match self.id() { Id::Transaction(transaction_hash) => *transaction_hash, - Id::Seed(_) => return Err(Error::RecordTransferFailure), + // we don't write transfer records for systemic transfers (step, fees, rewards, etc) + // so return Ok and move on. + Id::Seed(_) => return Ok(()), }; let transfer_addr = TransferAddr::new(self.address_generator().create_address()); From 87b921f8eb9d7b6e3167654bdec70372e217f74a Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Wed, 20 Mar 2024 01:53:31 +0000 Subject: [PATCH 23/70] wip --- binary_port/src/error_code.rs | 2 +- execution_engine/src/engine_state/error.rs | 8 +- .../src/engine_state/executable_item.rs | 910 ------------------ .../src/engine_state/execute_request.rs | 332 ------- .../src/engine_state/execution_kind.rs | 79 +- .../src/engine_state/execution_result.rs | 22 - execution_engine/src/engine_state/mod.rs | 78 +- execution_engine/src/engine_state/wasm_v1.rs | 512 ++++++++-- execution_engine/src/execution/error.rs | 3 + .../src/execute_request_builder.rs | 204 ++-- .../test_support/src/wasm_test_builder.rs | 82 +- node/src/components/contract_runtime.rs | 4 +- node/src/components/contract_runtime/error.rs | 30 +- .../components/contract_runtime/operations.rs | 59 +- node/src/components/contract_runtime/types.rs | 22 +- node/src/effect.rs | 2 +- node/src/effect/requests.rs | 2 +- 17 files changed, 686 insertions(+), 1665 deletions(-) delete mode 100644 execution_engine/src/engine_state/executable_item.rs delete mode 100644 execution_engine/src/engine_state/execute_request.rs diff --git a/binary_port/src/error_code.rs b/binary_port/src/error_code.rs index c17bdef487..b92ea4d0ec 100644 --- a/binary_port/src/error_code.rs +++ b/binary_port/src/error_code.rs @@ -88,7 +88,7 @@ impl From for ErrorCode { match err { EngineError::RootNotFound(_) => ErrorCode::RootNotFound, EngineError::Deploy => ErrorCode::InvalidTransaction, - EngineError::InvalidItemVariant(_) => ErrorCode::InvalidItemVariant, + EngineError::InvalidExecutableItem(_) => ErrorCode::InvalidItemVariant, EngineError::WasmPreprocessing(_) => ErrorCode::WasmPreprocessing, EngineError::InvalidProtocolVersion(_) => ErrorCode::UnsupportedProtocolVersion, EngineError::Deprecated(_) => ErrorCode::FunctionDisabled, diff --git a/execution_engine/src/engine_state/error.rs b/execution_engine/src/engine_state/error.rs index 8f5ad03376..16adedd82e 100644 --- a/execution_engine/src/engine_state/error.rs +++ b/execution_engine/src/engine_state/error.rs @@ -5,6 +5,7 @@ use thiserror::Error; use casper_storage::{system::transfer::TransferError, tracking_copy::TrackingCopyError}; use casper_types::{bytesrepr, system::mint, ApiError, Digest, Key, ProtocolVersion}; +use super::InvalidRequest; use crate::{ execution::ExecError, runtime::{stack, PreprocessingError}, @@ -50,9 +51,6 @@ pub enum Error { /// Invalid deploy item variant. #[error("Unsupported deploy item variant: {0}")] InvalidDeployItemVariant(String), - /// Empty module bytes cannot be used for custom payment. - #[error("empty module bytes cannot be used for custom payment")] - EmptyCustomPaymentModuleBytes, /// Missing system contract hash. #[error("Missing system contract hash: {0}")] MissingSystemContractHash(String), @@ -69,8 +67,8 @@ pub enum Error { #[error("Deprecated: {0}")] Deprecated(String), /// Could not derive a valid item to execute. - #[error("Invalid executable item")] - InvalidExecutableItem, + #[error("Invalid executable item: {0}")] + InvalidExecutableItem(#[from] InvalidRequest), } impl Error { diff --git a/execution_engine/src/engine_state/executable_item.rs b/execution_engine/src/engine_state/executable_item.rs deleted file mode 100644 index 9552a65c35..0000000000 --- a/execution_engine/src/engine_state/executable_item.rs +++ /dev/null @@ -1,910 +0,0 @@ -//! Code supporting an executable item. -use core::fmt::{self, Debug, Display, Formatter}; -use std::convert::TryFrom; - -#[cfg(feature = "datasize")] -use datasize::DataSize; - -use hex_fmt::HexFmt; - -use serde::{Deserialize, Serialize}; - -use casper_types::{ - account::AccountHash, - addressable_entity::DEFAULT_ENTRY_POINT_NAME, - bytesrepr::{self, Bytes, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, - runtime_args, - system::mint::ARG_AMOUNT, - AddressableEntityHash, AddressableEntityIdentifier, EntityAddr, EntityVersion, - ExecutableDeployItem, Gas, Motes, PackageHash, PackageIdentifier, Phase, PublicKey, - RuntimeArgs, Transaction, TransactionInvocationTarget, TransactionRuntime, TransactionTarget, - URef, U512, -}; - -#[cfg(test)] -use casper_types::testing::TestRng; -#[cfg(test)] -use rand::distributions::Alphanumeric; -#[cfg(test)] -use rand::distributions::Distribution; -#[cfg(test)] -use rand::distributions::Standard; -#[cfg(test)] -use rand::Rng; - -const TAG_LENGTH: usize = U8_SERIALIZED_LENGTH; -const MODULE_BYTES_TAG: u8 = 0; -const BY_HASH_TAG: u8 = 1; -const BY_NAME_TAG: u8 = 2; -const BY_PACKAGE_HASH: u8 = 3; -const BY_PACKAGE_NAME: u8 = 4; -const BY_ADDR_TAG: u8 = 5; - -/// Identifier for an [`ExecutableItem`]. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub enum ExecutableItemIdentifier { - /// The item is of the type [`ExecutableItem::Wasm`] - Module, - /// The item is a variation of a stored contract. - AddressableEntity(AddressableEntityIdentifier), - /// The item is a variation of a stored contract package. - Package(PackageIdentifier), - /// The item is a native transfer. - Transfer, -} - -/// The executable component of a [``]. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] -#[cfg_attr(feature = "datasize", derive(DataSize))] -#[cfg_attr(feature = "json-schema", derive(JsonSchema))] -#[serde(deny_unknown_fields)] -pub enum ExecutableItem { - /// Executable specified as raw bytes that represent Wasm code and an instance of - /// [`RuntimeArgs`]. - Wasm { - /// Raw Wasm module bytes with 'call' exported as an entrypoint. - #[cfg_attr( - feature = "json-schema", - schemars(description = "Hex-encoded raw Wasm bytes.") - )] - module_bytes: Bytes, - /// Runtime arguments. - args: RuntimeArgs, - }, - /// Entity referenced by its [`AddressableEntityHash`], entry point and an instance of - /// [`RuntimeArgs`]. - ByHash { - /// entity hash. - hash: AddressableEntityHash, - /// Name of an entry point. - entry_point: String, - /// Runtime arguments. - args: RuntimeArgs, - }, - /// Entity referenced by its [`EntityAddr`], entry point and an instance of - /// [`RuntimeArgs`]. - ByAddress { - /// Entity address. - address: EntityAddr, - /// Name of an entry point. - entry_point: String, - /// Runtime arguments. - args: RuntimeArgs, - }, - /// Entity referenced by a named key existing in the signer's account context, entry - /// point and an instance of [`RuntimeArgs`]. - ByName { - /// Named key. - name: String, - /// Name of an entry point. - entry_point: String, - /// Runtime arguments. - args: RuntimeArgs, - }, - /// Entity referenced by its [`PackageHash`], entry point and an - /// instance of [`RuntimeArgs`]. - ByPackageHash { - /// Contract package hash - hash: PackageHash, - /// An optional version of the contract to call. It will default to the highest enabled - /// version if no value is specified. - version: Option, - /// Entry point name. - entry_point: String, - /// Runtime arguments. - args: RuntimeArgs, - }, - /// Entity referenced by a named key existing in the signer's account - /// context, entry point and an instance of [`RuntimeArgs`]. - ByPackageName { - /// Named key. - name: String, - /// An optional version of the contract to call. It will default to the highest enabled - /// version if no value is specified. - version: Option, - /// Entry point name. - entry_point: String, - /// Runtime arguments. - args: RuntimeArgs, - }, -} - -impl ExecutableItem { - /// Returns a new `ExecutableItem::Wasm`. - pub fn new_wasm(module_bytes: Bytes, args: RuntimeArgs) -> Self { - ExecutableItem::Wasm { module_bytes, args } - } - - /// Returns a new `ExecutableItem::Wasm` suitable for use as standard payment code - /// of a ``. - pub fn new_standard_payment>(amount: A) -> Self { - ExecutableItem::Wasm { - module_bytes: Bytes::new(), - args: runtime_args! { - ARG_AMOUNT => amount.into(), - }, - } - } - - /// Returns a new `ExecutableItem::ByHash`. - pub fn new_by_hash( - hash: AddressableEntityHash, - entry_point: String, - args: RuntimeArgs, - ) -> Self { - ExecutableItem::ByHash { - hash, - entry_point, - args, - } - } - - /// Returns a new `ExecutableItem::ByAddress`. - pub fn new_by_addr(addr: EntityAddr, entry_point: String, args: RuntimeArgs) -> Self { - ExecutableItem::ByAddress { - address: addr, - entry_point, - args, - } - } - - /// Returns a new `ExecutableItem::ByName`. - pub fn new_by_name(name: String, entry_point: String, args: RuntimeArgs) -> Self { - ExecutableItem::ByName { - name, - entry_point, - args, - } - } - - /// Returns a new `ExecutableItem::ByPackageHash`. - pub fn new_by_package_hash( - hash: PackageHash, - version: Option, - entry_point: String, - args: RuntimeArgs, - ) -> Self { - ExecutableItem::ByPackageHash { - hash, - version, - entry_point, - args, - } - } - - /// Returns a new `ExecutableItem::ByPackageName`. - pub fn new_by_package( - name: String, - version: Option, - entry_point: String, - args: RuntimeArgs, - ) -> Self { - ExecutableItem::ByPackageName { - name, - version, - entry_point, - args, - } - } - - /// Returns the entry point name. - pub fn entry_point_name(&self) -> &str { - match self { - ExecutableItem::Wasm { .. } => DEFAULT_ENTRY_POINT_NAME, - ExecutableItem::ByPackageName { entry_point, .. } - | ExecutableItem::ByPackageHash { entry_point, .. } - | ExecutableItem::ByAddress { entry_point, .. } - | ExecutableItem::ByName { entry_point, .. } - | ExecutableItem::ByHash { entry_point, .. } => entry_point, - } - } - - /// Returns the identifier of the `ExecutableItem`. - pub fn identifier(&self) -> ExecutableItemIdentifier { - match self { - ExecutableItem::Wasm { .. } => ExecutableItemIdentifier::Module, - ExecutableItem::ByHash { hash, .. } => ExecutableItemIdentifier::AddressableEntity( - AddressableEntityIdentifier::Hash(*hash), - ), - ExecutableItem::ByAddress { address, .. } => { - ExecutableItemIdentifier::AddressableEntity(AddressableEntityIdentifier::Addr( - *address, - )) - } - ExecutableItem::ByName { name, .. } => ExecutableItemIdentifier::AddressableEntity( - AddressableEntityIdentifier::Name(name.clone()), - ), - ExecutableItem::ByPackageHash { hash, version, .. } => { - ExecutableItemIdentifier::Package(PackageIdentifier::Hash { - package_hash: *hash, - version: *version, - }) - } - ExecutableItem::ByPackageName { name, version, .. } => { - ExecutableItemIdentifier::Package(PackageIdentifier::Name { - name: name.clone(), - version: *version, - }) - } - } - } - - /// Returns the identifier of the contract in the item, if present. - pub fn contract_identifier(&self) -> Option { - match self { - ExecutableItem::Wasm { .. } - | ExecutableItem::ByPackageHash { .. } - | ExecutableItem::ByPackageName { .. } => None, - ExecutableItem::ByHash { hash, .. } => Some(AddressableEntityIdentifier::Hash(*hash)), - ExecutableItem::ByAddress { address, .. } => { - Some(AddressableEntityIdentifier::Addr(*address)) - } - ExecutableItem::ByName { name, .. } => { - Some(AddressableEntityIdentifier::Name(name.clone())) - } - } - } - - /// Returns the identifier of the contract package in the item, if present. - pub fn contract_package_identifier(&self) -> Option { - match self { - ExecutableItem::Wasm { .. } - | ExecutableItem::ByAddress { .. } - | ExecutableItem::ByName { .. } - | ExecutableItem::ByHash { .. } => None, - - ExecutableItem::ByPackageHash { hash, version, .. } => Some(PackageIdentifier::Hash { - package_hash: *hash, - version: *version, - }), - ExecutableItem::ByPackageName { name, version, .. } => Some(PackageIdentifier::Name { - name: name.clone(), - version: *version, - }), - } - } - - /// Returns the runtime arguments. - pub fn args(&self) -> &RuntimeArgs { - match self { - ExecutableItem::Wasm { args, .. } - | ExecutableItem::ByAddress { args, .. } - | ExecutableItem::ByName { args, .. } - | ExecutableItem::ByHash { args, .. } - | ExecutableItem::ByPackageHash { args, .. } - | ExecutableItem::ByPackageName { args, .. } => args, - } - } - - /// Returns the payment amount from args (if any) as Gas. - pub fn payment_amount(&self, conv_rate: u64) -> Option { - let cl_value = self.args().get(ARG_AMOUNT)?; - let motes = cl_value.clone().into_t::().ok()?; - Gas::from_motes(Motes::new(motes), conv_rate) - } - - /// Returns `true` if this item is a native transfer. - pub fn is_transfer(&self) -> bool { - false - } - - /// Returns `true` if this item is a standard payment. - pub fn is_standard_payment(&self, phase: Phase) -> bool { - if phase != Phase::Payment { - return false; - } - - if let ExecutableItem::Wasm { module_bytes, .. } = self { - return module_bytes.is_empty(); - } - - false - } - - /// Returns `true` if the item is a contract identified by its name. - pub fn is_by_name(&self) -> bool { - matches!(self, ExecutableItem::ByPackageName { .. }) - || matches!(self, ExecutableItem::ByName { .. }) - } - - /// Returns the name of the contract or contract package, if the item is identified by - /// name. - pub fn by_name(&self) -> Option { - match self { - ExecutableItem::ByName { name, .. } | ExecutableItem::ByPackageName { name, .. } => { - Some(name.clone()) - } - ExecutableItem::Wasm { .. } - | ExecutableItem::ByAddress { .. } - | ExecutableItem::ByPackageHash { .. } - | ExecutableItem::ByHash { .. } => None, - } - } - - /// Returns `true` if the item is a stored contract. - pub fn is_addressable_entity(&self) -> bool { - matches!(self, ExecutableItem::ByAddress { .. }) - || matches!(self, ExecutableItem::ByName { .. }) - || matches!(self, ExecutableItem::ByAddress { .. }) - } - - /// Returns `true` if the item is a stored contract package. - pub fn is_package(&self) -> bool { - matches!(self, ExecutableItem::ByPackageHash { .. }) - || matches!(self, ExecutableItem::ByPackageName { .. }) - } - - /// Returns `true` if the item is [`ModuleBytes`]. - /// - /// [`ModuleBytes`]: ExecutableItem::Wasm - pub fn is_module_bytes(&self) -> bool { - matches!(self, Self::Wasm { .. }) - } - - /// Returns a random `ExecutableItem`. - #[cfg(test)] - pub fn random(rng: &mut TestRng) -> Self { - rng.gen() - } -} - -impl ToBytes for ExecutableItem { - fn to_bytes(&self) -> Result, bytesrepr::Error> { - let mut buffer = bytesrepr::allocate_buffer(self)?; - self.write_bytes(&mut buffer)?; - Ok(buffer) - } - - fn serialized_length(&self) -> usize { - TAG_LENGTH - + match self { - ExecutableItem::Wasm { module_bytes, args } => { - module_bytes.serialized_length() + args.serialized_length() - } - ExecutableItem::ByHash { - hash, - entry_point, - args, - } => { - hash.serialized_length() - + entry_point.serialized_length() - + args.serialized_length() - } - ExecutableItem::ByAddress { - address, - entry_point, - args, - } => { - address.serialized_length() - + entry_point.serialized_length() - + args.serialized_length() - } - ExecutableItem::ByName { - name, - entry_point, - args, - } => { - name.serialized_length() - + entry_point.serialized_length() - + args.serialized_length() - } - ExecutableItem::ByPackageHash { - hash, - version, - entry_point, - args, - } => { - hash.serialized_length() - + version.serialized_length() - + entry_point.serialized_length() - + args.serialized_length() - } - ExecutableItem::ByPackageName { - name, - version, - entry_point, - args, - } => { - name.serialized_length() - + version.serialized_length() - + entry_point.serialized_length() - + args.serialized_length() - } - } - } - - fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - match self { - ExecutableItem::Wasm { module_bytes, args } => { - writer.push(MODULE_BYTES_TAG); - module_bytes.write_bytes(writer)?; - args.write_bytes(writer) - } - ExecutableItem::ByHash { - hash, - entry_point, - args, - } => { - writer.push(BY_HASH_TAG); - hash.write_bytes(writer)?; - entry_point.write_bytes(writer)?; - args.write_bytes(writer) - } - ExecutableItem::ByAddress { - address, - entry_point, - args, - } => { - writer.push(BY_ADDR_TAG); - address.write_bytes(writer)?; - entry_point.write_bytes(writer)?; - args.write_bytes(writer) - } - ExecutableItem::ByName { - name, - entry_point, - args, - } => { - writer.push(BY_NAME_TAG); - name.write_bytes(writer)?; - entry_point.write_bytes(writer)?; - args.write_bytes(writer) - } - ExecutableItem::ByPackageHash { - hash, - version, - entry_point, - args, - } => { - writer.push(BY_PACKAGE_HASH); - hash.write_bytes(writer)?; - version.write_bytes(writer)?; - entry_point.write_bytes(writer)?; - args.write_bytes(writer) - } - ExecutableItem::ByPackageName { - name, - version, - entry_point, - args, - } => { - writer.push(BY_PACKAGE_NAME); - name.write_bytes(writer)?; - version.write_bytes(writer)?; - entry_point.write_bytes(writer)?; - args.write_bytes(writer) - } - } - } -} - -impl FromBytes for ExecutableItem { - fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (tag, remainder) = u8::from_bytes(bytes)?; - match tag { - MODULE_BYTES_TAG => { - let (module_bytes, remainder) = Bytes::from_bytes(remainder)?; - let (args, remainder) = RuntimeArgs::from_bytes(remainder)?; - Ok((ExecutableItem::Wasm { module_bytes, args }, remainder)) - } - BY_ADDR_TAG => { - let (address, remainder) = EntityAddr::from_bytes(remainder)?; - let (entry_point, remainder) = String::from_bytes(remainder)?; - let (args, remainder) = RuntimeArgs::from_bytes(remainder)?; - Ok(( - ExecutableItem::ByAddress { - address, - entry_point, - args, - }, - remainder, - )) - } - BY_HASH_TAG => { - let (hash, remainder) = AddressableEntityHash::from_bytes(remainder)?; - let (entry_point, remainder) = String::from_bytes(remainder)?; - let (args, remainder) = RuntimeArgs::from_bytes(remainder)?; - Ok(( - ExecutableItem::ByHash { - hash, - entry_point, - args, - }, - remainder, - )) - } - BY_NAME_TAG => { - let (name, remainder) = String::from_bytes(remainder)?; - let (entry_point, remainder) = String::from_bytes(remainder)?; - let (args, remainder) = RuntimeArgs::from_bytes(remainder)?; - Ok(( - ExecutableItem::ByName { - name, - entry_point, - args, - }, - remainder, - )) - } - BY_PACKAGE_HASH => { - let (hash, remainder) = PackageHash::from_bytes(remainder)?; - let (version, remainder) = Option::::from_bytes(remainder)?; - let (entry_point, remainder) = String::from_bytes(remainder)?; - let (args, remainder) = RuntimeArgs::from_bytes(remainder)?; - Ok(( - ExecutableItem::ByPackageHash { - hash, - version, - entry_point, - args, - }, - remainder, - )) - } - BY_PACKAGE_NAME => { - let (name, remainder) = String::from_bytes(remainder)?; - let (version, remainder) = Option::::from_bytes(remainder)?; - let (entry_point, remainder) = String::from_bytes(remainder)?; - let (args, remainder) = RuntimeArgs::from_bytes(remainder)?; - Ok(( - ExecutableItem::ByPackageName { - name, - version, - entry_point, - args, - }, - remainder, - )) - } - _ => Err(bytesrepr::Error::Formatting), - } - } -} - -impl Display for ExecutableItem { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self { - ExecutableItem::Wasm { module_bytes, .. } => { - write!(f, "module-bytes [{} bytes]", module_bytes.len()) - } - ExecutableItem::ByHash { - hash, entry_point, .. - } => write!( - f, - "by-hash: {:10}, entry-point: {}", - HexFmt(hash), - entry_point, - ), - ExecutableItem::ByAddress { - address, - entry_point, - .. - } => write!(f, "by-address: {}, entry-point: {}", address, entry_point,), - ExecutableItem::ByName { - name, entry_point, .. - } => write!(f, "by-name: {}, entry-point: {}", name, entry_point,), - ExecutableItem::ByPackageHash { - hash, - version: Some(ver), - entry_point, - .. - } => write!( - f, - "by-package-hash-and-version: {:10}, version: {}, entry-point: {}", - HexFmt(hash), - ver, - entry_point, - ), - ExecutableItem::ByPackageHash { - hash, entry_point, .. - } => write!( - f, - "by-package-hash: {:10}, version: latest, entry-point: {}", - HexFmt(hash), - entry_point, - ), - ExecutableItem::ByPackageName { - name, - version: Some(ver), - entry_point, - .. - } => write!( - f, - "by-package-name-and-version: {}, version: {}, entry-point: {}", - name, ver, entry_point, - ), - ExecutableItem::ByPackageName { - name, entry_point, .. - } => write!( - f, - "by-package-name: {}, version: latest, entry-point: {}", - name, entry_point, - ), - } - } -} - -impl Debug for ExecutableItem { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self { - ExecutableItem::Wasm { module_bytes, args } => f - .debug_struct("Wasm") - .field("module_bytes", &format!("[{} bytes]", module_bytes.len())) - .field("args", args) - .finish(), - ExecutableItem::ByHash { - hash, - entry_point, - args, - } => f - .debug_struct("ByHash") - .field("hash", &base16::encode_lower(hash)) - .field("entry_point", &entry_point) - .field("args", args) - .finish(), - ExecutableItem::ByAddress { - address, - entry_point, - args, - } => f - .debug_struct("ByAddress") - .field("address", &address) - .field("entry_point", &entry_point) - .field("args", args) - .finish(), - ExecutableItem::ByName { - name, - entry_point, - args, - } => f - .debug_struct("StoredContractByName") - .field("name", &name) - .field("entry_point", &entry_point) - .field("args", args) - .finish(), - ExecutableItem::ByPackageHash { - hash, - version, - entry_point, - args, - } => f - .debug_struct("ByPackageHash") - .field("hash", &base16::encode_lower(hash)) - .field("version", version) - .field("entry_point", &entry_point) - .field("args", args) - .finish(), - ExecutableItem::ByPackageName { - name, - version, - entry_point, - args, - } => f - .debug_struct("ByPackageName") - .field("name", &name) - .field("version", version) - .field("entry_point", &entry_point) - .field("args", args) - .finish(), - } - } -} - -impl TryFrom for ExecutableItem { - type Error = (); - - fn try_from(deploy_item: ExecutableDeployItem) -> Result { - let ret = match deploy_item { - ExecutableDeployItem::ModuleBytes { module_bytes, args } => { - ExecutableItem::Wasm { module_bytes, args } - } - ExecutableDeployItem::StoredContractByHash { - hash, - entry_point, - args, - } => ExecutableItem::ByHash { - hash, - entry_point, - args, - }, - ExecutableDeployItem::StoredContractByName { - name, - entry_point, - args, - } => ExecutableItem::ByName { - name, - entry_point, - args, - }, - ExecutableDeployItem::StoredVersionedContractByHash { - hash, - version, - entry_point, - args, - } => ExecutableItem::ByPackageHash { - hash, - version, - entry_point, - args, - }, - ExecutableDeployItem::StoredVersionedContractByName { - name, - version, - entry_point, - args, - } => ExecutableItem::ByPackageName { - name, - version, - entry_point, - args, - }, - _ => return Err(()), - }; - - Ok(ret) - } -} - -impl TryFrom for ExecutableItem { - type Error = (); - - fn try_from(transaction: Transaction) -> Result { - match transaction { - Transaction::Deploy(deploy) => Ok(ExecutableItem::try_from(deploy.session().clone())?), - Transaction::V1(v1) => match v1.body().target() { - TransactionTarget::Native => Err(()), - TransactionTarget::Stored { id, runtime } => { - if &TransactionRuntime::VmCasperV1 != runtime { - return Err(()); - } - match id { - TransactionInvocationTarget::InvocableEntity(hash_addr) => { - Ok(ExecutableItem::ByHash { - hash: AddressableEntityHash::new(*hash_addr), - args: v1.body().args().clone(), - entry_point: v1.body().entry_point().to_string(), - }) - } - TransactionInvocationTarget::InvocableEntityAlias(name) => { - Ok(ExecutableItem::ByName { - name: name.clone(), - args: v1.body().args().clone(), - entry_point: v1.body().entry_point().to_string(), - }) - } - TransactionInvocationTarget::Package { addr, version } => { - Ok(ExecutableItem::ByPackageHash { - hash: PackageHash::new(*addr), - args: v1.body().args().clone(), - entry_point: v1.body().entry_point().to_string(), - version: *version, - }) - } - TransactionInvocationTarget::PackageAlias { alias, version } => { - Ok(ExecutableItem::ByPackageName { - name: alias.clone(), - args: v1.body().args().clone(), - entry_point: v1.body().entry_point().to_string(), - version: *version, - }) - } - } - } - TransactionTarget::Session { - module_bytes, - runtime, - .. - } => { - if &TransactionRuntime::VmCasperV1 != runtime { - return Err(()); - } - Ok(ExecutableItem::Wasm { - module_bytes: module_bytes.clone(), - args: v1.body().args().clone(), - }) - } - }, - } - } -} - -#[cfg(test)] -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> ExecutableItem { - fn random_bytes(rng: &mut R) -> Vec { - let mut bytes = vec![0u8; rng.gen_range(0..100)]; - rng.fill_bytes(bytes.as_mut()); - bytes - } - - fn random_string(rng: &mut R) -> String { - rng.sample_iter(&Alphanumeric) - .take(20) - .map(char::from) - .collect() - } - - let mut args = RuntimeArgs::new(); - let _ = args.insert(random_string(rng), Bytes::from(random_bytes(rng))); - - match rng.gen_range(0..5) { - 0 => ExecutableItem::Wasm { - module_bytes: random_bytes(rng).into(), - args, - }, - 1 => ExecutableItem::ByHash { - hash: AddressableEntityHash::new(rng.gen()), - entry_point: random_string(rng), - args, - }, - 2 => ExecutableItem::ByName { - name: random_string(rng), - entry_point: random_string(rng), - args, - }, - 3 => ExecutableItem::ByPackageHash { - hash: PackageHash::new(rng.gen()), - version: rng.gen(), - entry_point: random_string(rng), - args, - }, - 4 => ExecutableItem::ByPackageName { - name: random_string(rng), - version: rng.gen(), - entry_point: random_string(rng), - args, - }, - 5 => ExecutableItem::ByAddress { - address: EntityAddr::new_of_kind(rng.gen(), rng.gen()), - entry_point: random_string(rng), - args, - }, - _ => unreachable!(), - } - } -} - -/// The various types which can be used as the `target` runtime argument of a native transfer. -#[derive(Clone, Ord, PartialOrd, Eq, PartialEq)] -pub enum TransferTarget { - /// A public key. - PublicKey(PublicKey), - /// An account hash. - AccountHash(AccountHash), - /// A URef. - URef(URef), -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn serialization_roundtrip() { - let rng = &mut TestRng::new(); - for _ in 0..10 { - let executable_deploy_item = ExecutableItem::random(rng); - bytesrepr::test_serialization_roundtrip(&executable_deploy_item); - } - } -} diff --git a/execution_engine/src/engine_state/execute_request.rs b/execution_engine/src/engine_state/execute_request.rs deleted file mode 100644 index a6680d1972..0000000000 --- a/execution_engine/src/engine_state/execute_request.rs +++ /dev/null @@ -1,332 +0,0 @@ -use std::{collections::BTreeSet, convert::TryFrom}; - -use serde::Serialize; -use thiserror::Error; - -use casper_types::{ - account::AccountHash, bytesrepr::Bytes, runtime_args, BlockTime, DeployHash, Digest, - ExecutableDeployItem, InitiatorAddr, PublicKey, RuntimeArgs, Transaction, - TransactionEntryPoint, TransactionHash, TransactionInvocationTarget, TransactionSessionKind, - TransactionTarget, TransactionV1Body, TransactionV1Hash, U512, -}; - -const DEFAULT_ENTRY_POINT: &str = "call"; - -/// The payment method for the transaction. -#[derive(Debug)] -pub enum Payment { - /// Standard payment (Wasmless execution). - Standard, - /// A stored entity or package to be executed as custom payment. - Stored(TransactionInvocationTarget), - /// Compiled Wasm as byte code to be executed as custom payment. - ModuleBytes(Bytes), -} - -/// The payment-related portion of an `ExecuteRequest`. -pub struct PaymentInfo { - /// The payment item. - pub payment: Payment, - /// The payment entry point. - pub entry_point: String, - /// The payment runtime args. - pub args: RuntimeArgs, -} - -impl TryFrom<(ExecutableDeployItem, DeployHash)> for PaymentInfo { - type Error = NewRequestError; - - fn try_from( - (payment_item, deploy_hash): (ExecutableDeployItem, DeployHash), - ) -> Result { - let payment: Payment; - let payment_entry_point: String; - let payment_args: RuntimeArgs; - match payment_item { - ExecutableDeployItem::ModuleBytes { module_bytes, args } => { - if module_bytes.is_empty() { - payment = Payment::Standard; - } else { - payment = Payment::ModuleBytes(module_bytes); - } - payment_entry_point = DEFAULT_ENTRY_POINT.to_string(); - payment_args = args; - } - ExecutableDeployItem::StoredContractByHash { - hash, - entry_point, - args, - } => { - payment = Payment::Stored(TransactionInvocationTarget::new_invocable_entity(hash)); - payment_entry_point = entry_point; - payment_args = args; - } - ExecutableDeployItem::StoredContractByName { - name, - entry_point, - args, - } => { - payment = Payment::Stored(TransactionInvocationTarget::new_invocable_entity_alias( - name, - )); - payment_entry_point = entry_point; - payment_args = args; - } - ExecutableDeployItem::StoredVersionedContractByHash { - hash, - version, - entry_point, - args, - } => { - payment = Payment::Stored(TransactionInvocationTarget::new_package(hash, version)); - payment_entry_point = entry_point; - payment_args = args; - } - ExecutableDeployItem::StoredVersionedContractByName { - name, - version, - entry_point, - args, - } => { - payment = Payment::Stored(TransactionInvocationTarget::new_package_alias( - name, version, - )); - payment_entry_point = entry_point; - payment_args = args; - } - ExecutableDeployItem::Transfer { .. } => { - return Err(NewRequestError::InvalidPaymentDeployItem(deploy_hash)); - } - } - Ok(PaymentInfo { - payment, - entry_point: payment_entry_point, - args: payment_args, - }) - } -} - -/// The session to be executed. -#[derive(Debug)] -pub enum Session { - /// A stored entity or package. - Stored(TransactionInvocationTarget), - /// Compiled Wasm from a transaction >= V1 as byte code. - ModuleBytes { - /// The kind of session. - kind: TransactionSessionKind, - /// The compiled Wasm. - module_bytes: Bytes, - }, - /// Compiled Wasm from a deploy as byte code. - DeployModuleBytes(Bytes), -} - -/// The session-related portion of an `ExecuteRequest`. -pub struct SessionInfo { - /// The session item. - pub session: Session, - /// The session entry point. - pub entry_point: String, - /// The session runtime args. - pub args: RuntimeArgs, -} - -impl TryFrom<(ExecutableDeployItem, DeployHash)> for SessionInfo { - type Error = NewRequestError; - - fn try_from( - (session_item, deploy_hash): (ExecutableDeployItem, DeployHash), - ) -> Result { - let session: Session; - let session_entry_point: String; - let session_args: RuntimeArgs; - match session_item { - ExecutableDeployItem::ModuleBytes { module_bytes, args } => { - session = Session::DeployModuleBytes(module_bytes); - session_entry_point = DEFAULT_ENTRY_POINT.to_string(); - session_args = args; - } - ExecutableDeployItem::StoredContractByHash { - hash, - entry_point, - args, - } => { - session = Session::Stored(TransactionInvocationTarget::new_invocable_entity(hash)); - session_entry_point = entry_point; - session_args = args; - } - ExecutableDeployItem::StoredContractByName { - name, - entry_point, - args, - } => { - session = Session::Stored(TransactionInvocationTarget::new_invocable_entity_alias( - name, - )); - session_entry_point = entry_point; - session_args = args; - } - ExecutableDeployItem::StoredVersionedContractByHash { - hash, - version, - entry_point, - args, - } => { - session = Session::Stored(TransactionInvocationTarget::new_package(hash, version)); - session_entry_point = entry_point; - session_args = args; - } - ExecutableDeployItem::StoredVersionedContractByName { - name, - version, - entry_point, - args, - } => { - session = Session::Stored(TransactionInvocationTarget::new_package_alias( - name, version, - )); - session_entry_point = entry_point; - session_args = args; - } - ExecutableDeployItem::Transfer { .. } => { - return Err(NewRequestError::InvalidSessionDeployItem(deploy_hash)); - } - } - Ok(SessionInfo { - session, - entry_point: session_entry_point, - args: session_args, - }) - } -} - -impl TryFrom<(TransactionV1Body, TransactionV1Hash)> for SessionInfo { - type Error = NewRequestError; - - fn try_from( - (txn_v1_body, txn_v1_hash): (TransactionV1Body, TransactionV1Hash), - ) -> Result { - let (args, target, entry_point, _scheduling) = txn_v1_body.destructure(); - - let session = match target { - TransactionTarget::Native => { - return Err(NewRequestError::InvalidSessionV1Target(txn_v1_hash)); - } - TransactionTarget::Stored { id, .. } => Session::Stored(id), - TransactionTarget::Session { - kind, module_bytes, .. - } => Session::ModuleBytes { kind, module_bytes }, - }; - - let TransactionEntryPoint::Custom(session_entry_point) = entry_point else { - return Err(NewRequestError::InvalidSessionV1EntryPoint(txn_v1_hash)); - }; - - Ok(SessionInfo { - session, - entry_point: session_entry_point, - args, - }) - } -} - -/// Error returned if constructing a new [`ExecuteRequest`] fails. -#[derive(Copy, Clone, Eq, PartialEq, Error, Serialize, Debug)] -pub enum NewRequestError { - /// The executable deploy item for payment cannot be the transfer variant. - #[error("cannot use transfer variant for payment in deploy {0}")] - InvalidPaymentDeployItem(DeployHash), - /// The executable deploy item for session cannot be the transfer variant. - #[error("cannot use transfer variant for session in deploy {0}")] - InvalidSessionDeployItem(DeployHash), - /// The transaction v1 target for session cannot be the native variant. - #[error("cannot use native variant for session target in transaction v1 {0}")] - InvalidSessionV1Target(TransactionV1Hash), - /// The transaction v1 entry point for session cannot be one of the native variants. - #[error("cannot use native variant for session entry point in transaction v1 {0}")] - InvalidSessionV1EntryPoint(TransactionV1Hash), -} - -/// A request to execute the given transaction. -#[derive(Debug)] -pub struct ExecuteRequest { - /// State root hash of the global state in which the transaction will be executed. - pub state_hash: Digest, - /// Block time represented as a unix timestamp. - pub block_time: BlockTime, - /// The hash identifying the transaction. - pub transaction_hash: TransactionHash, - /// The number of Motes per unit of Gas to be paid for execution. - pub gas_price: u64, - /// The transaction's initiator. - pub initiator_addr: InitiatorAddr, - /// The payment kind. - pub payment: Payment, - /// The entry point to call when executing the payment. - pub payment_entry_point: String, - /// The payment runtime args. - pub payment_args: RuntimeArgs, - /// The session kind. - pub session: Session, - /// The entry point to call when executing the session. - pub session_entry_point: String, - /// The session runtime args. - pub session_args: RuntimeArgs, - /// The account hashes of the signers of the transaction. - pub authorization_keys: BTreeSet, - /// The owner of the node that proposed the block containing this request. - pub proposer: PublicKey, -} - -impl ExecuteRequest { - /// Creates a new execute request. - pub fn new( - state_hash: Digest, - block_time: BlockTime, - txn: Transaction, - proposer: PublicKey, - ) -> Result { - let transaction_hash = txn.hash(); - let initiator_addr = txn.initiator_addr(); - let authorization_keys = txn.signers(); - - let gas_price: u64; - let payment_info: PaymentInfo; - let session_info: SessionInfo; - match txn { - Transaction::Deploy(deploy) => { - let (hash, _header, payment, session, _approvals) = deploy.destructure(); - gas_price = _header.gas_price(); - payment_info = PaymentInfo::try_from((payment, hash))?; - session_info = SessionInfo::try_from((session, hash))?; - } - Transaction::V1(v1_txn) => { - let (hash, _header, body, _approvals) = v1_txn.destructure(); - gas_price = 1; - payment_info = PaymentInfo { - payment: Payment::Standard, - entry_point: DEFAULT_ENTRY_POINT.to_string(), - args: runtime_args! { "amount" => U512::from(1_500_000_000_000_u64) }, /* TODO - this is bogus: should be resolved once new payment logic is merged. */ - }; - session_info = SessionInfo::try_from((body, hash))?; - } - }; - - Ok(Self { - state_hash, - block_time, - transaction_hash, - gas_price, - initiator_addr, - payment: payment_info.payment, - payment_entry_point: payment_info.entry_point, - payment_args: payment_info.args, - session: session_info.session, - session_entry_point: session_info.entry_point, - session_args: session_info.args, - authorization_keys, - proposer, - }) - } -} diff --git a/execution_engine/src/engine_state/execution_kind.rs b/execution_engine/src/engine_state/execution_kind.rs index 435dc09d9f..fe0af6dca5 100644 --- a/execution_engine/src/engine_state/execution_kind.rs +++ b/execution_engine/src/engine_state/execution_kind.rs @@ -6,10 +6,11 @@ use casper_storage::{ }; use casper_types::{ addressable_entity::NamedKeys, bytesrepr::Bytes, AddressableEntityHash, EntityVersionKey, Key, - PackageHash, ProtocolVersion, StoredValue, TransactionInvocationTarget, + PackageHash, ProtocolVersion, StoredValue, TransactionInvocationTarget, TransactionSessionKind, }; -use crate::{engine_state::error::Error, execution::ExecError}; +use super::{Error, ExecutableItem}; +use crate::execution::ExecError; /// The type of execution about to be performed. #[derive(Clone, Debug)] @@ -37,46 +38,52 @@ pub(crate) enum ExecutionKind<'a> { } impl<'a> ExecutionKind<'a> { - /// Returns a new `Standard` variant of `ExecutionKind`. - pub fn new_standard(module_bytes: &'a Bytes) -> Self { - ExecutionKind::Standard(module_bytes) - } - - /// Returns a new `Installer` variant of `ExecutionKind`. - pub fn new_installer(module_bytes: &'a Bytes) -> Self { - ExecutionKind::Installer(module_bytes) - } - - /// Returns a new `Upgrader` variant of `ExecutionKind`. - pub fn new_upgrader(module_bytes: &'a Bytes) -> Self { - ExecutionKind::Upgrader(module_bytes) - } - - /// Returns a new `Isolated` variant of `ExecutionKind`. - pub fn new_isolated(module_bytes: &'a Bytes) -> Self { - ExecutionKind::Isolated(module_bytes) - } - - /// Returns a new `Deploy` variant of `ExecutionKind`. - pub fn new_deploy(module_bytes: &'a Bytes) -> Self { - ExecutionKind::Deploy(module_bytes) - } - - /// Returns a new `Standard` variant of `ExecutionKind`, returning an error if the module bytes - /// are empty. - pub fn new_standard_for_payment(module_bytes: &'a Bytes) -> Result { - if module_bytes.is_empty() { - return Err(Error::EmptyCustomPaymentModuleBytes); + pub(crate) fn new( + tracking_copy: &mut TrackingCopy, + named_keys: &NamedKeys, + executable_item: &'a ExecutableItem, + entry_point: String, + protocol_version: ProtocolVersion, + ) -> Result + where + R: StateReader, + { + match executable_item { + ExecutableItem::Stored(target) => Self::new_stored( + tracking_copy, + named_keys, + target, + entry_point, + protocol_version, + ), + ExecutableItem::CustomPayment(module_bytes) + | ExecutableItem::SessionModuleBytes { + kind: TransactionSessionKind::Standard, + module_bytes, + } => Ok(ExecutionKind::Standard(module_bytes)), + ExecutableItem::SessionModuleBytes { + kind: TransactionSessionKind::Installer, + module_bytes, + } => Ok(ExecutionKind::Installer(module_bytes)), + ExecutableItem::SessionModuleBytes { + kind: TransactionSessionKind::Upgrader, + module_bytes, + } => Ok(ExecutionKind::Upgrader(module_bytes)), + ExecutableItem::SessionModuleBytes { + kind: TransactionSessionKind::Isolated, + module_bytes, + } => Ok(ExecutionKind::Isolated(module_bytes)), + ExecutableItem::DeploySessionModuleBytes(module_bytes) => { + Ok(ExecutionKind::Deploy(module_bytes)) + } } - Ok(ExecutionKind::Standard(module_bytes)) } - /// Returns a new `Stored` variant of `ExecutionKind`. - pub fn new_stored( + fn new_stored( tracking_copy: &mut TrackingCopy, + named_keys: &NamedKeys, target: &TransactionInvocationTarget, entry_point: String, - named_keys: &NamedKeys, protocol_version: ProtocolVersion, ) -> Result where diff --git a/execution_engine/src/engine_state/execution_result.rs b/execution_engine/src/engine_state/execution_result.rs index f53a335079..f1623524e5 100644 --- a/execution_engine/src/engine_state/execution_result.rs +++ b/execution_engine/src/engine_state/execution_result.rs @@ -317,28 +317,6 @@ impl ExecutionResult { (None, self) } - /// Converts a transfer result to an execution result. - pub fn from_transfer_result(transfer_result: TransferResult, gas: Gas) -> Option { - match transfer_result { - TransferResult::RootNotFound => None, - TransferResult::Success { transfers, effects } => Some(ExecutionResult::Success { - transfers, - gas, - effects, - messages: Messages::default(), - }), - TransferResult::Failure(te) => { - Some(ExecutionResult::Failure { - error: Error::Transfer(te), - transfers: vec![], - gas, - effects: Effects::default(), // currently not returning effects on failure - messages: Messages::default(), - }) - } - } - } - /// Converts a bidding result to an execution result. pub fn from_bidding_result(bidding_result: BiddingResult, gas: Gas) -> Option { match bidding_result { diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index 023754609b..72b05b6d0d 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -2,13 +2,11 @@ pub mod deploy_item; pub mod engine_config; mod error; -pub mod executable_item; -pub mod execute_request; pub(crate) mod execution_kind; pub mod execution_result; mod wasm_v1; -use std::{cell::RefCell, convert::TryFrom, rc::Rc}; +use std::{cell::RefCell, rc::Rc}; use once_cell::sync::Lazy; @@ -16,7 +14,7 @@ use casper_storage::{ global_state::state::StateProvider, tracking_copy::{TrackingCopyEntityExt, TrackingCopyError, TrackingCopyExt}, }; -use casper_types::{Phase, ProtocolVersion, U512}; +use casper_types::{ProtocolVersion, U512}; use crate::{execution::Executor, runtime::RuntimeStack}; pub use deploy_item::DeployItem; @@ -25,13 +23,9 @@ pub use engine_config::{ DEFAULT_MAX_RUNTIME_CALL_STACK_HEIGHT, }; pub use error::Error; -pub use executable_item::{ExecutableItem, ExecutableItemIdentifier}; -pub use execute_request::{ - ExecuteRequest, NewRequestError, Payment, PaymentInfo, Session, SessionInfo, -}; use execution_kind::ExecutionKind; pub use execution_result::{ExecutionResult, ForcedTransferResult}; -pub use wasm_v1::{WasmV1Request, WasmV1Result}; +pub use wasm_v1::{ExecutableItem, InvalidRequest, WasmV1Request, WasmV1Result}; /// The maximum amount of motes that payment code execution can cost. pub const MAX_PAYMENT_AMOUNT: u64 = 2_500_000_000; @@ -82,47 +76,18 @@ impl ExecutionEngineV1 { state_provider: &impl StateProvider, WasmV1Request { state_hash, - protocol_version, block_time, - transaction, + transaction_hash, gas_limit, - phase, + initiator_addr, + executable_item, + entry_point, + args, + authorization_keys, }: WasmV1Request, ) -> WasmV1Result { - let account_hash = transaction.initiator_addr().account_hash(); - let authorization_keys = &transaction.authorization_keys(); - let transaction_hash = transaction.hash(); - let executable_item = match ExecutableItem::try_from(transaction) { - Ok(executable_item) => executable_item, - Err(_) => return WasmV1Result::invalid_executable_item(gas_limit), - }; - match phase { - Phase::System | Phase::FinalizePayment => { - return WasmV1Result::precondition_failure( - gas_limit, - Error::Deprecated(format!( - "execution of phase {:?} is no longer supported", - phase - )), - ); - } - Phase::Payment => { - if !executable_item.is_module_bytes() { - return WasmV1Result::precondition_failure( - gas_limit, - Error::Deprecated(format!( - "direct execution in phase {:?} is no longer supported", - phase - )), - ); - } - // module bytes is allowed - } - Phase::Session => { - // noop - } - }; - + let account_hash = initiator_addr.account_hash(); + let protocol_version = self.config.protocol_version(); let tc = match state_provider.tracking_copy(state_hash) { Ok(Some(tracking_copy)) => Rc::new(RefCell::new(tracking_copy)), Ok(None) => return WasmV1Result::root_not_found(gas_limit, state_hash), @@ -137,7 +102,7 @@ impl ExecutionEngineV1 { match tc.borrow_mut().get_authorized_addressable_entity( protocol_version, account_hash, - authorization_keys, + &authorization_keys, &self.config().administrative_accounts, ) { Ok((addressable_entity, entity_hash)) => (addressable_entity, entity_hash), @@ -156,28 +121,27 @@ impl ExecutionEngineV1 { return WasmV1Result::precondition_failure(gas_limit, Error::TrackingCopy(tce)) } }; - let execution_kind = match ExecutionKind::from_executable_item( - tc.clone(), + let phase = executable_item.phase(); + let execution_kind = match ExecutionKind::new( + &mut *tc.borrow_mut(), &named_keys, - executable_item.clone(), - &protocol_version, - phase, + &executable_item, + entry_point, + protocol_version, ) { Ok(execution_kind) => execution_kind, Err(ese) => return WasmV1Result::precondition_failure(gas_limit, ese), }; let access_rights = entity.extract_access_rights(entity_hash, &named_keys); - let runtime_args = executable_item.args().clone(); - let execution_result = Executor::new(self.config().clone()).exec( execution_kind, - runtime_args, + args, entity_hash, &entity, &mut named_keys, access_rights, - authorization_keys.clone(), + authorization_keys, account_hash, block_time, transaction_hash, @@ -191,6 +155,6 @@ impl ExecutionEngineV1 { ), ); - WasmV1Result::execution_result(gas_limit, execution_result) + WasmV1Result::from_execution_result(gas_limit, execution_result) } } diff --git a/execution_engine/src/engine_state/wasm_v1.rs b/execution_engine/src/engine_state/wasm_v1.rs index f1d676b9e4..390011b592 100644 --- a/execution_engine/src/engine_state/wasm_v1.rs +++ b/execution_engine/src/engine_state/wasm_v1.rs @@ -1,125 +1,227 @@ +use std::{collections::BTreeSet, convert::TryFrom}; + +use serde::Serialize; +use thiserror::Error; + +use casper_storage::data_access_layer::TransferResult; use casper_types::{ - bytesrepr, - bytesrepr::{FromBytes, ToBytes}, - contract_messages::Messages, - execution::Effects, - BlockTime, Digest, Gas, Phase, ProtocolVersion, Transaction, TransferAddr, + account::AccountHash, bytesrepr::Bytes, contract_messages::Messages, execution::Effects, + runtime_args, system::mint::ARG_AMOUNT, BlockTime, DeployHash, Digest, ExecutableDeployItem, + Gas, InitiatorAddr, Phase, PricingMode, RuntimeArgs, Transaction, TransactionEntryPoint, + TransactionHash, TransactionInvocationTarget, TransactionSessionKind, TransactionTarget, + TransactionV1, TransactionV1Hash, TransferAddr, U512, }; -use crate::engine_state::{Error as EngineError, ExecutionResult}; +use crate::engine_state::{DeployItem, Error as EngineError, ExecutionResult}; + +const DEFAULT_ENTRY_POINT: &str = "call"; + +/// Error returned if constructing a new [`WasmV1Request`] fails. +#[derive(Copy, Clone, Eq, PartialEq, Error, Serialize, Debug)] +pub enum InvalidRequest { + /// The module bytes for custom payment must not be empty. + #[error("empty module bytes for custom payment in deploy {0}")] + EmptyCustomPaymentBytes(DeployHash), + /// The executable deploy item for custom payment must be the module bytes variant. + #[error("can only use module bytes for custom payment in deploy {0}")] + InvalidPaymentDeployItem(DeployHash), + /// The transaction v1 pricing mode must be the classic variant with `standard_payment` false. + #[error( + "can only use classic variant with `standard_payment` false for pricing mode in \ + transaction v1 {0}" + )] + InvalidPricingMode(TransactionV1Hash), + /// The executable deploy item for session cannot be the transfer variant. + #[error("cannot use transfer variant for session in deploy {0}")] + InvalidSessionDeployItem(DeployHash), + /// The transaction v1 target for session cannot be the native variant. + #[error("cannot use native variant for session target in transaction v1 {0}")] + InvalidSessionV1Target(TransactionV1Hash), + /// The transaction v1 entry point for session cannot be one of the native variants. + #[error("cannot use native variant for session entry point in transaction v1 {0}")] + InvalidSessionV1EntryPoint(TransactionV1Hash), +} + +/// The item to be executed. +#[derive(Debug)] +pub enum ExecutableItem { + /// A stored entity or package. + Stored(TransactionInvocationTarget), + /// Compiled Wasm from a transaction >= V1 as byte code. + SessionModuleBytes { + /// The kind of session. + kind: TransactionSessionKind, + /// The compiled Wasm. + module_bytes: Bytes, + }, + /// Compiled Wasm from a deploy as byte code. + DeploySessionModuleBytes(Bytes), + /// Module bytes to be used as custom payment. + CustomPayment(Bytes), +} + +impl ExecutableItem { + pub(super) fn phase(&self) -> Phase { + match self { + ExecutableItem::Stored(_) + | ExecutableItem::SessionModuleBytes { .. } + | ExecutableItem::DeploySessionModuleBytes(_) => Phase::Session, + ExecutableItem::CustomPayment(_) => Phase::Payment, + } + } +} -/// Wasm v1 request. +/// A request to execute the given Wasm on the V1 runtime. +#[derive(Debug)] pub struct WasmV1Request { - pub(super) state_hash: Digest, - pub(super) protocol_version: ProtocolVersion, - pub(super) block_time: BlockTime, - pub(super) transaction: Transaction, - pub(super) gas_limit: Gas, - pub(super) phase: Phase, + /// State root hash of the global state in which the transaction will be executed. + pub state_hash: Digest, + /// Block time represented as a unix timestamp. + pub block_time: BlockTime, + /// The hash identifying the transaction. + pub transaction_hash: TransactionHash, + /// The number of Motes per unit of Gas to be paid for execution. + pub gas_limit: Gas, + /// The transaction's initiator. + pub initiator_addr: InitiatorAddr, + /// The executable item. + pub executable_item: ExecutableItem, + /// The entry point to call when executing. + pub entry_point: String, + /// The runtime args. + pub args: RuntimeArgs, + /// The account hashes of the signers of the transaction. + pub authorization_keys: BTreeSet, } impl WasmV1Request { - /// Returns new instance of WasmV1Request. - pub fn new( + /// Creates a new request from a transaction for use as the session code. + pub fn new_session( state_hash: Digest, - protocol_version: ProtocolVersion, block_time: BlockTime, - transaction: Transaction, gas_limit: Gas, - phase: Phase, - ) -> Self { - WasmV1Request { + txn: Transaction, + ) -> Result { + let transaction_hash = txn.hash(); + let initiator_addr = txn.initiator_addr(); + let authorization_keys = txn.signers(); + + let session_info = match txn { + Transaction::Deploy(deploy) => { + let (hash, _header, _payment, session_deploy_item, _approvals) = + deploy.destructure(); + SessionInfo::try_from((session_deploy_item, hash))? + } + Transaction::V1(v1_txn) => SessionInfo::try_from(v1_txn)?, + }; + + Ok(Self { state_hash, - protocol_version, block_time, - transaction, + transaction_hash, gas_limit, - phase, - } - } - - /// State hash. - pub fn state_hash(&self) -> Digest { - self.state_hash - } - - /// Protocol version. - pub fn protocol_version(&self) -> ProtocolVersion { - self.protocol_version + initiator_addr, + executable_item: session_info.session, + entry_point: session_info.entry_point, + args: session_info.args, + authorization_keys, + }) } - /// Blocktime. - pub fn block_time(&self) -> BlockTime { - self.block_time - } - - /// Transaction. - pub fn transaction(&self) -> &Transaction { - &self.transaction - } - - /// Gas limit. - pub fn gas_limit(&self) -> Gas { - self.gas_limit - } - - /// Phase. - pub fn phase(&self) -> Phase { - self.phase - } -} + /// Creates a new request from a transaction for use as custom payment. + pub fn new_custom_payment( + state_hash: Digest, + block_time: BlockTime, + gas_limit: Gas, + txn: Transaction, + ) -> Result { + let transaction_hash = txn.hash(); + let initiator_addr = txn.initiator_addr(); + let authorization_keys = txn.signers(); -impl ToBytes for WasmV1Request { - fn to_bytes(&self) -> Result, bytesrepr::Error> { - let mut buffer = bytesrepr::allocate_buffer(self)?; - self.write_bytes(&mut buffer)?; - Ok(buffer) - } + let payment_info = match txn { + Transaction::Deploy(deploy) => { + let (hash, _header, payment_deploy_item, _session, _approvals) = + deploy.destructure(); + PaymentInfo::try_from((payment_deploy_item, hash))? + } + Transaction::V1(v1_txn) => PaymentInfo::try_from(v1_txn)?, + }; - fn serialized_length(&self) -> usize { - ToBytes::serialized_length(&self.state_hash) - + ToBytes::serialized_length(&self.protocol_version) - + ToBytes::serialized_length(&self.block_time) - + ToBytes::serialized_length(&self.protocol_version) - + ToBytes::serialized_length(&self.transaction) - + ToBytes::serialized_length(&self.gas_limit) - + ToBytes::serialized_length(&self.phase) + Ok(Self { + state_hash, + block_time, + transaction_hash, + gas_limit, + initiator_addr, + executable_item: payment_info.payment, + entry_point: DEFAULT_ENTRY_POINT.to_string(), + args: payment_info.args, + authorization_keys, + }) } - fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - self.state_hash.write_bytes(writer)?; - self.protocol_version.write_bytes(writer)?; - self.block_time.write_bytes(writer)?; - self.transaction.write_bytes(writer)?; - self.gas_limit.write_bytes(writer)?; - self.phase.write_bytes(writer) + /// Creates a new request from a deploy item for use as the session code. + // + // TODO - deprecate? + pub fn new_session_from_deploy_item( + state_hash: Digest, + block_time: BlockTime, + gas_limit: Gas, + DeployItem { + address, + session, + authorization_keys, + deploy_hash, + .. + }: DeployItem, + ) -> Result { + let session_info = SessionInfo::try_from((session, deploy_hash))?; + Ok(Self { + state_hash, + block_time, + transaction_hash: TransactionHash::Deploy(deploy_hash), + gas_limit, + initiator_addr: InitiatorAddr::AccountHash(address), + executable_item: session_info.session, + entry_point: session_info.entry_point, + args: session_info.args, + authorization_keys, + }) } -} -impl FromBytes for WasmV1Request { - fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (state_hash, bytes) = Digest::from_bytes(bytes)?; - let (protocol_version, bytes) = ProtocolVersion::from_bytes(bytes)?; - let (blocktime, bytes) = BlockTime::from_bytes(bytes)?; - let (transaction, bytes) = Transaction::from_bytes(bytes)?; - let (gas_limit, bytes) = Gas::from_bytes(bytes)?; - let (phase, bytes) = Phase::from_bytes(bytes)?; - Ok(( - WasmV1Request { - state_hash, - protocol_version, - block_time: blocktime, - transaction, - gas_limit, - phase, - }, - bytes, - )) + /// Creates a new request from a deploy item for use as custom payment. + // + // TODO - deprecate? + pub fn new_payment_from_deploy_item( + state_hash: Digest, + block_time: BlockTime, + gas_limit: Gas, + DeployItem { + address, + payment, + authorization_keys, + deploy_hash, + .. + }: DeployItem, + ) -> Result { + let payment_info = PaymentInfo::try_from((payment, deploy_hash))?; + Ok(Self { + state_hash, + block_time, + transaction_hash: TransactionHash::Deploy(deploy_hash), + gas_limit, + initiator_addr: InitiatorAddr::AccountHash(address), + executable_item: payment_info.payment, + entry_point: DEFAULT_ENTRY_POINT.to_string(), + args: payment_info.args, + authorization_keys, + }) } } /// Wasm v1 result. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct WasmV1Result { /// List of transfers that happened during execution. transfers: Vec, @@ -137,8 +239,8 @@ pub struct WasmV1Result { impl WasmV1Result { /// Error, if any. - pub fn error(&self) -> &Option { - &self.error + pub fn error(&self) -> Option<&EngineError> { + self.error.as_ref() } /// List of transfers that happened during execution. @@ -191,19 +293,19 @@ impl WasmV1Result { } /// Failed to transform transaction into an executable item. - pub fn invalid_executable_item(gas_limit: Gas) -> Self { + pub fn invalid_executable_item(gas_limit: Gas, error: InvalidRequest) -> Self { WasmV1Result { transfers: Vec::default(), effects: Effects::new(), messages: Vec::default(), limit: gas_limit, consumed: Gas::zero(), - error: Some(EngineError::InvalidExecutableItem), + error: Some(EngineError::InvalidExecutableItem(error)), } } /// From an execution result. - pub fn execution_result(gas_limit: Gas, execution_result: ExecutionResult) -> Self { + pub fn from_execution_result(gas_limit: Gas, execution_result: ExecutionResult) -> Self { match execution_result { ExecutionResult::Failure { error, @@ -234,4 +336,212 @@ impl WasmV1Result { }, } } + + /// Converts a transfer result to an execution result. + pub fn from_transfer_result(transfer_result: TransferResult, consumed: Gas) -> Option { + match transfer_result { + TransferResult::RootNotFound => None, + TransferResult::Success { transfers, effects } => { + Some(WasmV1Result { + transfers, + limit: consumed, // TODO - check this is legit. + consumed, + effects, + messages: Messages::default(), + error: None, + }) + } + TransferResult::Failure(te) => { + Some(WasmV1Result { + transfers: vec![], + limit: consumed, // TODO - check this is legit. + consumed, + effects: Effects::default(), // currently not returning effects on failure + messages: Messages::default(), + error: Some(EngineError::Transfer(te)), + }) + } + } + } +} + +/// Helper struct to carry the appropriate info for converting an `ExecutableDeployItem` or a +/// `TransactionV1` into the corresponding fields of a `WasmV1Request` for execution as session +/// code. +struct SessionInfo { + session: ExecutableItem, + entry_point: String, + args: RuntimeArgs, +} + +impl TryFrom<(ExecutableDeployItem, DeployHash)> for SessionInfo { + type Error = InvalidRequest; + + fn try_from( + (session_item, deploy_hash): (ExecutableDeployItem, DeployHash), + ) -> Result { + let session: ExecutableItem; + let session_entry_point: String; + let session_args: RuntimeArgs; + match session_item { + ExecutableDeployItem::ModuleBytes { module_bytes, args } => { + session = ExecutableItem::DeploySessionModuleBytes(module_bytes); + session_entry_point = DEFAULT_ENTRY_POINT.to_string(); + session_args = args; + } + ExecutableDeployItem::StoredContractByHash { + hash, + entry_point, + args, + } => { + session = + ExecutableItem::Stored(TransactionInvocationTarget::new_invocable_entity(hash)); + session_entry_point = entry_point; + session_args = args; + } + ExecutableDeployItem::StoredContractByName { + name, + entry_point, + args, + } => { + session = ExecutableItem::Stored( + TransactionInvocationTarget::new_invocable_entity_alias(name), + ); + session_entry_point = entry_point; + session_args = args; + } + ExecutableDeployItem::StoredVersionedContractByHash { + hash, + version, + entry_point, + args, + } => { + session = + ExecutableItem::Stored(TransactionInvocationTarget::new_package(hash, version)); + session_entry_point = entry_point; + session_args = args; + } + ExecutableDeployItem::StoredVersionedContractByName { + name, + version, + entry_point, + args, + } => { + session = ExecutableItem::Stored(TransactionInvocationTarget::new_package_alias( + name, version, + )); + session_entry_point = entry_point; + session_args = args; + } + ExecutableDeployItem::Transfer { .. } => { + return Err(InvalidRequest::InvalidSessionDeployItem(deploy_hash)); + } + } + + Ok(SessionInfo { + session, + entry_point: session_entry_point, + args: session_args, + }) + } +} + +impl TryFrom for SessionInfo { + type Error = InvalidRequest; + + fn try_from(v1_txn: TransactionV1) -> Result { + let (hash, _header, body, _approvals) = v1_txn.destructure(); + let (args, target, entry_point, _scheduling) = body.destructure(); + let session = match target { + TransactionTarget::Native => { + return Err(InvalidRequest::InvalidSessionV1Target(hash)); + } + TransactionTarget::Stored { id, .. } => ExecutableItem::Stored(id), + TransactionTarget::Session { + kind, module_bytes, .. + } => ExecutableItem::SessionModuleBytes { kind, module_bytes }, + }; + + let TransactionEntryPoint::Custom(entry_point) = entry_point else { + return Err(InvalidRequest::InvalidSessionV1EntryPoint(hash)); + }; + + Ok(SessionInfo { + session, + entry_point, + args, + }) + } +} + +/// Helper struct to carry the appropriate info for converting an `ExecutableDeployItem` or a +/// `TransactionV1` into the corresponding fields of a `WasmV1Request` for execution as custom +/// payment. +struct PaymentInfo { + payment: ExecutableItem, + args: RuntimeArgs, +} + +impl TryFrom<(ExecutableDeployItem, DeployHash)> for PaymentInfo { + type Error = InvalidRequest; + + fn try_from( + (payment_item, deploy_hash): (ExecutableDeployItem, DeployHash), + ) -> Result { + match payment_item { + ExecutableDeployItem::ModuleBytes { module_bytes, args } => { + if module_bytes.is_empty() { + return Err(InvalidRequest::EmptyCustomPaymentBytes(deploy_hash)); + } + Ok(PaymentInfo { + payment: ExecutableItem::CustomPayment(module_bytes), + args, + }) + } + ExecutableDeployItem::StoredContractByHash { .. } + | ExecutableDeployItem::StoredContractByName { .. } + | ExecutableDeployItem::StoredVersionedContractByHash { .. } + | ExecutableDeployItem::StoredVersionedContractByName { .. } + | ExecutableDeployItem::Transfer { .. } => { + Err(InvalidRequest::InvalidPaymentDeployItem(deploy_hash)) + } + } + } +} + +impl TryFrom for PaymentInfo { + type Error = InvalidRequest; + + fn try_from(v1_txn: TransactionV1) -> Result { + let (hash, header, body, _approvals) = v1_txn.destructure(); + let (_args, target, _entry_point, _scheduling) = body.destructure(); + // TODO - check this is using the correct value (i.e. we don't need to account for gas_price here). + let payment_amount = match header.pricing_mode() { + PricingMode::Classic { + payment_amount, + standard_payment, + .. + } => { + if *standard_payment { + return Err(InvalidRequest::InvalidPricingMode(hash)); + } + *payment_amount + } + PricingMode::Fixed { .. } | PricingMode::Reserved { .. } => { + return Err(InvalidRequest::InvalidPricingMode(hash)); + } + }; + + let payment = match target { + // TODO - should we also consider the session kind here? + TransactionTarget::Session { module_bytes, .. } => { + ExecutableItem::CustomPayment(module_bytes) + } + TransactionTarget::Native | TransactionTarget::Stored { .. } => { + return Err(InvalidRequest::InvalidSessionV1Target(hash)); + } + }; + let args = runtime_args! { ARG_AMOUNT => U512::from(payment_amount)}; + Ok(PaymentInfo { payment, args }) + } } diff --git a/execution_engine/src/execution/error.rs b/execution_engine/src/execution/error.rs index e4f72e2522..c76a2ef64e 100644 --- a/execution_engine/src/execution/error.rs +++ b/execution_engine/src/execution/error.rs @@ -115,6 +115,9 @@ pub enum Error { #[error("No active contract versions for contract package")] NoActiveEntityVersions(PackageHash), /// Invalid entity version supplied. + #[error("Invalid entity version: {}", _0)] + InvalidEntityVersion(EntityVersionKey), + /// Invalid entity version supplied. #[error("Disabled entity version: {}", _0)] DisabledEntityVersion(EntityVersionKey), /// Invalid entity version supplied. diff --git a/execution_engine_testing/test_support/src/execute_request_builder.rs b/execution_engine_testing/test_support/src/execute_request_builder.rs index ecd57865b5..4fd15c147c 100644 --- a/execution_engine_testing/test_support/src/execute_request_builder.rs +++ b/execution_engine_testing/test_support/src/execute_request_builder.rs @@ -1,99 +1,91 @@ -use std::{collections::BTreeSet, convert::TryFrom, iter}; +use std::collections::BTreeSet; use casper_execution_engine::engine_state::{ - deploy_item::DeployItem, execute_request::ExecuteRequest, Payment, PaymentInfo, Session, - SessionInfo, + deploy_item::DeployItem, ExecutableItem, WasmV1Request, }; use casper_types::{ - account::AccountHash, runtime_args, AddressableEntityHash, BlockTime, DeployHash, Digest, - EntityVersion, InitiatorAddr, PackageHash, PublicKey, RuntimeArgs, TransactionHash, - TransactionV1Hash, + account::AccountHash, runtime_args, AddressableEntityHash, BlockTime, Digest, EntityVersion, + Gas, InitiatorAddr, PackageHash, Phase, RuntimeArgs, TransactionHash, TransactionV1Hash, + DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT, }; -use crate::{ - DeployItemBuilder, ARG_AMOUNT, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, - DEFAULT_BLOCK_TIME, DEFAULT_GAS_PRICE, DEFAULT_PAYMENT, DEFAULT_PROPOSER_PUBLIC_KEY, -}; +use crate::{DeployItemBuilder, ARG_AMOUNT, DEFAULT_BLOCK_TIME, DEFAULT_PAYMENT}; -/// Builds an [`ExecuteRequest`]. +/// Builds a [`WasmV1Request`] for use as session code, and an optional custom payment +/// `WasmV1Request`. #[derive(Debug)] pub struct ExecuteRequestBuilder { state_hash: Digest, block_time: BlockTime, transaction_hash: TransactionHash, - gas_price: u64, initiator_addr: InitiatorAddr, - payment: Payment, - payment_entry_point: String, + payment: Option, + payment_gas_limit: Gas, payment_args: RuntimeArgs, - session: Option, + session: ExecutableItem, + session_gas_limit: Gas, session_entry_point: String, session_args: RuntimeArgs, authorization_keys: BTreeSet, - proposer: PublicKey, -} - -impl Default for ExecuteRequestBuilder { - fn default() -> Self { - ExecuteRequestBuilder { - state_hash: Self::DEFAULT_STATE_HASH, - block_time: BlockTime::new(DEFAULT_BLOCK_TIME), - transaction_hash: Self::DEFAULT_TRANSACTION_HASH, - gas_price: DEFAULT_GAS_PRICE, - initiator_addr: InitiatorAddr::PublicKey(DEFAULT_ACCOUNT_PUBLIC_KEY.clone()), - payment: Self::DEFAULT_PAYMENT, - payment_entry_point: Self::DEFAULT_PAYMENT_ENTRY_POINT.to_string(), - payment_args: runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }, - session: None, - session_entry_point: Self::DEFAULT_SESSION_ENTRY_POINT.to_string(), - session_args: RuntimeArgs::new(), - authorization_keys: iter::once(*DEFAULT_ACCOUNT_ADDR).collect(), - proposer: DEFAULT_PROPOSER_PUBLIC_KEY.clone(), - } - } } impl ExecuteRequestBuilder { - /// The default value used for `ExecuteRequest::state_hash`. + /// The default value used for `WasmV1Request::state_hash`. pub const DEFAULT_STATE_HASH: Digest = Digest::from_raw([1; 32]); - /// The default value used for `ExecuteRequest::transaction_hash`. + /// The default value used for `WasmV1Request::transaction_hash`. pub const DEFAULT_TRANSACTION_HASH: TransactionHash = TransactionHash::V1(TransactionV1Hash::from_raw([2; 32])); - /// The default value used for `ExecuteRequest::payment`. - pub const DEFAULT_PAYMENT: Payment = Payment::Standard; - /// The default value used for `ExecuteRequest::payment_entry_point`. - pub const DEFAULT_PAYMENT_ENTRY_POINT: &'static str = "call"; - /// The default value used for `ExecuteRequest::session_entry_point`. - pub const DEFAULT_SESSION_ENTRY_POINT: &'static str = "call"; - - /// Returns a new `ExecuteRequestBuilder` with default values. - pub fn new() -> Self { - Self::default() - } + /// The default value used for `WasmV1Request::entry_point`. + pub const DEFAULT_ENTRY_POINT: &'static str = "call"; /// Converts a `DeployItem` into an `ExecuteRequestBuilder`. pub fn from_deploy_item(deploy_item: DeployItem) -> Self { - let session_info = - SessionInfo::try_from((deploy_item.session, DeployHash::default())).unwrap(); - let payment_info = - PaymentInfo::try_from((deploy_item.payment, DeployHash::default())).unwrap(); + let authorization_keys = deploy_item.authorization_keys.clone(); + let session = WasmV1Request::new_session_from_deploy_item( + Self::DEFAULT_STATE_HASH, + BlockTime::new(DEFAULT_BLOCK_TIME), + Gas::new(DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT), // TODO - set proper value + deploy_item.clone(), + ) + .unwrap(); + + let payment: Option; + let payment_gas_limit: Gas; + let payment_args: RuntimeArgs; + if deploy_item.payment.is_standard_payment(Phase::Payment) { + payment = None; + payment_gas_limit = Gas::zero(); + payment_args = RuntimeArgs::new(); + } else { + let request = WasmV1Request::new_payment_from_deploy_item( + Self::DEFAULT_STATE_HASH, + BlockTime::new(DEFAULT_BLOCK_TIME), + Gas::new(DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT), // TODO - set proper value + deploy_item, + ) + .unwrap(); + payment = Some(request.executable_item); + payment_gas_limit = request.gas_limit; + payment_args = request.args; + } ExecuteRequestBuilder { - transaction_hash: TransactionHash::Deploy(deploy_item.deploy_hash), - gas_price: deploy_item.gas_price, - initiator_addr: InitiatorAddr::AccountHash(deploy_item.address), - payment: payment_info.payment, - payment_entry_point: payment_info.entry_point, - payment_args: payment_info.args, - session: Some(session_info.session), - session_entry_point: session_info.entry_point, - session_args: session_info.args, - authorization_keys: deploy_item.authorization_keys, - ..Self::default() + state_hash: session.state_hash, + block_time: session.block_time, + transaction_hash: session.transaction_hash, + initiator_addr: session.initiator_addr, + payment, + payment_gas_limit, + payment_args, + session: session.executable_item, + session_gas_limit: session.gas_limit, + session_entry_point: session.entry_point, + session_args: session.args, + authorization_keys, } } - /// Returns an [`ExecuteRequest`] derived from a deploy with standard dependencies. + /// Returns an [`WasmV1Request`] derived from a deploy with standard dependencies. pub fn standard( account_hash: AccountHash, session_file: &str, @@ -110,7 +102,7 @@ impl ExecuteRequestBuilder { Self::from_deploy_item(deploy_item) } - /// Returns an [`ExecuteRequest`] derived from a deploy with session module bytes. + /// Returns an [`WasmV1Request`] derived from a deploy with session module bytes. pub fn module_bytes( account_hash: AccountHash, module_bytes: Vec, @@ -127,7 +119,7 @@ impl ExecuteRequestBuilder { Self::from_deploy_item(deploy_item) } - /// Returns an [`ExecuteRequest`] derived from a deploy with a session item that will call a + /// Returns an [`WasmV1Request`] derived from a deploy with a session item that will call a /// stored contract by hash. pub fn contract_call_by_hash( sender: AccountHash, @@ -144,7 +136,7 @@ impl ExecuteRequestBuilder { Self::from_deploy_item(deploy_item) } - /// Returns an [`ExecuteRequest`] derived from a deploy with a session item that will call a + /// Returns an [`WasmV1Request`] derived from a deploy with a session item that will call a /// stored contract by name. pub fn contract_call_by_name( sender: AccountHash, @@ -161,7 +153,7 @@ impl ExecuteRequestBuilder { Self::from_deploy_item(deploy_item) } - /// Returns an [`ExecuteRequest`] derived from a deploy with a session item that will call a + /// Returns an [`WasmV1Request`] derived from a deploy with a session item that will call a /// versioned stored contract by hash. pub fn versioned_contract_call_by_hash( sender: AccountHash, @@ -184,7 +176,7 @@ impl ExecuteRequestBuilder { Self::from_deploy_item(deploy_item) } - /// Returns an [`ExecuteRequest`] derived from a deploy with a session item that will call a + /// Returns an [`WasmV1Request`] derived from a deploy with a session item that will call a /// versioned stored contract by name. pub fn versioned_contract_call_by_name( sender: AccountHash, @@ -202,42 +194,60 @@ impl ExecuteRequestBuilder { Self::from_deploy_item(deploy_item) } - /// Sets the block time of the [`ExecuteRequest`]. + /// Sets the block time of the [`WasmV1Request`]. pub fn with_block_time(mut self, block_time: u64) -> Self { self.block_time = BlockTime::new(block_time); self } - /// Sets the proposer used by the [`ExecuteRequest`]. - pub fn with_proposer(mut self, proposer: PublicKey) -> Self { - self.proposer = proposer; - self - } - - /// Sets the authorization keys used by the [`ExecuteRequest`]. + /// Sets the authorization keys used by the [`WasmV1Request`]. pub fn with_authorization_keys(mut self, authorization_keys: BTreeSet) -> Self { self.authorization_keys = authorization_keys; self } - /// Consumes self and returns an `ExecuteRequest`. - pub fn build(self) -> ExecuteRequest { - ExecuteRequest { - state_hash: self.state_hash, - block_time: self.block_time, - transaction_hash: self.transaction_hash, - gas_price: self.gas_price, - initiator_addr: self.initiator_addr, - payment: self.payment, - payment_entry_point: self.payment_entry_point, - payment_args: self.payment_args, - session: self - .session - .expect("builder must have been provided with a valid session item"), - session_entry_point: self.session_entry_point, - session_args: self.session_args, - authorization_keys: self.authorization_keys, - proposer: self.proposer, - } + /// Consumes self and returns a session `WasmV1Request` and an optional custom payment + /// `WasmV1Request`. + pub fn build(self) -> (WasmV1Request, Option) { + let ExecuteRequestBuilder { + state_hash, + block_time, + transaction_hash, + initiator_addr, + payment, + payment_gas_limit, + payment_args, + session, + session_gas_limit, + session_entry_point, + session_args, + authorization_keys, + } = self; + + let maybe_payment = payment.map(|executable_item| WasmV1Request { + state_hash, + block_time, + transaction_hash, + gas_limit: payment_gas_limit, + initiator_addr: initiator_addr.clone(), + executable_item, + entry_point: Self::DEFAULT_ENTRY_POINT.to_string(), + args: payment_args, + authorization_keys: authorization_keys.clone(), + }); + + let session = WasmV1Request { + state_hash, + block_time, + transaction_hash, + gas_limit: session_gas_limit, + initiator_addr, + executable_item: session, + entry_point: session_entry_point, + args: session_args, + authorization_keys, + }; + + (session, maybe_payment) } } diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index cdd3f68cf2..f4cd92ffcd 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -17,8 +17,7 @@ use num_traits::{CheckedMul, Zero}; use tempfile::TempDir; use casper_execution_engine::engine_state::{ - execute_request::ExecuteRequest, execution_result::ExecutionResult, Error, ExecutionEngineV1, - DEFAULT_MAX_QUERY_DEPTH, + Error, ExecutionEngineV1, WasmV1Request, WasmV1Result, DEFAULT_MAX_QUERY_DEPTH, }; use casper_storage::{ data_access_layer::{ @@ -126,7 +125,7 @@ pub struct WasmTestBuilder { execution_engine: Rc, /// The chainspec. chainspec: ChainspecConfig, - exec_results: Vec, + exec_results: Vec, upgrade_results: Vec, prune_results: Vec, genesis_hash: Option, @@ -171,7 +170,7 @@ impl WasmTestBuilder { /// Execute and commit transforms from an ExecuteRequest into a scratch global state. /// You MUST call write_scratch_to_lmdb to flush these changes to LmdbGlobalState. #[allow(deprecated)] - pub fn scratch_exec_and_commit(&mut self, mut exec_request: ExecuteRequest) -> &mut Self { + pub fn scratch_exec_and_commit(&mut self, mut exec_request: WasmV1Request) -> &mut Self { if self.scratch_global_state.is_none() { self.scratch_global_state = Some(self.data_access_layer.get_scratch_global_state()); } @@ -184,10 +183,7 @@ impl WasmTestBuilder { exec_request.state_hash = self.post_state_hash.expect("expected post_state_hash"); // First execute the request against our scratch global state. - let execution_result = self - .execution_engine - .exec(cached_state, exec_request) - .unwrap(); + let execution_result = self.execution_engine.execute(cached_state, exec_request); let _post_state_hash = cached_state .commit( self.post_state_hash.expect("requires a post_state_hash"), @@ -558,7 +554,7 @@ impl LmdbWasmTestBuilder { let gas = transfer_request.gas(); let transfer_result = self.data_access_layer.transfer(transfer_request); - let execution_result = ExecutionResult::from_transfer_result(transfer_result, gas).unwrap(); + let execution_result = WasmV1Result::from_transfer_result(transfer_result, gas).unwrap(); let effects = execution_result.effects().clone(); self.effects.push(effects.clone()); self.exec_results.push(execution_result); @@ -819,17 +815,39 @@ where self.data_access_layer().bidding(bidding_req) } - /// Runs an [`ExecuteRequest`]. - #[allow(deprecated)] - pub fn exec(&mut self, mut exec_request: ExecuteRequest) -> &mut Self { - exec_request.state_hash = self.post_state_hash.expect("expected post_state_hash"); - let execution_result = self + /// Runs an optional custom payment [`WasmV1Request`] and a session `WasmV1Request`. + /// + /// If the custom payment is `Some` and its execution fails, the session request is not + /// attempted. + pub fn exec( + &mut self, + mut session: WasmV1Request, + custom_payment: Option, + ) -> &mut Self { + let mut effects = Effects::new(); + if let Some(mut payment) = custom_payment { + payment.state_hash = self.post_state_hash.expect("expected post_state_hash"); + let payment_result = self + .execution_engine + .execute(self.data_access_layer.as_ref(), payment); + // If executing payment code failed, record this and exit without attempting session + // execution. + effects = payment_result.effects().clone(); + let payment_failed = payment_result.error().is_some(); + self.exec_results.push(payment_result); + if payment_failed { + self.effects.push(effects); + return self; + } + } + session.state_hash = self.post_state_hash.expect("expected post_state_hash"); + let session_result = self .execution_engine - .exec(self.data_access_layer.as_ref(), exec_request) - .unwrap(); + .execute(self.data_access_layer.as_ref(), session); // Cache transformations - self.effects.push(execution_result.effects().clone()); - self.exec_results.push(execution_result); + effects.append(session_result.effects().clone()); + self.effects.push(effects); + self.exec_results.push(session_result); self } @@ -882,7 +900,7 @@ where evicted_validators: Vec, ) -> &mut Self { let auction = self.get_auction_contract_hash(); - let run_request = ExecuteRequestBuilder::contract_call_by_hash( + let (session, maybe_payment) = ExecuteRequestBuilder::contract_call_by_hash( *SYSTEM_ADDR, auction, METHOD_RUN_AUCTION, @@ -892,7 +910,7 @@ where }, ) .build(); - self.exec(run_request).expect_success().commit() + self.exec(session, maybe_payment).expect_success().commit() } /// Increments engine state. @@ -999,7 +1017,7 @@ where let exec_result = self .get_last_exec_result() .expect("Expected to be called after exec()"); - if exec_result.is_failure() { + if exec_result.error().is_some() { panic!( "Expected successful execution result, but instead got: {:#?}", exec_result, @@ -1013,7 +1031,7 @@ where let exec_result = self .get_last_exec_result() .expect("Expected to be called after exec()"); - if exec_result.is_success() { + if exec_result.error().is_none() { panic!( "Expected failed execution result, but instead got: {:?}", exec_result, @@ -1027,7 +1045,8 @@ where pub fn is_error(&self) -> bool { self.get_last_exec_result() .expect("Expected to be called after exec()") - .is_failure() + .error() + .is_some() } /// Returns an `engine_state::Error` if the last exec had an error, otherwise `None`. @@ -1035,7 +1054,7 @@ where pub fn get_error(&self) -> Option { self.get_last_exec_result() .expect("Expected to be called after exec()") - .as_error() + .error() .cloned() } @@ -1044,8 +1063,8 @@ where pub fn get_error_message(&self) -> Option { self.get_last_exec_result() .expect("Expected to be called after exec()") - .as_error() - .map(Error::to_string) + .error() + .map(|error| error.to_string()) } /// Gets `Effects` of all previous runs. @@ -1135,12 +1154,12 @@ where } /// Returns the last results execs. - pub fn get_last_exec_result(&self) -> Option { + pub fn get_last_exec_result(&self) -> Option { self.exec_results.last().cloned() } /// Returns the owned results of a specific exec. - pub fn get_exec_result_owned(&self, index: usize) -> Option { + pub fn get_exec_result_owned(&self, index: usize) -> Option { self.exec_results.get(index).cloned() } @@ -1406,13 +1425,16 @@ where pub fn exec_cost(&self, index: usize) -> Gas { self.exec_results .get(index) - .map(ExecutionResult::gas) + .map(WasmV1Result::consumed) .unwrap() } /// Returns the `Gas` cost of the last exec. pub fn last_exec_gas_cost(&self) -> Gas { - self.exec_results.last().map(ExecutionResult::gas).unwrap() + self.exec_results + .last() + .map(WasmV1Result::consumed) + .unwrap() } /// Assert that last error is the expected one. diff --git a/node/src/components/contract_runtime.rs b/node/src/components/contract_runtime.rs index aeb3cd7283..bc98fe7fc0 100644 --- a/node/src/components/contract_runtime.rs +++ b/node/src/components/contract_runtime.rs @@ -63,9 +63,7 @@ use crate::{ NodeRng, }; pub(crate) use config::Config; -pub(crate) use error::{ - BlockExecutionError, ConfigError, ContractRuntimeError, NewUserRequestError, -}; +pub(crate) use error::{BlockExecutionError, ConfigError, ContractRuntimeError}; pub(crate) use event::Event; use exec_queue::{ExecQueue, QueueItem}; use metrics::Metrics; diff --git a/node/src/components/contract_runtime/error.rs b/node/src/components/contract_runtime/error.rs index 0dcdf5b837..0f8d32557a 100644 --- a/node/src/components/contract_runtime/error.rs +++ b/node/src/components/contract_runtime/error.rs @@ -5,17 +5,13 @@ use std::collections::BTreeMap; use serde::Serialize; use thiserror::Error; -use casper_execution_engine::engine_state::{ - Error as EngineStateError, NewRequestError as NewExecuteRequestError, -}; +use casper_execution_engine::engine_state::Error as EngineStateError; use casper_storage::{ - data_access_layer::{ - bidding::InvalidAuctionRuntimeArgs, BlockRewardsError, FeeError, StepError, - }, + data_access_layer::{BlockRewardsError, FeeError, StepError}, global_state::error::Error as GlobalStateError, tracking_copy::TrackingCopyError, }; -use casper_types::{bytesrepr, CLValueError, Digest, PublicKey, TransactionHash, U512}; +use casper_types::{bytesrepr, CLValueError, Digest, PublicKey, U512}; use crate::{ components::contract_runtime::ExecutionPreState, @@ -47,23 +43,6 @@ pub(crate) enum ContractRuntimeError { ChunkingError(#[source] ChunkingError), } -/// Error returned if constructing a new user request fails. -#[derive(Clone, Eq, PartialEq, Error, Serialize, Debug)] -pub enum NewUserRequestError { - /// The transaction is a native one, but the wrapped deploy is not a transfer. - #[error("native transaction of deploy variant is not a transfer")] - ExpectedNativeTransferDeploy(TransactionHash), - /// The transaction is a native version 1 variant, but has a custom entry point. - #[error("cannot use custom variant for entry point in native transaction v1 {0}")] - InvalidEntryPoint(TransactionHash), - /// The transaction is a native auction one, but the runtime args are invalid. - #[error(transparent)] - InvalidAuctionRuntimeArgs(#[from] InvalidAuctionRuntimeArgs), - /// Error constructing a new execution request. - #[error(transparent)] - Execute(#[from] NewExecuteRequestError), -} - /// An error during block execution. #[derive(Debug, Error, Serialize)] pub enum BlockExecutionError { @@ -150,9 +129,6 @@ pub enum BlockExecutionError { /// A root state hash was not found. #[error("Root state hash not found in global state.")] RootNotFound(Digest), - /// An error that occurred while constructing the execution request. - #[error(transparent)] - NewRequest(#[from] NewUserRequestError), /// Missing checksum registry. #[error("Missing checksum registry")] MissingChecksumRegistry, diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index ffccdfede9..f88d729865 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -3,18 +3,15 @@ use std::{collections::BTreeMap, convert::TryInto, sync::Arc, time::Instant}; use itertools::Itertools; use tracing::{debug, error, info, trace, warn}; -use casper_execution_engine::engine_state::{ - self, execution_result::ExecutionResultAndMessages, ExecuteRequest, ExecutionEngineV1, - ExecutionResult as EngineExecutionResult, WasmV1Request, -}; +use casper_execution_engine::engine_state::{ExecutionEngineV1, WasmV1Request, WasmV1Result}; use casper_storage::{ block_store::types::ApprovalsHashes, data_access_layer::{ balance::BalanceHandling, AuctionMethod, BalanceHoldRequest, BalanceIdentifier, - BalanceRequest, BiddingRequest, BiddingResult, BlockRewardsRequest, BlockRewardsResult, - DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, EvictItem, FeeRequest, - FeeResult, FlushRequest, InsufficientBalanceHandling, PruneRequest, PruneResult, - StepRequest, StepResult, TransferRequest, + BalanceRequest, BiddingRequest, BlockRewardsRequest, BlockRewardsResult, DataAccessLayer, + EraValidatorsRequest, EraValidatorsResult, EvictItem, FeeRequest, FeeResult, FlushRequest, + InsufficientBalanceHandling, PruneRequest, PruneResult, StepRequest, StepResult, + TransferRequest, }, global_state::state::{ lmdb::LmdbGlobalState, scratch::ScratchGlobalState, CommitProvider, ScratchProvider, @@ -26,18 +23,16 @@ use casper_types::{ bytesrepr::{self, ToBytes, U32_SERIALIZED_LENGTH}, execution::{Effects, ExecutionResult, TransformKindV2, TransformV2}, system::mint::BalanceHoldAddrTag, - ApprovalsHash, BlockHeader, BlockTime, BlockV2, CLValue, CategorizedTransaction, Chainspec, - ChecksumRegistry, Digest, EraEndV2, EraId, FeeHandling, Gas, GasLimited, Key, Phase, - ProtocolVersion, PublicKey, SystemConfig, Transaction, TransactionCategory, - TransactionEntryPoint, TransactionHash, TransactionHeader, U512, + BlockHeader, BlockTime, BlockV2, CLValue, CategorizedTransaction, Chainspec, ChecksumRegistry, + Digest, EraEndV2, EraId, FeeHandling, Gas, GasLimited, Key, Phase, ProtocolVersion, PublicKey, + Transaction, TransactionCategory, U512, }; use super::{ types::{ExecutionArtifactOutcome, SpeculativeExecutionResult, StepOutcome}, utils::calculate_prune_eras, - BlockAndExecutionArtifacts, BlockExecutionError, ExecutionArtifact, ExecutionArtifacts, - ExecutionPreState, Metrics, NewUserRequestError, APPROVALS_CHECKSUM_NAME, - EXECUTION_RESULTS_CHECKSUM_NAME, + BlockAndExecutionArtifacts, BlockExecutionError, ExecutionArtifacts, ExecutionPreState, + Metrics, APPROVALS_CHECKSUM_NAME, EXECUTION_RESULTS_CHECKSUM_NAME, }; use crate::{ components::fetcher::FetchItem, @@ -88,7 +83,7 @@ pub fn execute_finalized_block( let insufficient_balance_handling = InsufficientBalanceHandling::HoldRemaining; let gas_price = Some(1); // < --TODO: this is where Karan's calculated gas price needs to be used - for txn in &executable_block.transactions { + for txn in executable_block.transactions { let mut effects = Effects::new(); let initiator_addr = txn.initiator_addr(); let txn_hash = txn.hash(); @@ -131,15 +126,17 @@ pub fn execute_finalized_block( // using a multiple of a small value. chainspec.transaction_config.native_transfer_minimum_motes * 5, ); - let pay_request = WasmV1Request::new( + let pay_result = match WasmV1Request::new_custom_payment( state_root_hash, - protocol_version, block_time, - txn, custom_payment_gas_limit, - Phase::Payment, - ); - let pay_result = execution_engine_v1.execute(&scratch_state, pay_request); + txn.clone(), + ) { + Ok(pay_request) => execution_engine_v1.execute(&scratch_state, pay_request), + Err(error) => { + WasmV1Result::invalid_executable_item(custom_payment_gas_limit, error) + } + }; match artifacts.push_wasm_v1_result(txn_hash, txn_header, pay_result) { ExecutionArtifactOutcome::RootNotFound => { return Err(BlockExecutionError::RootNotFound(state_root_hash)) @@ -232,21 +229,23 @@ pub fn execute_finalized_block( } } (TransactionCategory::Standard, _) | (TransactionCategory::InstallUpgrade, _) => { - let wasm_1_request = WasmV1Request::new( + let wasm_v1_result = match WasmV1Request::new_session( state_root_hash, - protocol_version, block_time, - txn, gas_limit, - Phase::Session, - ); - let wasm_1_result = execution_engine_v1.execute(&scratch_state, wasm_1_request); + txn.clone(), + ) { + Ok(wasm_v1_request) => { + execution_engine_v1.execute(&scratch_state, wasm_v1_request) + } + Err(error) => WasmV1Result::invalid_executable_item(gas_limit, error), + }; trace!( %txn_hash, - %wasm_1_result, + ?wasm_v1_result, "transaction execution result" ); - match artifacts.push_wasm_v1_result(txn_hash, txn_header.clone(), wasm_1_result) { + match artifacts.push_wasm_v1_result(txn_hash, txn_header.clone(), wasm_v1_result) { ExecutionArtifactOutcome::RootNotFound => { return Err(BlockExecutionError::RootNotFound(state_root_hash)) } diff --git a/node/src/components/contract_runtime/types.rs b/node/src/components/contract_runtime/types.rs index 43e78ab036..4fab29a3ee 100644 --- a/node/src/components/contract_runtime/types.rs +++ b/node/src/components/contract_runtime/types.rs @@ -1,12 +1,12 @@ use std::{collections::BTreeMap, sync::Arc}; -use casper_execution_engine::engine_state::WasmV1Result; use datasize::DataSize; use serde::Serialize; use thiserror::Error; use tracing::{debug, trace}; -use casper_execution_engine::engine_state::Error as EngineStateError; +use casper_binary_port::ErrorCode as BinaryPortErrorCode; +use casper_execution_engine::engine_state::{Error as EngineStateError, WasmV1Result}; use casper_storage::{ block_store::types::ApprovalsHashes, data_access_layer::{BalanceHoldResult, BiddingResult, EraValidatorsRequest, TransferResult}, @@ -15,12 +15,10 @@ use casper_types::{ contract_messages::Messages, execution::{Effects, ExecutionResult, ExecutionResultV2}, BlockHash, BlockHeaderV2, BlockV2, DeployHash, DeployHeader, Digest, EraId, Gas, InvalidDeploy, - InvalidTransaction, InvalidTransactionV1, ProtocolVersion, PublicKey, Timestamp, Transaction, + InvalidTransaction, InvalidTransactionV1, ProtocolVersion, PublicKey, Transaction, TransactionHash, TransactionHeader, TransactionV1Hash, TransactionV1Header, U512, }; -use crate::contract_runtime::NewUserRequestError; - /// Request for validator weights for a specific era. #[derive(Debug, Clone, PartialEq, Eq)] pub struct ValidatorWeightsByEraIdRequest { @@ -304,7 +302,7 @@ impl ExecutionArtifacts { self.artifacts.push(execution_artifact); } - pub fn execution_results(&self) -> impl Iterator { + pub fn execution_results(&self) -> impl Iterator + Clone { self.artifacts .iter() .map(|artifact| &artifact.execution_result) @@ -468,9 +466,9 @@ impl ExecutionPreState { #[derive(Debug, Error)] pub enum SpeculativeExecutionError { - /// An error that occurred while constructing the execution request. - #[error(transparent)] - NewRequest(#[from] NewUserRequestError), + // /// An error that occurred while constructing the execution request. + // #[error(transparent)] + // NewRequest(#[from] NewUserRequestError), /// An error that occurred while constructing the execution request. #[error(transparent)] EngineState(#[from] EngineStateError), @@ -479,13 +477,13 @@ pub enum SpeculativeExecutionError { NativeNotSupported, } -impl From for binary_port::ErrorCode { +impl From for BinaryPortErrorCode { fn from(error: SpeculativeExecutionError) -> Self { match error { - SpeculativeExecutionError::NewRequest(_) => binary_port::ErrorCode::InvalidTransaction, + // SpeculativeExecutionError::NewRequest(_) => BinaryPortErrorCode::InvalidTransaction, SpeculativeExecutionError::EngineState(error) => error.into(), SpeculativeExecutionError::NativeNotSupported => { - binary_port::ErrorCode::UnsupportedRequest + BinaryPortErrorCode::UnsupportedRequest } } } diff --git a/node/src/effect.rs b/node/src/effect.rs index 102c2ef3c3..c3d0d7465d 100644 --- a/node/src/effect.rs +++ b/node/src/effect.rs @@ -144,7 +144,7 @@ use crate::{ TrieAccumulatorResponse, }, consensus::{ClContext, EraDump, ProposedBlock}, - contract_runtime::{SpeculativeExecutionError, SpeculativeExecutionResult}, + contract_runtime::SpeculativeExecutionResult, diagnostics_port::StopAtSpec, fetcher::{FetchItem, FetchResult}, gossiper::GossipItem, diff --git a/node/src/effect/requests.rs b/node/src/effect/requests.rs index fb7aac1979..a281ff94f7 100644 --- a/node/src/effect/requests.rs +++ b/node/src/effect/requests.rs @@ -45,7 +45,7 @@ use crate::{ TrieAccumulatorResponse, }, consensus::{ClContext, ProposedBlock}, - contract_runtime::{SpeculativeExecutionError, SpeculativeExecutionResult}, + contract_runtime::SpeculativeExecutionResult, diagnostics_port::StopAtSpec, fetcher::{FetchItem, FetchResult}, gossiper::GossipItem, From c0a904d527b5f05b266cf77ef9bdce920a854447 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Wed, 20 Mar 2024 00:46:53 -0700 Subject: [PATCH 24/70] more tweaks --- Cargo.lock | 2 - binary_port/Cargo.toml | 2 - binary_port/src/binary_response.rs | 8 +- .../src/binary_response_and_request.rs | 14 +-- binary_port/src/error_code.rs | 15 --- binary_port/src/lib.rs | 4 + binary_port/src/payload_type.rs | 7 +- binary_port/src/raw_bytes_spec.rs | 44 ++++++++ .../src}/record_id.rs | 0 .../src/speculative_execution_result.rs | 39 +++---- execution_engine/src/runtime/mint_internal.rs | 20 ++-- execution_engine/src/runtime/mod.rs | 74 ++++++------ node/src/components/binary_port.rs | 22 ++-- node/src/components/binary_port/tests.rs | 33 +++++- .../components/contract_runtime/operations.rs | 5 +- node/src/components/contract_runtime/types.rs | 2 +- node/src/components/contract_runtime/utils.rs | 21 +++- node/src/components/storage.rs | 13 ++- node/src/components/storage/error.rs | 6 +- node/src/components/storage/utils.rs | 16 +++ node/src/effect.rs | 20 ++-- node/src/effect/requests.rs | 20 ++-- .../reactor/main_reactor/tests/binary_port.rs | 3 +- .../lmdb/indexed_lmdb_block_store.rs | 27 ++--- storage/src/block_store/lmdb/mod.rs | 105 ++++++++++++++++++ .../block_store/lmdb/versioned_databases.rs | 8 +- storage/src/block_store/mod.rs | 2 - storage/src/lib.rs | 5 +- storage/src/system/mint/mint_native.rs | 79 ++++++------- storage/src/system/mint/system_provider.rs | 10 ++ types/src/transaction/pricing_mode.rs | 2 +- 31 files changed, 418 insertions(+), 210 deletions(-) create mode 100644 binary_port/src/raw_bytes_spec.rs rename {storage/src/block_store => binary_port/src}/record_id.rs (100%) create mode 100644 node/src/components/storage/utils.rs diff --git a/Cargo.lock b/Cargo.lock index a3479c55f8..d1c9a988e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -472,8 +472,6 @@ name = "casper-binary-port" version = "1.0.0" dependencies = [ "bincode", - "casper-execution-engine", - "casper-storage", "casper-types", "once_cell", "rand", diff --git a/binary_port/Cargo.toml b/binary_port/Cargo.toml index 8697a9838e..058181cae4 100644 --- a/binary_port/Cargo.toml +++ b/binary_port/Cargo.toml @@ -11,8 +11,6 @@ license = "Apache-2.0" exclude = ["proptest-regressions"] [dependencies] -casper-execution-engine = { version = "6.0.0", path = "../execution_engine" } -casper-storage = { version = "1.4.3", path = "../storage" } casper-types = { version = "3.0.0", path = "../types", features = ["datasize", "json-schema", "std"] } serde = { version = "1.0.183", features = ["derive"] } thiserror = "1.0.45" diff --git a/binary_port/src/binary_response.rs b/binary_port/src/binary_response.rs index 9b1043bbe7..49d02cedad 100644 --- a/binary_port/src/binary_response.rs +++ b/binary_port/src/binary_response.rs @@ -1,4 +1,3 @@ -use casper_storage::{block_store::record_id::RecordId, DbRawBytesSpec}; use casper_types::{ bytesrepr::{self, Bytes, FromBytes, ToBytes}, ProtocolVersion, @@ -10,6 +9,7 @@ use crate::{ payload_type::{PayloadEntity, PayloadType}, }; +use crate::{raw_bytes_spec::RawBytesSpec, record_id::RecordId}; #[cfg(test)] use casper_types::testing::TestRng; @@ -39,10 +39,10 @@ impl BinaryResponse { } } - /// Creates new binary response from raw DB bytes. - pub fn from_db_raw_bytes( + /// Creates new binary response from raw bytes. + pub fn from_raw_bytes( record_id: RecordId, - spec: Option, + spec: Option, protocol_version: ProtocolVersion, ) -> Self { match spec { diff --git a/binary_port/src/binary_response_and_request.rs b/binary_port/src/binary_response_and_request.rs index 3a497d7065..f1c988bc9f 100644 --- a/binary_port/src/binary_response_and_request.rs +++ b/binary_port/src/binary_response_and_request.rs @@ -1,11 +1,11 @@ -use casper_storage::{block_store::record_id::RecordId, DbRawBytesSpec}; use casper_types::{ bytesrepr::{self, Bytes, FromBytes, ToBytes}, ProtocolVersion, }; -use crate::{binary_response::BinaryResponse, payload_type::PayloadEntity}; +use crate::{binary_response::BinaryResponse, payload_type::PayloadEntity, RawBytesSpec}; +use crate::record_id::RecordId; #[cfg(test)] use casper_types::testing::TestRng; @@ -33,9 +33,9 @@ impl BinaryResponseAndRequest { data: &A, protocol_version: ProtocolVersion, ) -> BinaryResponseAndRequest { - let response = BinaryResponse::from_db_raw_bytes( + let response = BinaryResponse::from_raw_bytes( record_id, - Some(DbRawBytesSpec::new_current(&data.to_bytes().unwrap())), + Some(RawBytesSpec::new_current(&data.to_bytes().unwrap())), protocol_version, ); Self::new(response, &[]) @@ -47,11 +47,9 @@ impl BinaryResponseAndRequest { data: &A, protocol_version: ProtocolVersion, ) -> BinaryResponseAndRequest { - let response = BinaryResponse::from_db_raw_bytes( + let response = BinaryResponse::from_raw_bytes( record_id, - Some(DbRawBytesSpec::new_legacy( - &bincode::serialize(data).unwrap(), - )), + Some(RawBytesSpec::new_legacy(&bincode::serialize(data).unwrap())), protocol_version, ); Self::new(response, &[]) diff --git a/binary_port/src/error_code.rs b/binary_port/src/error_code.rs index c17bdef487..96acd26cea 100644 --- a/binary_port/src/error_code.rs +++ b/binary_port/src/error_code.rs @@ -1,6 +1,5 @@ use core::{convert::TryFrom, fmt}; -use casper_execution_engine::engine_state::Error as EngineError; use casper_types::InvalidTransaction; /// The error code indicating the result of handling the binary request. @@ -83,20 +82,6 @@ impl fmt::Display for UnknownErrorCode { impl std::error::Error for UnknownErrorCode {} -impl From for ErrorCode { - fn from(err: EngineError) -> Self { - match err { - EngineError::RootNotFound(_) => ErrorCode::RootNotFound, - EngineError::Deploy => ErrorCode::InvalidTransaction, - EngineError::InvalidItemVariant(_) => ErrorCode::InvalidItemVariant, - EngineError::WasmPreprocessing(_) => ErrorCode::WasmPreprocessing, - EngineError::InvalidProtocolVersion(_) => ErrorCode::UnsupportedProtocolVersion, - EngineError::Deprecated(_) => ErrorCode::FunctionDisabled, - _ => ErrorCode::InternalError, - } - } -} - impl From for ErrorCode { fn from(_value: InvalidTransaction) -> Self { ErrorCode::InvalidTransaction diff --git a/binary_port/src/lib.rs b/binary_port/src/lib.rs index 80093c7c61..0af78b33a2 100644 --- a/binary_port/src/lib.rs +++ b/binary_port/src/lib.rs @@ -11,6 +11,8 @@ mod information_request; mod minimal_block_info; mod node_status; mod payload_type; +mod raw_bytes_spec; +pub mod record_id; mod speculative_execution_result; mod state_request; mod type_wrappers; @@ -26,6 +28,8 @@ pub use information_request::{InformationRequest, InformationRequestTag}; pub use minimal_block_info::MinimalBlockInfo; pub use node_status::NodeStatus; pub use payload_type::{PayloadEntity, PayloadType}; +pub use raw_bytes_spec::RawBytesSpec; +pub use record_id::{RecordId, UnknownRecordId}; pub use speculative_execution_result::SpeculativeExecutionResult; pub use state_request::GlobalStateRequest; pub use type_wrappers::{ diff --git a/binary_port/src/payload_type.rs b/binary_port/src/payload_type.rs index 5e535e6ffa..501c223d15 100644 --- a/binary_port/src/payload_type.rs +++ b/binary_port/src/payload_type.rs @@ -6,8 +6,7 @@ use schemars::JsonSchema; #[cfg(test)] use rand::Rng; -use casper_execution_engine::engine_state::WasmV1Result; -use casper_storage::block_store::record_id::RecordId; +use crate::record_id::RecordId; use core::{convert::TryFrom, fmt}; #[cfg(test)] @@ -419,10 +418,6 @@ impl PayloadEntity for BlockSignaturesV1 { const PAYLOAD_TYPE: PayloadType = PayloadType::BlockSignaturesV1; } -impl PayloadEntity for WasmV1Result { - const PAYLOAD_TYPE: PayloadType = PayloadType::WasmV1Result; -} - impl PayloadEntity for ExecutionResult { const PAYLOAD_TYPE: PayloadType = PayloadType::ExecutionResult; } diff --git a/binary_port/src/raw_bytes_spec.rs b/binary_port/src/raw_bytes_spec.rs new file mode 100644 index 0000000000..296a19f14b --- /dev/null +++ b/binary_port/src/raw_bytes_spec.rs @@ -0,0 +1,44 @@ +pub use crate::record_id::{RecordId, UnknownRecordId}; + +/// Stores raw bytes along with the flag indicating whether data is in a legacy format or not. +#[derive(Debug)] +pub struct RawBytesSpec { + is_legacy: bool, + raw_bytes: Vec, +} + +impl RawBytesSpec { + /// Creates an instance of the appropriate variant. + pub fn new(raw_bytes: &[u8], is_legacy: bool) -> Self { + Self { + is_legacy, + raw_bytes: raw_bytes.to_vec(), + } + } + + /// Creates a variant indicating that raw bytes are coming from a legacy source. + pub fn new_legacy(raw_bytes: &[u8]) -> Self { + Self { + is_legacy: true, + raw_bytes: raw_bytes.to_vec(), + } + } + + /// Creates a variant indicating that raw bytes are coming from the current database. + pub fn new_current(raw_bytes: &[u8]) -> Self { + Self { + is_legacy: false, + raw_bytes: raw_bytes.to_vec(), + } + } + + /// Is legacy? + pub fn is_legacy(&self) -> bool { + self.is_legacy + } + + /// Raw bytes. + pub fn raw_bytes(&self) -> Vec { + self.raw_bytes.clone() + } +} diff --git a/storage/src/block_store/record_id.rs b/binary_port/src/record_id.rs similarity index 100% rename from storage/src/block_store/record_id.rs rename to binary_port/src/record_id.rs diff --git a/binary_port/src/speculative_execution_result.rs b/binary_port/src/speculative_execution_result.rs index 23d60e9c53..9d179f98e6 100644 --- a/binary_port/src/speculative_execution_result.rs +++ b/binary_port/src/speculative_execution_result.rs @@ -1,4 +1,3 @@ -use casper_execution_engine::engine_state::WasmV1Result; use casper_types::{ bytesrepr, bytesrepr::{FromBytes, ToBytes}, @@ -23,6 +22,26 @@ pub struct SpeculativeExecutionResult { error: Option, } +impl SpeculativeExecutionResult { + pub fn new( + transfers: Vec, + limit: Gas, + consumed: Gas, + effects: Effects, + messages: Messages, + error: Option, + ) -> Self { + SpeculativeExecutionResult { + transfers, + limit, + consumed, + effects, + messages, + error, + } + } +} + impl From for SpeculativeExecutionResult { fn from(invalid_transaction: InvalidTransaction) -> Self { SpeculativeExecutionResult { @@ -36,24 +55,6 @@ impl From for SpeculativeExecutionResult { } } -impl From for SpeculativeExecutionResult { - fn from(wasm_v1_result: WasmV1Result) -> Self { - let error = wasm_v1_result - .error() - .as_ref() - .map(|err| format!("{}", err)); - - SpeculativeExecutionResult { - transfers: wasm_v1_result.transfers().to_owned(), - limit: wasm_v1_result.limit(), - consumed: wasm_v1_result.consumed(), - effects: wasm_v1_result.effects().to_owned(), - messages: wasm_v1_result.messages().to_owned(), - error, - } - } -} - impl ToBytes for SpeculativeExecutionResult { fn to_bytes(&self) -> Result, bytesrepr::Error> { let mut buffer = bytesrepr::allocate_buffer(self)?; diff --git a/execution_engine/src/runtime/mint_internal.rs b/execution_engine/src/runtime/mint_internal.rs index 8709f79318..d3dff596c1 100644 --- a/execution_engine/src/runtime/mint_internal.rs +++ b/execution_engine/src/runtime/mint_internal.rs @@ -170,16 +170,18 @@ where { fn record_transfer( &mut self, - maybe_to: Option, - source: URef, - target: URef, - amount: U512, - id: Option, + _maybe_to: Option, + _source: URef, + _target: URef, + _amount: U512, + _id: Option, ) -> Result<(), Error> { - let result = Runtime::record_transfer(self, maybe_to, source, target, amount, id); - result.map_err(|exec_error| { - >::from(exec_error).unwrap_or(Error::RecordTransferFailure) - }) + Ok(()) + + // let result = Runtime::record_transfer(self, maybe_to, source, target, amount, id); + // result.map_err(|exec_error| { + // >::from(exec_error).unwrap_or(Error::RecordTransferFailure) + // }) } } diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index a77527fb38..b2a18bbde7 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -53,8 +53,7 @@ use casper_types::{ CLValue, ContextAccessRights, ContractWasm, EntityAddr, EntityKind, EntityVersion, EntityVersionKey, EntityVersions, Gas, GrantedAccess, Group, Groups, HostFunction, HostFunctionCost, Key, NamedArg, Package, PackageHash, Phase, PublicKey, RuntimeArgs, - StoredValue, Tagged, Transfer, TransferResult, TransferredTo, URef, - DICTIONARY_ITEM_KEY_MAX_LENGTH, U512, + StoredValue, Tagged, TransferResult, TransferredTo, URef, DICTIONARY_ITEM_KEY_MAX_LENGTH, U512, }; use crate::{ @@ -2100,43 +2099,44 @@ where /// Records a transfer. fn record_transfer( &mut self, - maybe_to: Option, - source: URef, - target: URef, - amount: U512, - id: Option, + _maybe_to: Option, + _source: URef, + _target: URef, + _amount: U512, + _id: Option, ) -> Result<(), ExecError> { - if self.context.get_entity_key() != self.context.get_system_entity_key(MINT)? { - return Err(ExecError::InvalidContext); - } - - if self.context.phase() != Phase::Session { - return Ok(()); - } - - let transfer_addr = self.context.new_transfer_addr()?; - let transfer = { - let transaction_hash = self.context.get_transaction_hash(); - let from: AccountHash = self.context.get_caller(); - let fee: U512 = U512::zero(); // TODO - Transfer::new( - transaction_hash, - from, - maybe_to, - source, - target, - amount, - fee, - id, - ) - }; - { - let transfers = self.context.transfers_mut(); - transfers.push(transfer_addr); - } - self.context - .write_transfer(Key::Transfer(transfer_addr), transfer); Ok(()) + // if self.context.get_entity_key() != self.context.get_system_entity_key(MINT)? { + // return Err(ExecError::InvalidContext); + // } + // + // if self.context.phase() != Phase::Session { + // return Ok(()); + // } + // + // let transfer_addr = self.context.new_transfer_addr()?; + // let transfer = { + // let transaction_hash = self.context.get_transaction_hash(); + // let from: AccountHash = self.context.get_caller(); + // let fee: U512 = U512::zero(); // TODO + // Transfer::new( + // transaction_hash, + // from, + // maybe_to, + // source, + // target, + // amount, + // fee, + // id, + // ) + // }; + // { + // let transfers = self.context.transfers_mut(); + // transfers.push(transfer_addr); + // } + // self.context + // .write_transfer(Key::Transfer(transfer_addr), transfer); + // Ok(()) } /// Records given auction info at a given era id diff --git a/node/src/components/binary_port.rs b/node/src/components/binary_port.rs index e9ad3510c0..c409e57f72 100644 --- a/node/src/components/binary_port.rs +++ b/node/src/components/binary_port.rs @@ -12,8 +12,8 @@ use bytes::Bytes; use casper_binary_port::{ BinaryRequest, BinaryRequestHeader, BinaryRequestTag, BinaryResponse, BinaryResponseAndRequest, ErrorCode, GetRequest, GetTrieFullResult, GlobalStateQueryResult, GlobalStateRequest, - InformationRequest, InformationRequestTag, NodeStatus, ReactorStateName, - TransactionWithExecutionInfo, + InformationRequest, InformationRequestTag, NodeStatus, RawBytesSpec, ReactorStateName, + RecordId, TransactionWithExecutionInfo, }; use casper_storage::{ data_access_layer::{ @@ -21,7 +21,6 @@ use casper_storage::{ QueryRequest, QueryResult, TrieRequest, }, global_state::trie::TrieRaw, - DbRawBytesSpec, RecordId, }; use casper_types::{ bytesrepr::{self, FromBytes, ToBytes}, @@ -188,8 +187,8 @@ where let Ok(serialized) = bincode::serialize(&transfers) else { return BinaryResponse::new_error(ErrorCode::InternalError, protocol_version); }; - let bytes = DbRawBytesSpec::new_current(&serialized); - BinaryResponse::from_db_raw_bytes(RecordId::Transfer, Some(bytes), protocol_version) + let bytes = RawBytesSpec::new_current(&serialized); + BinaryResponse::from_raw_bytes(RecordId::Transfer, Some(bytes), protocol_version) } GetRequest::Record { record_type_tag, @@ -199,7 +198,7 @@ where match RecordId::try_from(record_type_tag) { Ok(record_id) => { let maybe_raw_bytes = effect_builder.get_raw_data(record_id, key).await; - BinaryResponse::from_db_raw_bytes(record_id, maybe_raw_bytes, protocol_version) + BinaryResponse::from_raw_bytes(record_id, maybe_raw_bytes, protocol_version) } Err(_) => { BinaryResponse::new_error(ErrorCode::UnsupportedRequest, protocol_version) @@ -222,7 +221,6 @@ where } } } - async fn handle_get_all_items( state_identifier: Option, key_tag: casper_types::KeyTag, @@ -546,13 +544,9 @@ where SpeculativeExecutionResult::InvalidTransaction(ite) => { BinaryResponse::new_error(ite.into(), protocol_version) } - SpeculativeExecutionResult::WasmV1(v1) => match v1.error() { - Some(_) => BinaryResponse::new_error(ErrorCode::InternalError, protocol_version), - None => BinaryResponse::from_value( - casper_binary_port::SpeculativeExecutionResult::from(v1), - protocol_version, - ), - }, + SpeculativeExecutionResult::WasmV1(spec_exec_result) => { + BinaryResponse::from_value(spec_exec_result, protocol_version) + } } } diff --git a/node/src/components/binary_port/tests.rs b/node/src/components/binary_port/tests.rs index b2ca2ebf54..de46072c9d 100644 --- a/node/src/components/binary_port/tests.rs +++ b/node/src/components/binary_port/tests.rs @@ -6,7 +6,10 @@ use serde::Serialize; use casper_binary_port::{BinaryRequest, BinaryResponse, GetRequest, GlobalStateRequest}; -use casper_types::{Digest, GlobalStateIdentifier, KeyTag, Transaction, TransactionV1Builder}; +use casper_types::{ + BlockHeader, Digest, GlobalStateIdentifier, KeyTag, Timestamp, Transaction, + TransactionV1Builder, +}; use crate::{ components::binary_port::event::Event as BinaryPortEvent, @@ -54,7 +57,7 @@ struct TestCase { } #[tokio::test] -async fn should_execute_enabled_functions() { +async fn should_enqueue_requests_for_enabled_functions() { let mut rng = TestRng::new(); let get_all_values_enabled = TestCase { @@ -258,6 +261,25 @@ impl Reactor for MockReactor { Effects::new() } Event::AcceptTransactionRequest(req) => req.responder.respond(Ok(())).ignore(), + Event::StorageRequest(StorageRequest::GetHighestCompleteBlockHeader { responder }) => { + let block_header_v2 = casper_types::BlockHeaderV2::new( + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Timestamp::now(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + ); + responder + .respond(Some(BlockHeader::V2(block_header_v2))) + .ignore() + } + Event::StorageRequest(req) => panic!("unexpected storage req {}", req), } } } @@ -283,6 +305,7 @@ enum Event { ReactorInfoRequest(ReactorInfoRequest), #[from] AcceptTransactionRequest(AcceptTransactionRequest), + StorageRequest(StorageRequest), } impl From for Event { @@ -317,8 +340,7 @@ impl From for Event { impl From for Event { fn from(request: StorageRequest) -> Self { - println!("{}", request); - unreachable!() + Event::StorageRequest(request) } } @@ -336,6 +358,9 @@ impl Display for Event { Event::AcceptTransactionRequest(request) => { write!(formatter, "accept transaction request: {:?}", request) } + Event::StorageRequest(request) => { + write!(formatter, "storage request: {:?}", request) + } } } } diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 8bb59144b1..8d61bf1663 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -38,6 +38,7 @@ use crate::{ }, contract_runtime::{ types::{ExecutionArtifactOutcome, SpeculativeExecutionResult}, + utils, utils::calculate_prune_eras, }, types::{self, Chunkable, ExecutableBlock, InternalEraReport}, @@ -699,7 +700,9 @@ where gas_limit, Phase::Session, ); - SpeculativeExecutionResult::WasmV1(execution_engine_v1.execute(state_provider, request)) + let result = execution_engine_v1.execute(state_provider, request); + let spec_exec = utils::spec_exec_from_wasm_v1_result(result); + SpeculativeExecutionResult::WasmV1(spec_exec) } #[allow(clippy::too_many_arguments)] diff --git a/node/src/components/contract_runtime/types.rs b/node/src/components/contract_runtime/types.rs index 6429a31342..2adc33eb28 100644 --- a/node/src/components/contract_runtime/types.rs +++ b/node/src/components/contract_runtime/types.rs @@ -385,7 +385,7 @@ pub struct BlockAndExecutionArtifacts { #[derive(Debug)] pub enum SpeculativeExecutionResult { InvalidTransaction(InvalidTransaction), - WasmV1(WasmV1Result), + WasmV1(casper_binary_port::SpeculativeExecutionResult), } impl SpeculativeExecutionResult { diff --git a/node/src/components/contract_runtime/utils.rs b/node/src/components/contract_runtime/utils.rs index f8591a0bde..eba5352771 100644 --- a/node/src/components/contract_runtime/utils.rs +++ b/node/src/components/contract_runtime/utils.rs @@ -14,16 +14,17 @@ use crate::{ types::{ExecutableBlock, MetaBlock, MetaBlockState}, }; -use casper_execution_engine::engine_state::ExecutionEngineV1; +use casper_binary_port::SpeculativeExecutionResult; +use casper_execution_engine::engine_state::{ExecutionEngineV1, WasmV1Result}; use casper_storage::{ data_access_layer::DataAccessLayer, global_state::state::lmdb::LmdbGlobalState, }; use casper_types::{Chainspec, EraId, Key}; use once_cell::sync::Lazy; -use std::fmt::Debug; use std::{ cmp, collections::{BTreeMap, HashMap}, + fmt::Debug, ops::Range, sync::{Arc, Mutex}, }; @@ -297,6 +298,22 @@ pub(super) fn calculate_prune_eras( Some(range.map(EraId::new).map(Key::EraInfo).collect()) } +pub(crate) fn spec_exec_from_wasm_v1_result( + wasm_v1_result: WasmV1Result, +) -> SpeculativeExecutionResult { + let transfers = wasm_v1_result.transfers().to_owned(); + let limit = wasm_v1_result.limit().to_owned(); + let consumed = wasm_v1_result.consumed().to_owned(); + let effects = wasm_v1_result.effects().to_owned(); + let messages = wasm_v1_result.messages().to_owned(); + let error_msg = wasm_v1_result + .error() + .to_owned() + .map(|err| format!("{:?}", err)); + + SpeculativeExecutionResult::new(transfers, limit, consumed, effects, messages, error_msg) +} + #[cfg(test)] mod tests { use super::*; diff --git a/node/src/components/storage.rs b/node/src/components/storage.rs index b2ebadf3bb..7f6d290ca6 100644 --- a/node/src/components/storage.rs +++ b/node/src/components/storage.rs @@ -38,6 +38,7 @@ mod metrics; mod object_pool; #[cfg(test)] mod tests; +mod utils; use casper_storage::block_store::{ lmdb::{IndexedLmdbBlockStore, LmdbBlockStore}, @@ -978,9 +979,17 @@ impl Storage { responder, record_id, } => { + let db_table_id = utils::db_table_id_from_record_id(record_id) + .map_err(|_| FatalStorageError::UnexpectedRecordId(record_id))?; let txn = self.block_store.checkout_ro()?; - let maybe_data: Option = txn.read((record_id, key))?; - responder.respond(maybe_data).ignore() + let maybe_data: Option = txn.read((db_table_id, key))?; + match maybe_data { + None => responder.respond(None).ignore(), + Some(db_raw) => { + let raw_bytes_spec = utils::raw_bytes_from_db_raw_bytes(db_raw); + responder.respond(Some(raw_bytes_spec)).ignore() + } + } } }) } diff --git a/node/src/components/storage/error.rs b/node/src/components/storage/error.rs index 1a0cd88a1d..7a7531d4d0 100644 --- a/node/src/components/storage/error.rs +++ b/node/src/components/storage/error.rs @@ -1,5 +1,6 @@ use std::{fmt::Debug, io, path::PathBuf}; +use casper_binary_port::RecordId; use thiserror::Error; use tracing::error; @@ -9,7 +10,7 @@ use casper_types::{ }; use crate::types::VariantMismatch; -use casper_storage::{block_store::BlockStoreError, RecordId}; +use casper_storage::block_store::BlockStoreError; /// A fatal storage component error. /// @@ -179,6 +180,9 @@ pub enum FatalStorageError { /// BlockStoreError #[error(transparent)] BlockStoreError(#[from] BlockStoreError), + /// BlockStoreError + #[error("unexpected record id {0}")] + UnexpectedRecordId(RecordId), } impl From> for FatalStorageError { diff --git a/node/src/components/storage/utils.rs b/node/src/components/storage/utils.rs new file mode 100644 index 0000000000..d46082ec62 --- /dev/null +++ b/node/src/components/storage/utils.rs @@ -0,0 +1,16 @@ +use casper_binary_port::{RawBytesSpec, RecordId}; +use casper_storage::{DbRawBytesSpec, DbTableId, UnknownDbTableId}; +use std::convert::TryFrom; + +pub(crate) fn db_table_id_from_record_id( + record_id: RecordId, +) -> Result { + DbTableId::try_from(record_id as u16) +} + +pub(crate) fn raw_bytes_from_db_raw_bytes(db_raw_bytes_spec: DbRawBytesSpec) -> RawBytesSpec { + RawBytesSpec::new( + &db_raw_bytes_spec.raw_bytes(), + db_raw_bytes_spec.is_legacy(), + ) +} diff --git a/node/src/effect.rs b/node/src/effect.rs index c6ae7e57e5..3e0c279cdd 100644 --- a/node/src/effect.rs +++ b/node/src/effect.rs @@ -115,17 +115,15 @@ use tokio::{sync::Semaphore, time}; use tracing::{debug, error, warn}; use casper_binary_port::{ - ConsensusStatus, ConsensusValidatorChanges, LastProgress, NetworkName, Uptime, + ConsensusStatus, ConsensusValidatorChanges, LastProgress, NetworkName, RawBytesSpec, RecordId, + Uptime, }; -use casper_storage::{ - data_access_layer::{ - tagged_values::{TaggedValuesRequest, TaggedValuesResult}, - AddressableEntityResult, BalanceRequest, BalanceResult, EraValidatorsRequest, - EraValidatorsResult, ExecutionResultsChecksumResult, PutTrieRequest, PutTrieResult, - QueryRequest, QueryResult, RoundSeigniorageRateRequest, RoundSeigniorageRateResult, - TotalSupplyRequest, TotalSupplyResult, TrieRequest, TrieResult, - }, - DbRawBytesSpec, RecordId, +use casper_storage::data_access_layer::{ + tagged_values::{TaggedValuesRequest, TaggedValuesResult}, + AddressableEntityResult, BalanceRequest, BalanceResult, EraValidatorsRequest, + EraValidatorsResult, ExecutionResultsChecksumResult, PutTrieRequest, PutTrieResult, + QueryRequest, QueryResult, RoundSeigniorageRateRequest, RoundSeigniorageRateResult, + TotalSupplyRequest, TotalSupplyResult, TrieRequest, TrieResult, }; use casper_types::{ execution::{Effects as ExecutionEffects, ExecutionResult}, @@ -1171,7 +1169,7 @@ impl EffectBuilder { self, record_id: RecordId, key: Vec, - ) -> Option + ) -> Option where REv: From, { diff --git a/node/src/effect/requests.rs b/node/src/effect/requests.rs index fc32aaa09f..ff0daee092 100644 --- a/node/src/effect/requests.rs +++ b/node/src/effect/requests.rs @@ -16,17 +16,15 @@ use smallvec::SmallVec; use static_assertions::const_assert; use casper_binary_port::{ - ConsensusStatus, ConsensusValidatorChanges, LastProgress, NetworkName, Uptime, + ConsensusStatus, ConsensusValidatorChanges, LastProgress, NetworkName, RawBytesSpec, RecordId, + Uptime, }; -use casper_storage::{ - data_access_layer::{ - tagged_values::{TaggedValuesRequest, TaggedValuesResult}, - AddressableEntityResult, BalanceRequest, BalanceResult, EraValidatorsRequest, - EraValidatorsResult, ExecutionResultsChecksumResult, PutTrieRequest, PutTrieResult, - QueryRequest, QueryResult, RoundSeigniorageRateRequest, RoundSeigniorageRateResult, - TotalSupplyRequest, TotalSupplyResult, TrieRequest, TrieResult, - }, - DbRawBytesSpec, RecordId, +use casper_storage::data_access_layer::{ + tagged_values::{TaggedValuesRequest, TaggedValuesResult}, + AddressableEntityResult, BalanceRequest, BalanceResult, EraValidatorsRequest, + EraValidatorsResult, ExecutionResultsChecksumResult, PutTrieRequest, PutTrieResult, + QueryRequest, QueryResult, RoundSeigniorageRateRequest, RoundSeigniorageRateResult, + TotalSupplyRequest, TotalSupplyResult, TrieRequest, TrieResult, }; use casper_types::{ execution::ExecutionResult, Approval, AvailableBlockRange, Block, BlockHash, BlockHeader, @@ -340,7 +338,7 @@ pub(crate) enum StorageRequest { key: Vec, /// Responder to call with the result. Returns `None` if the data doesn't exist in /// local storage. - responder: Responder>, + responder: Responder>, }, GetBlockHeaderByHeight { /// Height of block to get header of. diff --git a/node/src/reactor/main_reactor/tests/binary_port.rs b/node/src/reactor/main_reactor/tests/binary_port.rs index 6de6e0584e..154bfac289 100644 --- a/node/src/reactor/main_reactor/tests/binary_port.rs +++ b/node/src/reactor/main_reactor/tests/binary_port.rs @@ -4,9 +4,8 @@ use casper_binary_port::{ BinaryRequest, BinaryRequestHeader, BinaryResponse, BinaryResponseAndRequest, ConsensusStatus, ConsensusValidatorChanges, ErrorCode, GetRequest, GetTrieFullResult, GlobalStateQueryResult, GlobalStateRequest, InformationRequest, InformationRequestTag, LastProgress, NetworkName, - NodeStatus, PayloadType, ReactorStateName, Uptime, + NodeStatus, PayloadType, ReactorStateName, RecordId, Uptime, }; -use casper_storage::RecordId; use casper_types::{ bytesrepr::{FromBytes, ToBytes}, testing::TestRng, diff --git a/storage/src/block_store/lmdb/indexed_lmdb_block_store.rs b/storage/src/block_store/lmdb/indexed_lmdb_block_store.rs index 7b4cefa3a2..fe0d4c3d28 100644 --- a/storage/src/block_store/lmdb/indexed_lmdb_block_store.rs +++ b/storage/src/block_store/lmdb/indexed_lmdb_block_store.rs @@ -3,7 +3,9 @@ use std::{ collections::{btree_map, hash_map::Entry, BTreeMap, BTreeSet, HashMap, HashSet}, }; -use super::{lmdb_block_store::LmdbBlockStore, lmdb_ext::LmdbExtError, temp_map::TempMap}; +use super::{ + lmdb_block_store::LmdbBlockStore, lmdb_ext::LmdbExtError, temp_map::TempMap, DbTableId, +}; use datasize::DataSize; use lmdb::{ Environment, RoTransaction, RwCursor, RwTransaction, Transaction as LmdbTransaction, WriteFlags, @@ -14,7 +16,6 @@ use tracing::info; use super::versioned_databases::VersionedDatabases; use crate::block_store::{ block_provider::{BlockStoreTransaction, DataReader, DataWriter}, - record_id::RecordId, types::{ ApprovalsHashes, BlockExecutionResults, BlockHashHeightAndEra, BlockHeight, BlockTransfers, LatestSwitchBlock, StateStore, StateStoreKey, Tip, TransactionFinalizedApprovals, @@ -883,34 +884,34 @@ impl<'a> DataReader> for IndexedLmdbBlockStoreReadTransac } } -impl<'a> DataReader<(RecordId, Vec), DbRawBytesSpec> +impl<'a> DataReader<(DbTableId, Vec), DbRawBytesSpec> for IndexedLmdbBlockStoreReadTransaction<'a> { fn read( &self, - (id, key): (RecordId, Vec), + (id, key): (DbTableId, Vec), ) -> Result, BlockStoreError> { let store = &self.block_store.block_store; let res = match id { - RecordId::BlockHeader => store.block_header_dbs.get_raw(&self.txn, &key), - RecordId::BlockBody => store.block_body_dbs.get_raw(&self.txn, &key), - RecordId::ApprovalsHashes => store.approvals_hashes_dbs.get_raw(&self.txn, &key), - RecordId::BlockMetadata => store.block_metadata_dbs.get_raw(&self.txn, &key), - RecordId::Transaction => store.transaction_dbs.get_raw(&self.txn, &key), - RecordId::ExecutionResult => store.execution_result_dbs.get_raw(&self.txn, &key), - RecordId::Transfer => match self.txn.get(store.transfer_db, &key) { + DbTableId::BlockHeader => store.block_header_dbs.get_raw(&self.txn, &key), + DbTableId::BlockBody => store.block_body_dbs.get_raw(&self.txn, &key), + DbTableId::ApprovalsHashes => store.approvals_hashes_dbs.get_raw(&self.txn, &key), + DbTableId::BlockMetadata => store.block_metadata_dbs.get_raw(&self.txn, &key), + DbTableId::Transaction => store.transaction_dbs.get_raw(&self.txn, &key), + DbTableId::ExecutionResult => store.execution_result_dbs.get_raw(&self.txn, &key), + DbTableId::Transfer => match self.txn.get(store.transfer_db, &key) { Ok(bytes) => Ok(Some(DbRawBytesSpec::new_legacy(bytes))), Err(lmdb::Error::NotFound) => Ok(None), Err(err) => return Err(BlockStoreError::InternalStorage(Box::new(err))), }, - RecordId::FinalizedTransactionApprovals => store + DbTableId::FinalizedTransactionApprovals => store .finalized_transaction_approvals_dbs .get_raw(&self.txn, &key), }; res.map_err(|err| BlockStoreError::InternalStorage(Box::new(err))) } - fn exists(&mut self, key: (RecordId, Vec)) -> Result { + fn exists(&mut self, key: (DbTableId, Vec)) -> Result { self.read(key).map(|res| res.is_some()) } } diff --git a/storage/src/block_store/lmdb/mod.rs b/storage/src/block_store/lmdb/mod.rs index c045886b2d..30ea9429fa 100644 --- a/storage/src/block_store/lmdb/mod.rs +++ b/storage/src/block_store/lmdb/mod.rs @@ -5,5 +5,110 @@ mod versioned_databases; mod indexed_lmdb_block_store; mod lmdb_block_store; +use core::convert::TryFrom; pub use indexed_lmdb_block_store::IndexedLmdbBlockStore; pub use lmdb_block_store::LmdbBlockStore; + +#[cfg(test)] +use rand::Rng; +use serde::Serialize; + +#[cfg(test)] +use casper_types::testing::TestRng; + +/// An identifier of db tables. +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)] +#[repr(u16)] +pub enum DbTableId { + /// Refers to `BlockHeader` db table. + BlockHeader = 0, + /// Refers to `BlockBody` db table. + BlockBody = 1, + /// Refers to `ApprovalsHashes` db table. + ApprovalsHashes = 2, + /// Refers to `BlockMetadata` db table. + BlockMetadata = 3, + /// Refers to `Transaction` db table. + Transaction = 4, + /// Refers to `ExecutionResult` db table. + ExecutionResult = 5, + /// Refers to `Transfer` db table. + Transfer = 6, + /// Refers to `FinalizedTransactionApprovals` db table. + FinalizedTransactionApprovals = 7, +} + +impl DbTableId { + #[cfg(test)] + pub fn random(rng: &mut TestRng) -> Self { + match rng.gen_range(0..8) { + 0 => DbTableId::BlockHeader, + 1 => DbTableId::BlockBody, + 2 => DbTableId::ApprovalsHashes, + 3 => DbTableId::BlockMetadata, + 4 => DbTableId::Transaction, + 5 => DbTableId::ExecutionResult, + 6 => DbTableId::Transfer, + 7 => DbTableId::FinalizedTransactionApprovals, + _ => unreachable!(), + } + } +} + +impl TryFrom for DbTableId { + type Error = UnknownDbTableId; + + fn try_from(value: u16) -> Result { + match value { + 0 => Ok(DbTableId::BlockHeader), + 1 => Ok(DbTableId::BlockBody), + 2 => Ok(DbTableId::ApprovalsHashes), + 3 => Ok(DbTableId::BlockMetadata), + 4 => Ok(DbTableId::Transaction), + 5 => Ok(DbTableId::ExecutionResult), + 6 => Ok(DbTableId::Transfer), + 7 => Ok(DbTableId::FinalizedTransactionApprovals), + _ => Err(UnknownDbTableId(value)), + } + } +} + +impl From for u16 { + fn from(value: DbTableId) -> Self { + value as u16 + } +} + +impl core::fmt::Display for DbTableId { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + DbTableId::BlockHeader => write!(f, "BlockHeader"), + DbTableId::BlockBody => write!(f, "BlockBody"), + DbTableId::ApprovalsHashes => write!(f, "ApprovalsHashes"), + DbTableId::BlockMetadata => write!(f, "BlockMetadata"), + DbTableId::Transaction => write!(f, "Transaction"), + DbTableId::ExecutionResult => write!(f, "ExecutionResult"), + DbTableId::Transfer => write!(f, "Transfer"), + DbTableId::FinalizedTransactionApprovals => write!(f, "FinalizedTransactionApprovals"), + } + } +} + +/// Error returned when trying to convert a `u16` into a `DbTableId`. +#[derive(Debug, PartialEq, Eq)] +pub struct UnknownDbTableId(u16); + +#[cfg(test)] +mod tests { + use super::*; + use casper_types::testing::TestRng; + + #[test] + fn tag_roundtrip() { + let rng = &mut TestRng::new(); + + let val = DbTableId::random(rng); + let tag = u16::from(val); + assert_eq!(DbTableId::try_from(tag), Ok(val)); + } +} diff --git a/storage/src/block_store/lmdb/versioned_databases.rs b/storage/src/block_store/lmdb/versioned_databases.rs index 8cd291f53c..0865e8de4e 100644 --- a/storage/src/block_store/lmdb/versioned_databases.rs +++ b/storage/src/block_store/lmdb/versioned_databases.rs @@ -16,9 +16,11 @@ use casper_types::{ }; use super::lmdb_ext::{self, LmdbExtError, TransactionExt, WriteTransactionExt}; -use crate::block_store::{ - error::BlockStoreError, - types::{ApprovalsHashes, DeployMetadataV1, LegacyApprovalsHashes}, +use crate::{ + block_store::{ + error::BlockStoreError, + types::{ApprovalsHashes, DeployMetadataV1, LegacyApprovalsHashes}, + }, DbRawBytesSpec, }; diff --git a/storage/src/block_store/mod.rs b/storage/src/block_store/mod.rs index 4779e3e175..3c22de98a7 100644 --- a/storage/src/block_store/mod.rs +++ b/storage/src/block_store/mod.rs @@ -1,12 +1,10 @@ mod block_provider; mod error; pub mod lmdb; -pub mod record_id; pub mod types; pub use block_provider::{BlockStoreProvider, BlockStoreTransaction, DataReader, DataWriter}; pub use error::BlockStoreError; -pub use record_id::{RecordId, UnknownRecordId}; /// Stores raw bytes from the DB along with the flag indicating whether data come from legacy or /// current version of the DB. diff --git a/storage/src/lib.rs b/storage/src/lib.rs index 734b405b8e..71c7918515 100644 --- a/storage/src/lib.rs +++ b/storage/src/lib.rs @@ -18,7 +18,10 @@ pub mod tracking_copy; pub use address_generator::{AddressGenerator, AddressGeneratorBuilder}; pub use tracking_copy::TrackingCopy; -pub use block_store::{DbRawBytesSpec, RecordId, UnknownRecordId}; +pub use block_store::{ + lmdb::{DbTableId, UnknownDbTableId}, + DbRawBytesSpec, +}; #[cfg(test)] pub use self::tracking_copy::new_temporary_tracking_copy; diff --git a/storage/src/system/mint/mint_native.rs b/storage/src/system/mint/mint_native.rs index 1b1aba9d04..decbb20bb6 100644 --- a/storage/src/system/mint/mint_native.rs +++ b/storage/src/system/mint/mint_native.rs @@ -8,7 +8,7 @@ use crate::{ runtime_provider::RuntimeProvider, storage_provider::StorageProvider, system_provider::SystemProvider, Mint, }, - runtime_native::{Id, RuntimeNative}, + runtime_native::RuntimeNative, }, tracking_copy::{TrackingCopyEntityExt, TrackingCopyExt}, }; @@ -17,7 +17,7 @@ use casper_types::{ bytesrepr::{FromBytes, ToBytes}, system::{mint::Error, Caller}, AccessRights, AddressableEntity, CLTyped, CLValue, Key, Phase, PublicKey, StoredValue, - SystemEntityRegistry, Transfer, TransferAddr, URef, U512, + SystemEntityRegistry, URef, U512, }; impl RuntimeProvider for RuntimeNative @@ -208,45 +208,46 @@ where { fn record_transfer( &mut self, - maybe_to: Option, - source: URef, - target: URef, - amount: U512, - id: Option, + _maybe_to: Option, + _source: URef, + _target: URef, + _amount: U512, + _id: Option, ) -> Result<(), Error> { - if self.phase() != Phase::Session { - return Ok(()); - } - let transaction_hash = match self.id() { - Id::Transaction(transaction_hash) => *transaction_hash, - // we don't write transfer records for systemic transfers (step, fees, rewards, etc) - // so return Ok and move on. - Id::Seed(_) => return Ok(()), - }; - - let transfer_addr = TransferAddr::new(self.address_generator().create_address()); - let key = Key::Transfer(transfer_addr); // <-- a new key variant needed to deal w/ versioned transaction hash - //let transaction_hash = self.transaction_hash(); - let transfer = { - let from: AccountHash = self.get_caller(); - let fee: U512 = U512::zero(); - Transfer::new( - transaction_hash, - from, - maybe_to, - source, - target, - amount, - fee, - id, - ) - }; - self.push_transfer(transfer_addr); - - self.tracking_copy() - .borrow_mut() - .write(key, StoredValue::Transfer(transfer)); Ok(()) + // if self.phase() != Phase::Session { + // return Ok(()); + // } + // let transaction_hash = match self.id() { + // Id::Transaction(transaction_hash) => *transaction_hash, + // // we don't write transfer records for systemic transfers (step, fees, rewards, etc) + // // so return Ok and move on. + // Id::Seed(_) => return Ok(()), + // }; + // + // let transfer_addr = TransferAddr::new(self.address_generator().create_address()); + // let key = Key::Transfer(transfer_addr); // <-- a new key variant needed to deal w/ + // versioned transaction hash //let + // transaction_hash = self.transaction_hash(); let transfer = { + // let from: AccountHash = self.get_caller(); + // let fee: U512 = U512::zero(); + // Transfer::new( + // transaction_hash, + // from, + // maybe_to, + // source, + // target, + // amount, + // fee, + // id, + // ) + // }; + // self.push_transfer(transfer_addr); + // + // self.tracking_copy() + // .borrow_mut() + // .write(key, StoredValue::Transfer(transfer)); + // Ok(()) } } diff --git a/storage/src/system/mint/system_provider.rs b/storage/src/system/mint/system_provider.rs index 64922f7247..627d77ec6b 100644 --- a/storage/src/system/mint/system_provider.rs +++ b/storage/src/system/mint/system_provider.rs @@ -2,6 +2,16 @@ use casper_types::{account::AccountHash, system::mint::Error, URef, U512}; /// Provides functionality of a system module. pub trait SystemProvider { + /* TODO: record_transfer:: writing Deploy / TransactionInfo and Transfer records to global state + is not sustainable as such records are never pruned away, causing the width of a + slice of global state at tip to unnecessarily grow as they accrete over time. + Instead, this salient details can be recored in the transaction meta data that we + already store ... currently a vec of TransferAddr is stored. Going forward we would + just store the record itself in the metadata. That metadata is already wired up + to be synchronized, chunked, etc. + In the meantime, until that can be wired up, disabling the storing of these records. + */ + /// Records a transfer. fn record_transfer( &mut self, diff --git a/types/src/transaction/pricing_mode.rs b/types/src/transaction/pricing_mode.rs index 0dfa3d7e60..eb82d9ec0c 100644 --- a/types/src/transaction/pricing_mode.rs +++ b/types/src/transaction/pricing_mode.rs @@ -37,7 +37,7 @@ pub enum PricingMode { Classic { /// User-specified payment amount. payment_amount: u64, - /// User-specified gas_price tolerance (minimum 1). + /// User-specified gas_price (minimum 1). gas_price: u64, /// Standard payment. standard_payment: bool, From 214eb1fae7e6eadcf8b356b3b41d6c6c6f866e62 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Wed, 20 Mar 2024 11:30:56 +0000 Subject: [PATCH 25/70] resolve compiler errors after merge --- .../src/engine_state/execution_result.rs | 5 +- execution_engine/src/engine_state/wasm_v1.rs | 13 +- .../src/execute_request_builder.rs | 78 ++++++- .../test_support/src/lib.rs | 2 +- .../test_support/src/utils.rs | 6 +- .../test_support/src/wasm_test_builder.rs | 21 +- .../contract_api/account/authorized_keys.rs | 12 +- .../test/contract_api/add_contract_version.rs | 21 +- .../tests/src/test/contract_api/dictionary.rs | 14 +- .../src/test/contract_api/get_call_stack.rs | 7 +- .../tests/src/test/contract_api/transfer.rs | 6 +- .../tests/src/test/contract_messages.rs | 20 +- .../tests/src/test/deploy/receipts.rs | 8 +- .../tests/src/test/deploy/stored_contracts.rs | 2 +- .../tests/src/test/explorer/faucet.rs | 2 +- .../src/test/explorer/faucet_test_helpers.rs | 5 +- .../tests/src/test/gas_counter.rs | 2 +- .../tests/src/test/groups.rs | 14 +- .../private_chain/burn_fees_and_refund.rs | 20 +- .../test/private_chain/fees_accumulation.rs | 36 +-- .../src/test/private_chain/management.rs | 7 +- .../tests/src/test/regression/ee_1129.rs | 16 +- .../tests/src/test/regression/ee_1160.rs | 6 +- .../tests/src/test/regression/ee_1163.rs | 2 +- .../tests/src/test/regression/ee_1174.rs | 2 +- .../tests/src/test/regression/ee_532.rs | 2 +- .../tests/src/test/regression/ee_771.rs | 2 +- .../tests/src/test/regression/ee_966.rs | 23 +- .../tests/src/test/regression/gh_1470.rs | 12 +- .../tests/src/test/regression/gh_1688.rs | 5 +- .../tests/src/test/regression/gh_1902.rs | 10 +- ...host_function_metrics_size_and_gas_cost.rs | 9 +- .../test/regression/regression_20210707.rs | 11 +- .../src/test/system_contracts/auction/bids.rs | 10 +- .../test/system_contracts/auction_bidding.rs | 2 +- .../test/system_contracts/standard_payment.rs | 16 +- .../tests/src/test/system_costs.rs | 2 +- .../tests/src/test/wasmless_transfer.rs | 4 +- node/src/components/contract_runtime.rs | 8 +- .../components/contract_runtime/operations.rs | 214 +++++++++--------- node/src/components/contract_runtime/utils.rs | 2 +- node/src/components/storage/tests.rs | 9 +- resources/test/sse_data_schema.json | 9 +- storage/src/data_access_layer/bidding.rs | 69 ++++-- types/src/block_time.rs | 8 +- types/src/lib.rs | 10 +- types/src/transaction/deploy.rs | 6 +- 47 files changed, 421 insertions(+), 349 deletions(-) diff --git a/execution_engine/src/engine_state/execution_result.rs b/execution_engine/src/engine_state/execution_result.rs index f1623524e5..a29c5b55b6 100644 --- a/execution_engine/src/engine_state/execution_result.rs +++ b/execution_engine/src/engine_state/execution_result.rs @@ -4,7 +4,7 @@ use std::collections::VecDeque; use tracing::{debug, trace}; -use casper_storage::data_access_layer::{BiddingResult, TransferResult}; +use casper_storage::data_access_layer::BiddingResult; use casper_types::{ bytesrepr::FromBytes, contract_messages::Messages, @@ -15,8 +15,7 @@ use casper_types::{ use super::Error; use crate::execution::ExecError; -/// Represents the result of an execution specified by -/// [`crate::engine_state::ExecuteRequest`]. +/// Represents the result of an execution. #[derive(Clone, Debug)] pub enum ExecutionResult { /// An error condition that happened during execution diff --git a/execution_engine/src/engine_state/wasm_v1.rs b/execution_engine/src/engine_state/wasm_v1.rs index 390011b592..5887486210 100644 --- a/execution_engine/src/engine_state/wasm_v1.rs +++ b/execution_engine/src/engine_state/wasm_v1.rs @@ -193,7 +193,7 @@ impl WasmV1Request { /// Creates a new request from a deploy item for use as custom payment. // // TODO - deprecate? - pub fn new_payment_from_deploy_item( + pub fn new_custom_payment_from_deploy_item( state_hash: Digest, block_time: BlockTime, gas_limit: Gas, @@ -304,6 +304,14 @@ impl WasmV1Result { } } + /// Returns `true` if this is a precondition failure. + /// + /// Precondition variant is further described as an execution failure which does not have any + /// effects, and has a gas cost of 0. + pub fn has_precondition_failure(&self) -> bool { + self.error.is_some() && self.consumed == Gas::zero() && self.effects.is_empty() + } + /// From an execution result. pub fn from_execution_result(gas_limit: Gas, execution_result: ExecutionResult) -> Self { match execution_result { @@ -515,7 +523,8 @@ impl TryFrom for PaymentInfo { fn try_from(v1_txn: TransactionV1) -> Result { let (hash, header, body, _approvals) = v1_txn.destructure(); let (_args, target, _entry_point, _scheduling) = body.destructure(); - // TODO - check this is using the correct value (i.e. we don't need to account for gas_price here). + // TODO - check this is using the correct value (i.e. we don't need to account for gas_price + // here). let payment_amount = match header.pricing_mode() { PricingMode::Classic { payment_amount, diff --git a/execution_engine_testing/test_support/src/execute_request_builder.rs b/execution_engine_testing/test_support/src/execute_request_builder.rs index 4fd15c147c..e9ead4d9e1 100644 --- a/execution_engine_testing/test_support/src/execute_request_builder.rs +++ b/execution_engine_testing/test_support/src/execute_request_builder.rs @@ -5,14 +5,22 @@ use casper_execution_engine::engine_state::{ }; use casper_types::{ account::AccountHash, runtime_args, AddressableEntityHash, BlockTime, Digest, EntityVersion, - Gas, InitiatorAddr, PackageHash, Phase, RuntimeArgs, TransactionHash, TransactionV1Hash, - DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT, + Gas, InitiatorAddr, PackageHash, Phase, RuntimeArgs, Transaction, TransactionHash, + TransactionV1Hash, DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT, }; use crate::{DeployItemBuilder, ARG_AMOUNT, DEFAULT_BLOCK_TIME, DEFAULT_PAYMENT}; -/// Builds a [`WasmV1Request`] for use as session code, and an optional custom payment -/// `WasmV1Request`. +/// A request comprising a [`WasmV1Request`] for use as session code, and an optional custom +/// payment `WasmV1Request`. +pub struct ExecuteRequest { + /// The session request. + pub session: WasmV1Request, + /// The optional custom payment request. + pub custom_payment: Option, +} + +/// Builds an [`ExecuteRequest`]. #[derive(Debug)] pub struct ExecuteRequestBuilder { state_hash: Digest, @@ -38,6 +46,53 @@ impl ExecuteRequestBuilder { /// The default value used for `WasmV1Request::entry_point`. pub const DEFAULT_ENTRY_POINT: &'static str = "call"; + /// Converts a `Transaction` into an `ExecuteRequestBuilder`. + pub fn from_transaction(txn: Transaction) -> Self { + let authorization_keys = txn.authorization_keys(); + let session = WasmV1Request::new_session( + Self::DEFAULT_STATE_HASH, + BlockTime::new(DEFAULT_BLOCK_TIME), + Gas::new(DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT), // TODO - set proper value + txn.clone(), + ) + .unwrap(); + + let payment: Option; + let payment_gas_limit: Gas; + let payment_args: RuntimeArgs; + if txn.is_standard_payment() { + payment = None; + payment_gas_limit = Gas::zero(); + payment_args = RuntimeArgs::new(); + } else { + let request = WasmV1Request::new_custom_payment( + Self::DEFAULT_STATE_HASH, + BlockTime::new(DEFAULT_BLOCK_TIME), + Gas::new(DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT), // TODO - set proper value + txn, + ) + .unwrap(); + payment = Some(request.executable_item); + payment_gas_limit = request.gas_limit; + payment_args = request.args; + } + + ExecuteRequestBuilder { + state_hash: session.state_hash, + block_time: session.block_time, + transaction_hash: session.transaction_hash, + initiator_addr: session.initiator_addr, + payment, + payment_gas_limit, + payment_args, + session: session.executable_item, + session_gas_limit: session.gas_limit, + session_entry_point: session.entry_point, + session_args: session.args, + authorization_keys, + } + } + /// Converts a `DeployItem` into an `ExecuteRequestBuilder`. pub fn from_deploy_item(deploy_item: DeployItem) -> Self { let authorization_keys = deploy_item.authorization_keys.clone(); @@ -57,7 +112,7 @@ impl ExecuteRequestBuilder { payment_gas_limit = Gas::zero(); payment_args = RuntimeArgs::new(); } else { - let request = WasmV1Request::new_payment_from_deploy_item( + let request = WasmV1Request::new_custom_payment_from_deploy_item( Self::DEFAULT_STATE_HASH, BlockTime::new(DEFAULT_BLOCK_TIME), Gas::new(DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT), // TODO - set proper value @@ -195,8 +250,8 @@ impl ExecuteRequestBuilder { } /// Sets the block time of the [`WasmV1Request`]. - pub fn with_block_time(mut self, block_time: u64) -> Self { - self.block_time = BlockTime::new(block_time); + pub fn with_block_time>(mut self, block_time: T) -> Self { + self.block_time = block_time.into(); self } @@ -208,7 +263,7 @@ impl ExecuteRequestBuilder { /// Consumes self and returns a session `WasmV1Request` and an optional custom payment /// `WasmV1Request`. - pub fn build(self) -> (WasmV1Request, Option) { + pub fn build(self) -> ExecuteRequest { let ExecuteRequestBuilder { state_hash, block_time, @@ -224,7 +279,7 @@ impl ExecuteRequestBuilder { authorization_keys, } = self; - let maybe_payment = payment.map(|executable_item| WasmV1Request { + let maybe_custom_payment = payment.map(|executable_item| WasmV1Request { state_hash, block_time, transaction_hash, @@ -248,6 +303,9 @@ impl ExecuteRequestBuilder { authorization_keys, }; - (session, maybe_payment) + ExecuteRequest { + session, + custom_payment: maybe_custom_payment, + } } } diff --git a/execution_engine_testing/test_support/src/lib.rs b/execution_engine_testing/test_support/src/lib.rs index ad5afc5b62..b3e7707ad0 100644 --- a/execution_engine_testing/test_support/src/lib.rs +++ b/execution_engine_testing/test_support/src/lib.rs @@ -31,7 +31,7 @@ use casper_types::{ pub use chainspec_config::ChainspecConfig; use chainspec_config::PRODUCTION_PATH; pub use deploy_item_builder::DeployItemBuilder; -pub use execute_request_builder::ExecuteRequestBuilder; +pub use execute_request_builder::{ExecuteRequest, ExecuteRequestBuilder}; pub use step_request_builder::StepRequestBuilder; pub use transfer_request_builder::TransferRequestBuilder; pub use upgrade_request_builder::UpgradeRequestBuilder; diff --git a/execution_engine_testing/test_support/src/utils.rs b/execution_engine_testing/test_support/src/utils.rs index 4f497b819a..87b6031e43 100644 --- a/execution_engine_testing/test_support/src/utils.rs +++ b/execution_engine_testing/test_support/src/utils.rs @@ -7,7 +7,7 @@ use std::{ use once_cell::sync::Lazy; -use casper_execution_engine::engine_state::{execution_result::ExecutionResult, Error}; +use casper_execution_engine::engine_state::{Error, WasmV1Result}; use casper_storage::data_access_layer::GenesisRequest; use casper_types::{bytesrepr::Bytes, GenesisAccount, GenesisConfig, GenesisConfigBuilder}; @@ -163,10 +163,10 @@ pub fn create_run_genesis_request(accounts: Vec) -> GenesisReque /// # Panics /// * Panics if the result does not have a precondition failure. /// * Panics if result.as_error() is `None`. -pub fn get_precondition_failure(exec_result: &ExecutionResult) -> &Error { +pub fn get_precondition_failure(exec_result: &WasmV1Result) -> &Error { assert!( exec_result.has_precondition_failure(), "should be a precondition failure" ); - exec_result.as_error().expect("should have an error") + exec_result.error().expect("should have an error") } diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index f4cd92ffcd..8a8aebd269 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -69,8 +69,8 @@ use casper_types::{ use crate::{ chainspec_config::{ChainspecConfig, PRODUCTION_PATH}, - ExecuteRequestBuilder, StepRequestBuilder, DEFAULT_GAS_PRICE, DEFAULT_PROPOSER_ADDR, - DEFAULT_PROTOCOL_VERSION, SYSTEM_ADDR, + ExecuteRequest, ExecuteRequestBuilder, StepRequestBuilder, DEFAULT_GAS_PRICE, + DEFAULT_PROPOSER_ADDR, DEFAULT_PROTOCOL_VERSION, SYSTEM_ADDR, }; /// LMDB initial map size is calculated based on DEFAULT_LMDB_PAGES and systems page size. @@ -819,13 +819,9 @@ where /// /// If the custom payment is `Some` and its execution fails, the session request is not /// attempted. - pub fn exec( - &mut self, - mut session: WasmV1Request, - custom_payment: Option, - ) -> &mut Self { + pub fn exec(&mut self, mut execute_request: ExecuteRequest) -> &mut Self { let mut effects = Effects::new(); - if let Some(mut payment) = custom_payment { + if let Some(mut payment) = execute_request.custom_payment { payment.state_hash = self.post_state_hash.expect("expected post_state_hash"); let payment_result = self .execution_engine @@ -840,10 +836,11 @@ where return self; } } - session.state_hash = self.post_state_hash.expect("expected post_state_hash"); + execute_request.session.state_hash = + self.post_state_hash.expect("expected post_state_hash"); let session_result = self .execution_engine - .execute(self.data_access_layer.as_ref(), session); + .execute(self.data_access_layer.as_ref(), execute_request.session); // Cache transformations effects.append(session_result.effects().clone()); self.effects.push(effects); @@ -900,7 +897,7 @@ where evicted_validators: Vec, ) -> &mut Self { let auction = self.get_auction_contract_hash(); - let (session, maybe_payment) = ExecuteRequestBuilder::contract_call_by_hash( + let exec_request = ExecuteRequestBuilder::contract_call_by_hash( *SYSTEM_ADDR, auction, METHOD_RUN_AUCTION, @@ -910,7 +907,7 @@ where }, ) .build(); - self.exec(session, maybe_payment).expect_success().commit() + self.exec(exec_request).expect_success().commit() } /// Increments engine state. diff --git a/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs b/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs index ff3808436f..f39bdc5498 100644 --- a/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs +++ b/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs @@ -81,7 +81,7 @@ fn should_raise_auth_failure_with_invalid_key() { "{:?}", deploy_result ); - let message = format!("{}", deploy_result.as_error().unwrap()); + let message = format!("{}", deploy_result.error().unwrap()); assert_eq!( message, @@ -130,7 +130,7 @@ fn should_raise_auth_failure_with_invalid_keys() { .expect("should have exec response"); assert!(deploy_result.has_precondition_failure()); - let message = format!("{}", deploy_result.as_error().unwrap()); + let message = format!("{}", deploy_result.error().unwrap()); assert_eq!( message, @@ -229,7 +229,7 @@ fn should_raise_deploy_authorization_failure() { .expect("should have exec response"); assert!(deploy_result.has_precondition_failure()); - let message = format!("{}", deploy_result.as_error().unwrap()); + let message = format!("{}", deploy_result.error().unwrap()); assert!(message.contains(&format!("{}", ExecError::DeploymentAuthorizationFailure))) } let exec_request_6 = { @@ -285,7 +285,7 @@ fn should_raise_deploy_authorization_failure() { .expect("should have exec response"); assert!(deploy_result.has_precondition_failure()); - let message = format!("{}", deploy_result.as_error().unwrap()); + let message = format!("{}", deploy_result.error().unwrap()); assert!(message.contains(&format!("{}", ExecError::DeploymentAuthorizationFailure))) } @@ -448,7 +448,7 @@ fn should_not_authorize_deploy_with_duplicated_keys() { "{:?}", deploy_result ); - let message = format!("{}", deploy_result.as_error().unwrap()); + let message = format!("{}", deploy_result.error().unwrap()); assert!(message.contains(&format!( "{}", TrackingCopyError::DeploymentAuthorizationFailure @@ -514,7 +514,7 @@ fn should_not_authorize_transfer_without_deploy_key_threshold() { let response = builder .get_exec_result_owned(3) .expect("should have response"); - let error = response.as_error().expect("should have error"); + let error = response.error().expect("should have error"); assert!(matches!( error, Error::Transfer(TransferError::TrackingCopy( diff --git a/execution_engine_testing/tests/src/test/contract_api/add_contract_version.rs b/execution_engine_testing/tests/src/test/contract_api/add_contract_version.rs index a5fcc833f5..cd4e9d5a90 100644 --- a/execution_engine_testing/tests/src/test/contract_api/add_contract_version.rs +++ b/execution_engine_testing/tests/src/test/contract_api/add_contract_version.rs @@ -1,20 +1,15 @@ use casper_engine_test_support::{ utils, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_ACCOUNT_SECRET_KEY, DEFAULT_PROPOSER_PUBLIC_KEY, LOCAL_GENESIS_REQUEST, -}; -use casper_execution_engine::{ - engine_state::{Error as StateError, ExecuteRequest}, - execution::ExecError, + DEFAULT_ACCOUNT_SECRET_KEY, LOCAL_GENESIS_REQUEST, }; +use casper_execution_engine::{engine_state::Error as StateError, execution::ExecError}; use casper_types::{ - ApiError, BlockTime, Digest, RuntimeArgs, Transaction, TransactionSessionKind, - TransactionV1Builder, + ApiError, BlockTime, RuntimeArgs, Transaction, TransactionSessionKind, TransactionV1Builder, }; const CONTRACT: &str = "do_nothing_stored.wasm"; const ENTRY_POINT: &str = "call"; const CHAIN_NAME: &str = "a"; -const STATE_HASH: Digest = Digest::from_raw([1; 32]); const BLOCK_TIME: BlockTime = BlockTime::new(10); #[ignore] @@ -42,13 +37,9 @@ fn try_add_contract_version(kind: TransactionSessionKind, should_succeed: bool) .build() .unwrap(); - let txn_request = ExecuteRequest::new( - STATE_HASH, - BLOCK_TIME, - Transaction::from(txn), - DEFAULT_PROPOSER_PUBLIC_KEY.clone(), - ) - .unwrap(); + let txn_request = ExecuteRequestBuilder::from_transaction(Transaction::from(txn)) + .with_block_time(BLOCK_TIME) + .build(); builder.exec(txn_request); diff --git a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs index 33e15a5220..869735be40 100644 --- a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs +++ b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs @@ -229,7 +229,7 @@ fn should_not_write_with_read_access_rights() { builder.exec(call_request).commit(); let exec_result = builder.get_last_exec_result().expect("should have results"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert!( matches!( error, @@ -280,7 +280,7 @@ fn should_not_read_with_write_access_rights() { builder.exec(call_request).commit(); let exec_result = builder.get_last_exec_result().expect("should have results"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert!( matches!( error, @@ -359,7 +359,7 @@ fn should_not_write_with_forged_uref() { builder.exec(call_request).commit(); let exec_result = builder.get_last_exec_result().expect("should have results"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert!( matches!( error, @@ -396,7 +396,7 @@ fn should_fail_put_with_invalid_dictionary_item_key() { builder.exec(call_request).commit(); let exec_result = builder.get_last_exec_result().expect("should have results"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert!( matches!( error, @@ -432,7 +432,7 @@ fn should_fail_get_with_invalid_dictionary_item_key() { builder.exec(call_request).commit(); let exec_result = builder.get_last_exec_result().expect("should have results"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert!( matches!( error, @@ -465,7 +465,7 @@ fn dictionary_put_should_fail_with_large_item_key() { builder.transfer_and_commit(fund_request).expect_success(); builder.exec(install_contract_request).commit(); let exec_result = builder.get_last_exec_result().expect("should have results"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert!( matches!( error, @@ -498,7 +498,7 @@ fn dictionary_get_should_fail_with_large_item_key() { builder.transfer_and_commit(fund_request).expect_success(); builder.exec(install_contract_request).commit(); let exec_result = builder.get_last_exec_result().expect("should have results"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert!( matches!( error, diff --git a/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs b/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs index 6dca29e4f5..43af88af4a 100644 --- a/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs +++ b/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs @@ -1,10 +1,7 @@ use num_traits::One; -use casper_engine_test_support::{LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR}; -use casper_execution_engine::{ - engine_state::{Error as CoreError, ExecuteRequest}, - execution::ExecError, -}; +use casper_engine_test_support::{ExecuteRequest, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR}; +use casper_execution_engine::{engine_state::Error as CoreError, execution::ExecError}; use casper_types::{ addressable_entity::NamedKeys, system::Caller, AddressableEntity, AddressableEntityHash, CLValue, EntityAddr, EntryPointType, HashAddr, Key, PackageAddr, PackageHash, StoredValue, diff --git a/execution_engine_testing/tests/src/test/contract_api/transfer.rs b/execution_engine_testing/tests/src/test/contract_api/transfer.rs index c1402026a7..4ed0068f96 100644 --- a/execution_engine_testing/tests/src/test/contract_api/transfer.rs +++ b/execution_engine_testing/tests/src/test/contract_api/transfer.rs @@ -463,9 +463,9 @@ fn should_fail_when_insufficient_funds() { let exec_result = builder .get_exec_result_owned(2) .expect("should have exec response"); - let exec_result = exec_result.as_error().expect("should have error"); - let error = assert_matches!(exec_result, EngineError::Exec(ExecError::Revert(e)) => *e, "{:?}", exec_result); - assert_eq!(error, ApiError::from(mint::Error::InsufficientFunds)); + let exec_result = exec_result.error().expect("should have error"); + let error = assert_matches!(exec_result, EngineError::Exec(ExecError::Revert(e)) => e, "{:?}", exec_result); + assert_eq!(*error, ApiError::from(mint::Error::InsufficientFunds)); } #[ignore] diff --git a/execution_engine_testing/tests/src/test/contract_messages.rs b/execution_engine_testing/tests/src/test/contract_messages.rs index f9c67d1d29..98032dace5 100644 --- a/execution_engine_testing/tests/src/test/contract_messages.rs +++ b/execution_engine_testing/tests/src/test/contract_messages.rs @@ -5,7 +5,6 @@ use casper_engine_test_support::{ ChainspecConfig, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_BLOCK_TIME, LOCAL_GENESIS_REQUEST, }; -use casper_execution_engine::engine_state::ExecutionResult; use casper_types::{ bytesrepr::ToBytes, contract_messages::{MessageChecksum, MessagePayload, MessageTopicSummary, TopicNameHash}, @@ -950,14 +949,17 @@ fn should_produce_per_block_message_ordering() { .expect("should have at least one topic"); let assert_last_message_block_index = |expected_index: u64| { - match builder.borrow().get_last_exec_result().unwrap() { - ExecutionResult::Failure { .. } => { - panic!("Expected that the message was emitted but the request did not produce successful execution effects"); - } - ExecutionResult::Success { messages, .. } => { - assert_eq!(messages.get(0).unwrap().block_index(), expected_index); - } - }; + assert_eq!( + builder + .borrow() + .get_last_exec_result() + .unwrap() + .messages() + .get(0) + .unwrap() + .block_index(), + expected_index + ) }; let query_message_count = || -> Option<(BlockTime, u64)> { diff --git a/execution_engine_testing/tests/src/test/deploy/receipts.rs b/execution_engine_testing/tests/src/test/deploy/receipts.rs index c5a0110557..4573726ace 100644 --- a/execution_engine_testing/tests/src/test/deploy/receipts.rs +++ b/execution_engine_testing/tests/src/test/deploy/receipts.rs @@ -129,7 +129,7 @@ fn should_record_wasm_transfer() { ) .build(); - let txn_hash = transfer_request.transaction_hash; + let txn_hash = transfer_request.session.transaction_hash; builder.exec(transfer_request).commit().expect_success(); @@ -196,7 +196,7 @@ fn should_record_wasm_transfer_with_id() { ) .build(); - let txn_hash = transfer_request.transaction_hash; + let txn_hash = transfer_request.session.transaction_hash; builder.exec(transfer_request).commit().expect_success(); @@ -273,7 +273,7 @@ fn should_record_wasm_transfers() { ) .build(); - let txn_hash = transfer_request.transaction_hash; + let txn_hash = transfer_request.session.transaction_hash; builder.exec(transfer_request).commit().expect_success(); @@ -415,7 +415,7 @@ fn should_record_wasm_transfers_with_subcall() { ) .build(); - let transfer_txn_hash = transfer_request.transaction_hash; + let transfer_txn_hash = transfer_request.session.transaction_hash; builder.exec(store_request).commit().expect_success(); builder.exec(transfer_request).commit().expect_success(); diff --git a/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs b/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs index e8da7475bb..1fcb2ab9b7 100644 --- a/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs +++ b/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs @@ -60,7 +60,7 @@ fn install_custom_payment( .into_package_hash() .expect("should be a hash"); - let exec_cost = builder.get_last_exec_result().unwrap().gas().value(); + let exec_cost = builder.get_last_exec_result().unwrap().consumed().value(); (default_account, package_hash, exec_cost) } diff --git a/execution_engine_testing/tests/src/test/explorer/faucet.rs b/execution_engine_testing/tests/src/test/explorer/faucet.rs index 182e430e85..503cd3b5bf 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet.rs @@ -843,7 +843,7 @@ fn should_allow_funding_by_an_authorized_account() { .get_last_exec_result() .expect("failed to get exec results"); - let error = exec_result.as_error().unwrap(); + let error = exec_result.error().unwrap(); assert!( matches!( error, diff --git a/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs b/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs index a76c960dd2..ef0fb894d5 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs @@ -1,10 +1,9 @@ use rand::Rng; use casper_engine_test_support::{ - DeployItemBuilder, EntityWithNamedKeys, ExecuteRequestBuilder, LmdbWasmTestBuilder, - TransferRequestBuilder, DEFAULT_PAYMENT, + DeployItemBuilder, EntityWithNamedKeys, ExecuteRequest, ExecuteRequestBuilder, + LmdbWasmTestBuilder, TransferRequestBuilder, DEFAULT_PAYMENT, }; -use casper_execution_engine::engine_state::ExecuteRequest; use casper_storage::data_access_layer::TransferRequest; use casper_types::{ account::AccountHash, addressable_entity::EntityKindTag, bytesrepr::FromBytes, runtime_args, diff --git a/execution_engine_testing/tests/src/test/gas_counter.rs b/execution_engine_testing/tests/src/test/gas_counter.rs index 8ad36ad76f..e12d960e5a 100644 --- a/execution_engine_testing/tests/src/test/gas_counter.rs +++ b/execution_engine_testing/tests/src/test/gas_counter.rs @@ -63,7 +63,7 @@ fn should_fail_to_overflow_gas_counter() { let exec_result = builder .get_exec_result_owned(0) .expect("should have response"); - let lhs = exec_result.as_error().expect("should have error"); + let lhs = exec_result.error().expect("should have error"); assert_matches!( lhs, Error::WasmPreprocessing(PreprocessingError::OperationForbiddenByGasRules) diff --git a/execution_engine_testing/tests/src/test/groups.rs b/execution_engine_testing/tests/src/test/groups.rs index 43828af440..ea25ba314f 100644 --- a/execution_engine_testing/tests/src/test/groups.rs +++ b/execution_engine_testing/tests/src/test/groups.rs @@ -168,7 +168,7 @@ fn should_not_call_restricted_session_from_wrong_account() { let response = builder .get_last_exec_result() .expect("should have last response"); - let error = response.as_error().expect("should have error"); + let error = response.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::InvalidContext)); } @@ -231,7 +231,7 @@ fn should_not_call_restricted_session_caller_from_wrong_account() { let response = builder .get_last_exec_result() .expect("should have last response"); - let error = response.as_error().expect("should have error"); + let error = response.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::InvalidContext)); } @@ -348,7 +348,7 @@ fn should_not_call_group_restricted_contract_from_wrong_account() { let response = builder .get_last_exec_result() .expect("should have last response"); - let error = response.as_error().expect("should have error"); + let error = response.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::InvalidContext)); } @@ -535,7 +535,7 @@ fn should_call_group_restricted_contract_as_session_from_wrong_account() { let response = builder .get_last_exec_result() .expect("should have last response"); - let error = response.as_error().expect("should have error"); + let error = response.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::InvalidContext)); } @@ -584,7 +584,7 @@ fn should_not_call_uncallable_contract_from_deploy() { let response = builder .get_last_exec_result() .expect("should have last response"); - let error = response.as_error().expect("should have error"); + let error = response.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::InvalidContext)); let exec_request_3 = { @@ -657,7 +657,7 @@ fn should_not_call_uncallable_session_from_deploy() { let response = builder .get_last_exec_result() .expect("should have last response"); - let error = response.as_error().expect("should have error"); + let error = response.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::InvalidContext)); let exec_request_3 = { @@ -747,7 +747,7 @@ fn should_not_call_group_restricted_stored_payment_code_from_invalid_account() { let response = builder .get_last_exec_result() .expect("should have last response"); - let error = response.as_error().expect("should have error"); + let error = response.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::InvalidContext)); } diff --git a/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs b/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs index 3bb6122ee5..74291ff804 100644 --- a/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs +++ b/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs @@ -124,16 +124,16 @@ fn test_burning_fees( ) .build(); let total_supply_before = builder.total_supply(None, protocol_version); - let exec_request_1_proposer = exec_request_1.proposer.clone(); - let proposer_account_1 = builder - .get_entity_by_account_hash(exec_request_1_proposer.to_account_hash()) - .expect("should have proposer account"); - builder.exec(exec_request_1).expect_success().commit(); - assert_eq!( - builder.get_purse_balance(proposer_account_1.main_purse()), - U512::zero(), - "proposer should not receive anything", - ); + // let exec_request_1_proposer = exec_request_1.proposer.clone(); + // let proposer_account_1 = builder + // .get_entity_by_account_hash(exec_request_1_proposer.to_account_hash()) + // .expect("should have proposer account"); + // builder.exec(exec_request_1).expect_success().commit(); + // assert_eq!( + // builder.get_purse_balance(proposer_account_1.main_purse()), + // U512::zero(), + // "proposer should not receive anything", + // ); let total_supply_after = builder.total_supply(None, protocol_version); assert_eq!( total_supply_before - total_supply_after, diff --git a/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs b/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs index fb37938860..466de315e5 100644 --- a/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs +++ b/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs @@ -61,15 +61,15 @@ fn should_finalize_and_accumulate_rewards_purse() { ) .build(); - let exec_request_1_proposer = exec_request_1.proposer.clone(); - let proposer_account_1 = builder - .get_entity_with_named_keys_by_account_hash(exec_request_1_proposer.to_account_hash()) - .expect("should have proposer account"); + // let exec_request_1_proposer = exec_request_1.proposer.clone(); + // let proposer_account_1 = builder + // .get_entity_with_named_keys_by_account_hash(exec_request_1_proposer.to_account_hash()) + // .expect("should have proposer account"); builder.exec(exec_request_1).expect_success().commit(); - assert_eq!( - builder.get_purse_balance(proposer_account_1.main_purse()), - U512::zero() - ); + // assert_eq!( + // builder.get_purse_balance(proposer_account_1.main_purse()), + // U512::zero() + // ); let handle_payment_2 = builder.get_named_keys(EntityAddr::System(handle_payment.value())); @@ -136,7 +136,7 @@ fn should_accumulate_deploy_fees() { ) .build(); - let exec_request_proposer = exec_request.proposer.clone(); + // let exec_request_proposer = exec_request.proposer.clone(); builder.exec(exec_request).expect_success().commit(); @@ -160,15 +160,15 @@ fn should_accumulate_deploy_fees() { "rewards balance should increase" ); - // Ensures default proposer didn't receive any funds - let proposer_account = builder - .get_entity_by_account_hash(exec_request_proposer.to_account_hash()) - .expect("should have proposer account"); - - assert_eq!( - builder.get_purse_balance(proposer_account.main_purse()), - U512::zero() - ); + // // Ensures default proposer didn't receive any funds + // let proposer_account = builder + // .get_entity_by_account_hash(exec_request_proposer.to_account_hash()) + // .expect("should have proposer account"); + // + // assert_eq!( + // builder.get_purse_balance(proposer_account.main_purse()), + // U512::zero() + // ); } #[ignore] diff --git a/execution_engine_testing/tests/src/test/private_chain/management.rs b/execution_engine_testing/tests/src/test/private_chain/management.rs index a3160a3297..a2a03f12d9 100644 --- a/execution_engine_testing/tests/src/test/private_chain/management.rs +++ b/execution_engine_testing/tests/src/test/private_chain/management.rs @@ -1,17 +1,14 @@ use std::convert::TryFrom; use casper_engine_test_support::{ - ChainspecConfig, DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, + ChainspecConfig, DeployItemBuilder, ExecuteRequest, ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, DEFAULT_AUCTION_DELAY, DEFAULT_CHAINSPEC_REGISTRY, DEFAULT_GENESIS_CONFIG_HASH, DEFAULT_GENESIS_TIMESTAMP_MILLIS, DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS, DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, DEFAULT_ROUND_SEIGNIORAGE_RATE, DEFAULT_SYSTEM_CONFIG, DEFAULT_UNBONDING_DELAY, DEFAULT_VALIDATOR_SLOTS, DEFAULT_WASM_CONFIG, }; -use casper_execution_engine::{ - engine_state::{Error, ExecuteRequest}, - execution::ExecError, -}; +use casper_execution_engine::{engine_state::Error, execution::ExecError}; use casper_storage::{data_access_layer::GenesisRequest, tracking_copy::TrackingCopyError}; use casper_types::{ account::{AccountHash, Weight}, diff --git a/execution_engine_testing/tests/src/test/regression/ee_1129.rs b/execution_engine_testing/tests/src/test/regression/ee_1129.rs index fa203ce91e..bdff6ff77c 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1129.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1129.rs @@ -93,7 +93,7 @@ fn should_run_ee_1129_underfunded_delegate_call() { let error = builder .get_last_exec_result() .expect("should have results") - .as_error() + .error() .cloned() .expect("should have error"); @@ -153,7 +153,7 @@ fn should_run_ee_1129_underfunded_add_bid_call() { let error = builder .get_last_exec_result() .expect("should have results") - .as_error() + .error() .cloned() .expect("should have error"); @@ -199,7 +199,7 @@ fn should_run_ee_1129_underfunded_mint_contract_call() { let error = builder .get_last_exec_result() .expect("should have results") - .as_error() + .error() .cloned() .expect("should have error"); @@ -245,7 +245,7 @@ fn should_not_panic_when_calling_session_contract_by_uref() { let error = builder .get_last_exec_result() .expect("should have results") - .as_error() + .error() .cloned() .expect("should have error"); @@ -289,7 +289,7 @@ fn should_not_panic_when_calling_payment_contract_by_uref() { let error = builder .get_last_exec_result() .expect("should have results") - .as_error() + .error() .cloned() .expect("should have error"); @@ -340,7 +340,7 @@ fn should_not_panic_when_calling_contract_package_by_uref() { let error = builder .get_last_exec_result() .expect("should have results") - .as_error() + .error() .cloned() .expect("should have error"); @@ -389,7 +389,7 @@ fn should_not_panic_when_calling_payment_versioned_contract_by_uref() { let error = builder .get_last_exec_result() .expect("should have results") - .as_error() + .error() .cloned() .expect("should have error"); assert!( @@ -442,7 +442,7 @@ fn should_not_panic_when_calling_module_without_memory() { let error = builder .get_last_exec_result() .expect("should have results") - .as_error() + .error() .cloned() .expect("should have error"); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1160.rs b/execution_engine_testing/tests/src/test/regression/ee_1160.rs index 80e999b56c..791301a598 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1160.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1160.rs @@ -35,7 +35,7 @@ fn ee_1160_wasmless_transfer_should_empty_account() { let last_result = builder.get_exec_result_owned(0).unwrap(); - assert!(last_result.as_error().is_none(), "{:?}", last_result); + assert!(last_result.error().is_none(), "{:?}", last_result); assert!(!last_result.transfers().is_empty()); let default_account_balance_after = builder.get_purse_balance(default_account.main_purse()); @@ -88,7 +88,7 @@ fn ee_1160_transfer_larger_than_balance_should_fail() { //assert_eq!(last_result.cost(), wasmless_transfer_gas_cost); assert!( - last_result.as_error().is_some(), + last_result.error().is_some(), "Expected error but last result is {:?}", last_result ); @@ -135,7 +135,7 @@ fn ee_1160_large_wasmless_transfer_should_avoid_overflow() { // assert_eq!(last_result.cost(), wasmless_transfer_gas_cost); assert!( - last_result.as_error().is_some(), + last_result.error().is_some(), "Expected error but last result is {:?}", last_result ); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1163.rs b/execution_engine_testing/tests/src/test/regression/ee_1163.rs index 6047635372..ba35d27ffd 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1163.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1163.rs @@ -62,7 +62,7 @@ fn should_charge_for_user_error( assert_eq!(payment_purse_balance, U512::zero()); - response.as_error().cloned().expect("should have error") + response.error().cloned().expect("should have error") } // TODO: reenable when new payment logic is added diff --git a/execution_engine_testing/tests/src/test/regression/ee_1174.rs b/execution_engine_testing/tests/src/test/regression/ee_1174.rs index 1ba0dcb0c6..cc5d833bd1 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1174.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1174.rs @@ -44,7 +44,7 @@ fn should_run_ee_1174_delegation_rate_too_high() { let error = builder .get_last_exec_result() .expect("should have results") - .as_error() + .error() .cloned() .expect("should have error"); diff --git a/execution_engine_testing/tests/src/test/regression/ee_532.rs b/execution_engine_testing/tests/src/test/regression/ee_532.rs index c2297f63f2..0f4bb49170 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_532.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_532.rs @@ -33,7 +33,7 @@ fn should_run_ee_532_non_existent_account_regression_test() { "expected precondition failure" ); - let message = deploy_result.as_error().map(|err| format!("{}", err)); + let message = deploy_result.error().map(|err| format!("{}", err)); assert_eq!( message, Some(format!( diff --git a/execution_engine_testing/tests/src/test/regression/ee_771.rs b/execution_engine_testing/tests/src/test/regression/ee_771.rs index a3ad56dc81..8786daaab1 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_771.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_771.rs @@ -25,7 +25,7 @@ fn should_run_ee_771_regression() { .get_exec_result_owned(0) .expect("should have a response"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert_eq!( format!("{}", error), "Function not found: functiondoesnotexist" diff --git a/execution_engine_testing/tests/src/test/regression/ee_966.rs b/execution_engine_testing/tests/src/test/regression/ee_966.rs index c215e2b1f9..087e5e9dcb 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_966.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_966.rs @@ -3,14 +3,11 @@ use casper_wasm::builder; use once_cell::sync::Lazy; use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, - ARG_AMOUNT, DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, - LOCAL_GENESIS_REQUEST, -}; -use casper_execution_engine::{ - engine_state::{Error, ExecuteRequest}, - execution::ExecError, + DeployItemBuilder, ExecuteRequest, ExecuteRequestBuilder, LmdbWasmTestBuilder, + UpgradeRequestBuilder, ARG_AMOUNT, DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, + DEFAULT_PROTOCOL_VERSION, LOCAL_GENESIS_REQUEST, }; +use casper_execution_engine::{engine_state::Error, execution::ExecError}; use casper_types::{ addressable_entity::DEFAULT_ENTRY_POINT_NAME, runtime_args, ApiError, EraId, HostFunctionCosts, MessageLimits, OpcodeCosts, ProtocolVersion, RuntimeArgs, StorageCosts, WasmConfig, @@ -105,7 +102,7 @@ fn should_run_ee_966_cant_have_too_much_initial_memory() { let exec_result = &builder .get_exec_result_owned(0) .expect("should have exec response"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::Interpreter(_))); } @@ -157,7 +154,7 @@ fn should_run_ee_966_cant_have_too_much_max_memory() { let exec_result = &builder .get_exec_result_owned(0) .expect("should have exec response"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::Interpreter(_))); } @@ -180,7 +177,7 @@ fn should_run_ee_966_cant_have_way_too_much_max_memory() { let exec_result = &builder .get_exec_result_owned(0) .expect("should have exec response"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::Interpreter(_))); } @@ -201,7 +198,7 @@ fn should_run_ee_966_cant_have_larger_initial_than_max_memory() { let exec_result = &builder .get_exec_result_owned(0) .expect("should have exec response"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::Interpreter(_))); } @@ -224,7 +221,7 @@ fn should_run_ee_966_regression_fail_when_growing_mem_past_max() { let exec_result = &builder .get_exec_result_owned(0) .expect("should have exec response"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::Revert(ApiError::OutOfMemory))); } @@ -251,7 +248,7 @@ fn should_run_ee_966_regression_when_growing_mem_after_upgrade() { let exec_result = &builder .get_exec_result_owned(0) .expect("should have exec response"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::Revert(ApiError::OutOfMemory))); // diff --git a/execution_engine_testing/tests/src/test/regression/gh_1470.rs b/execution_engine_testing/tests/src/test/regression/gh_1470.rs index e40df8f31c..365d8ad6c6 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1470.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1470.rs @@ -142,7 +142,7 @@ fn gh_1470_call_contract_should_verify_group_access() { let exec_result = builder .get_last_exec_result() .expect("should have last response"); - let call_contract_error = exec_result.as_error().cloned().expect("should have error"); + let call_contract_error = exec_result.error().cloned().expect("should have error"); let call_versioned_contract_request = { let args = runtime_args! { @@ -157,7 +157,7 @@ fn gh_1470_call_contract_should_verify_group_access() { let exec_result = builder .get_last_exec_result() .expect("should have last response"); - let call_versioned_contract_error = exec_result.as_error().expect("should have error"); + let call_versioned_contract_error = exec_result.error().expect("should have error"); match (&call_contract_error, &call_versioned_contract_error) { (Error::Exec(ExecError::InvalidContext), Error::Exec(ExecError::InvalidContext)) => (), @@ -469,7 +469,7 @@ fn gh_1470_call_contract_should_verify_wrong_argument_types() { let exec_result = builder .get_last_exec_result() .expect("should have last response"); - let call_contract_error = exec_result.as_error().cloned().expect("should have error"); + let call_contract_error = exec_result.error().cloned().expect("should have error"); let call_versioned_contract_request = { let args = runtime_args! { @@ -485,7 +485,7 @@ fn gh_1470_call_contract_should_verify_wrong_argument_types() { let exec_result = builder .get_last_exec_result() .expect("should have last response"); - let call_versioned_contract_error = exec_result.as_error().expect("should have error"); + let call_versioned_contract_error = exec_result.error().expect("should have error"); let expected = gh_1470_regression::Arg1Type::cl_type(); let found = gh_1470_regression::Arg3Type::cl_type(); @@ -572,7 +572,7 @@ fn gh_1470_call_contract_should_verify_wrong_optional_argument_types() { let exec_result = builder .get_last_exec_result() .expect("should have last response"); - let call_contract_error = exec_result.as_error().cloned().expect("should have error"); + let call_contract_error = exec_result.error().cloned().expect("should have error"); let call_versioned_contract_request = { let args = runtime_args! { @@ -588,7 +588,7 @@ fn gh_1470_call_contract_should_verify_wrong_optional_argument_types() { let exec_result = builder .get_last_exec_result() .expect("should have last response"); - let call_versioned_contract_error = exec_result.as_error().expect("should have error"); + let call_versioned_contract_error = exec_result.error().expect("should have error"); let expected = gh_1470_regression::Arg3Type::cl_type(); let found = gh_1470_regression::Arg4Type::cl_type(); diff --git a/execution_engine_testing/tests/src/test/regression/gh_1688.rs b/execution_engine_testing/tests/src/test/regression/gh_1688.rs index 755541ffea..673165c740 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1688.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1688.rs @@ -1,8 +1,7 @@ use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, + DeployItemBuilder, ExecuteRequest, ExecuteRequestBuilder, LmdbWasmTestBuilder, + DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; -use casper_execution_engine::engine_state::ExecuteRequest; use casper_types::{ runtime_args, system::standard_payment::ARG_AMOUNT, AddressableEntityHash, PackageHash, RuntimeArgs, diff --git a/execution_engine_testing/tests/src/test/regression/gh_1902.rs b/execution_engine_testing/tests/src/test/regression/gh_1902.rs index 3f0e7cca4b..013e09f03a 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1902.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1902.rs @@ -2,13 +2,11 @@ use num_rational::Ratio; use once_cell::sync::Lazy; use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, - DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, LOCAL_GENESIS_REQUEST, - MINIMUM_ACCOUNT_CREATION_BALANCE, -}; -use casper_execution_engine::engine_state::{ - engine_config::DEFAULT_MINIMUM_DELEGATION_AMOUNT, ExecuteRequest, + DeployItemBuilder, ExecuteRequest, ExecuteRequestBuilder, LmdbWasmTestBuilder, + TransferRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, + LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; +use casper_execution_engine::engine_state::engine_config::DEFAULT_MINIMUM_DELEGATION_AMOUNT; use casper_types::{ account::AccountHash, runtime_args, diff --git a/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs b/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs index f982f09048..050bdeb5ec 100644 --- a/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs +++ b/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs @@ -1,13 +1,10 @@ use std::convert::TryInto; use casper_engine_test_support::{ - utils, DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, -}; -use casper_execution_engine::{ - engine_state::{self, ExecuteRequest}, - execution::ExecError, + utils, DeployItemBuilder, ExecuteRequest, ExecuteRequestBuilder, LmdbWasmTestBuilder, + DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; +use casper_execution_engine::{engine_state, execution::ExecError}; use casper_types::{ account::{AccountHash, ACCOUNT_HASH_LENGTH}, bytesrepr::Bytes, diff --git a/execution_engine_testing/tests/src/test/regression/regression_20210707.rs b/execution_engine_testing/tests/src/test/regression/regression_20210707.rs index 2535a43b41..ee0010a450 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20210707.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20210707.rs @@ -1,14 +1,11 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ - DeployItemBuilder, EntityWithNamedKeys, ExecuteRequestBuilder, LmdbWasmTestBuilder, - TransferRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, - MINIMUM_ACCOUNT_CREATION_BALANCE, -}; -use casper_execution_engine::{ - engine_state::{Error as CoreError, ExecuteRequest}, - execution::ExecError, + DeployItemBuilder, EntityWithNamedKeys, ExecuteRequest, ExecuteRequestBuilder, + LmdbWasmTestBuilder, TransferRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, + LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, }; +use casper_execution_engine::{engine_state::Error as CoreError, execution::ExecError}; use casper_storage::{data_access_layer::TransferRequest, system::transfer::TransferError}; use casper_types::{ account::AccountHash, runtime_args, system::mint, AccessRights, AddressableEntityHash, diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs b/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs index b0bc5988c2..7ec37cf620 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs @@ -838,7 +838,7 @@ fn should_release_founder_stake() { let error = builder .get_last_exec_result() .expect("should have last exec result") - .as_error() + .error() .cloned() .expect("should have error"); assert_matches!( @@ -2356,7 +2356,7 @@ fn should_not_partially_undelegate_uninitialized_vesting_schedule() { let error = builder .get_last_exec_result() .expect("should have last exec result") - .as_error() + .error() .cloned() .expect("should have error"); @@ -2426,7 +2426,7 @@ fn should_not_fully_undelegate_uninitialized_vesting_schedule() { let error = builder .get_last_exec_result() .expect("should have last exec result") - .as_error() + .error() .cloned() .expect("should have error"); @@ -2553,7 +2553,7 @@ fn should_not_undelegate_vfta_holder_stake() { let error = builder .get_last_exec_result() .expect("should have last exec result") - .as_error() + .error() .cloned() .expect("should have error"); @@ -2615,7 +2615,7 @@ fn should_release_vfta_holder_stake() { let error = builder .get_last_exec_result() .expect("should have last exec result") - .as_error() + .error() .cloned() .expect("should have error"); diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs b/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs index 47bea18750..47440a51d3 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs @@ -281,7 +281,7 @@ fn should_fail_bonding_with_insufficient_funds() { let exec_result = builder .get_exec_result_owned(1) .expect("should have a response") - .as_error() + .error() .cloned() .expect("should have error"); assert!( diff --git a/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs b/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs index 39f663701f..2d97056597 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs @@ -133,7 +133,7 @@ fn should_forward_payment_execution_runtime_error() { .get_exec_result_owned(0) .expect("there should be a response"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::Revert(ApiError::User(100)))); } @@ -198,12 +198,12 @@ fn should_forward_payment_execution_gas_limit_error() { .get_exec_result_owned(0) .expect("there should be a response"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::GasLimit)); let payment_gas_limit = Gas::from_motes(Motes::new(*MAX_PAYMENT), DEFAULT_GAS_PRICE) .expect("should convert to gas"); assert_eq!( - exec_result.gas(), + exec_result.consumed(), payment_gas_limit, "cost should equal gas limit" ); @@ -242,12 +242,12 @@ fn should_run_out_of_gas_when_session_code_exceeds_gas_limit() { .get_exec_result_owned(0) .expect("there should be a response"); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::GasLimit)); let session_gas_limit = Gas::from_motes(Motes::new(payment_purse_amount), DEFAULT_GAS_PRICE) .expect("should convert to gas"); assert_eq!( - exec_result.gas(), + exec_result.consumed(), session_gas_limit, "cost should equal gas limit" ); @@ -292,7 +292,7 @@ fn should_correctly_charge_when_session_code_runs_out_of_gas() { .get_exec_result_owned(0) .expect("there should be a response"); - let gas = exec_result.gas(); + let gas = exec_result.consumed(); let motes = Motes::from_gas(gas, DEFAULT_GAS_PRICE).expect("should have motes"); let tally = motes.value() + modified_balance; @@ -302,12 +302,12 @@ fn should_correctly_charge_when_session_code_runs_out_of_gas() { "no net resources should be gained or lost post-distribution" ); - let error = exec_result.as_error().expect("should have error"); + let error = exec_result.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::GasLimit)); let session_gas_limit = Gas::from_motes(Motes::new(payment_purse_amount), DEFAULT_GAS_PRICE) .expect("should convert to gas"); assert_eq!( - exec_result.gas(), + exec_result.consumed(), session_gas_limit, "cost should equal gas limit" ); diff --git a/execution_engine_testing/tests/src/test/system_costs.rs b/execution_engine_testing/tests/src/test/system_costs.rs index 862ea8354a..75d8b3da60 100644 --- a/execution_engine_testing/tests/src/test/system_costs.rs +++ b/execution_engine_testing/tests/src/test/system_costs.rs @@ -722,7 +722,7 @@ fn should_charge_for_erroneous_system_contract_calls() { let _error = builder .get_last_exec_result() .expect("should have results") - .as_error() + .error() .unwrap_or_else(|| panic!("should have error while executing {}", entrypoint)); let transaction_fee = diff --git a/execution_engine_testing/tests/src/test/wasmless_transfer.rs b/execution_engine_testing/tests/src/test/wasmless_transfer.rs index 55fa0c854d..9e8469bd4f 100644 --- a/execution_engine_testing/tests/src/test/wasmless_transfer.rs +++ b/execution_engine_testing/tests/src/test/wasmless_transfer.rs @@ -509,9 +509,7 @@ fn invalid_transfer_wasmless(invalid_wasmless_transfer: InvalidWasmlessTransfer) .get_last_exec_result() .expect("Expected to be called after run()"); - assert!(result.is_failure(), "was expected to fail"); - - let error = result.as_error().expect("should have error"); + let error = result.error().expect("should have error"); let account_1_closing_balance = builder.get_purse_balance(account_1_purse); diff --git a/node/src/components/contract_runtime.rs b/node/src/components/contract_runtime.rs index bc98fe7fc0..0ac3862761 100644 --- a/node/src/components/contract_runtime.rs +++ b/node/src/components/contract_runtime.rs @@ -38,10 +38,7 @@ use casper_storage::{ transaction_source::lmdb::LmdbEnvironment, trie_store::lmdb::LmdbTrieStore, }, - system::{ - genesis::GenesisError, protocol_upgrade::ProtocolUpgradeError, - runtime_native::Config as NativeRuntimeConfig, - }, + system::{genesis::GenesisError, protocol_upgrade::ProtocolUpgradeError}, tracking_copy::TrackingCopyError, }; use casper_types::{Chainspec, ChainspecRawBytes, ChainspecRegistry, ProtocolUpgradeConfig}; @@ -562,9 +559,6 @@ impl ContractRuntime { transaction, responder, } => { - let native_runtime_config = - NativeRuntimeConfig::from_chainspec(self.chainspec.as_ref()); - let system_costs = self.chainspec.system_costs_config; let chainspec = Arc::clone(&self.chainspec); let data_access_layer = Arc::clone(&self.data_access_layer); let execution_engine_v1 = Arc::clone(&self.execution_engine_v1); diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index f88d729865..7cdc6465d1 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -24,7 +24,7 @@ use casper_types::{ execution::{Effects, ExecutionResult, TransformKindV2, TransformV2}, system::mint::BalanceHoldAddrTag, BlockHeader, BlockTime, BlockV2, CLValue, CategorizedTransaction, Chainspec, ChecksumRegistry, - Digest, EraEndV2, EraId, FeeHandling, Gas, GasLimited, Key, Phase, ProtocolVersion, PublicKey, + Digest, EraEndV2, EraId, FeeHandling, Gas, GasLimited, Key, ProtocolVersion, PublicKey, Transaction, TransactionCategory, U512, }; @@ -79,6 +79,11 @@ pub fn execute_finalized_block( let scratch_state = data_access_layer.get_scratch_global_state(); + let txn_ids = executable_block + .transactions + .iter() + .map(Transaction::fetch_id) + .collect_vec(); let system_costs = chainspec.system_costs_config; let insufficient_balance_handling = InsufficientBalanceHandling::HoldRemaining; let gas_price = Some(1); // < --TODO: this is where Karan's calculated gas price needs to be used @@ -137,7 +142,7 @@ pub fn execute_finalized_block( WasmV1Result::invalid_executable_item(custom_payment_gas_limit, error) } }; - match artifacts.push_wasm_v1_result(txn_hash, txn_header, pay_result) { + match artifacts.push_wasm_v1_result(txn_hash, txn_header.clone(), pay_result) { ExecutionArtifactOutcome::RootNotFound => { return Err(BlockExecutionError::RootNotFound(state_root_hash)) } @@ -148,7 +153,7 @@ pub fn execute_finalized_block( // balance request should check the handle payment purse, not initiator's purse BalanceIdentifier::Payment } else { - initiator_addr.into() + initiator_addr.clone().into() } }; @@ -159,101 +164,109 @@ pub fn execute_finalized_block( balance_handling, )); - let is_sufficient_balance = initial_balance_result.is_sufficient(cost.value()); - - match (txn.category(), is_sufficient_balance) { - (_, false) => { - debug!(%txn_hash, "skipping execution due to insufficient balance"); - } - (TransactionCategory::Mint, _) => { - let transfer_result = scratch_state.transfer(TransferRequest::with_runtime_args( - native_runtime_config.clone(), - state_root_hash, - holds_epoch, - protocol_version, - txn_hash, - initiator_addr, - authorization_keys, - runtime_args, - cost, - )); - match artifacts.push_transfer_result( - txn_hash, - txn_header.clone(), - transfer_result, - cost, - ) { - ExecutionArtifactOutcome::RootNotFound => { - return Err(BlockExecutionError::RootNotFound(state_root_hash)) - } - ExecutionArtifactOutcome::Effects(transfer_effects) => { - effects.append(transfer_effects.clone()); + if initial_balance_result.is_sufficient(cost.value()) { + match txn.category() { + TransactionCategory::Mint => { + let transfer_result = + scratch_state.transfer(TransferRequest::with_runtime_args( + native_runtime_config.clone(), + state_root_hash, + holds_epoch, + protocol_version, + txn_hash, + initiator_addr, + authorization_keys, + runtime_args, + cost, + )); + match artifacts.push_transfer_result( + txn_hash, + txn_header.clone(), + transfer_result, + cost, + ) { + ExecutionArtifactOutcome::RootNotFound => { + return Err(BlockExecutionError::RootNotFound(state_root_hash)) + } + ExecutionArtifactOutcome::Effects(transfer_effects) => { + effects.append(transfer_effects.clone()); + } } } - } - (TransactionCategory::Auction, _) => { - let auction_method = match AuctionMethod::from_parts( - entry_point, - &runtime_args, - holds_epoch, - chainspec, - ) { - Ok(auction_method) => auction_method, - Err(_) => { - artifacts.push_auction_method_failure(txn_hash, txn_header.clone(), cost); - continue; - } - }; - let bidding_result = scratch_state.bidding(BiddingRequest::new( - native_runtime_config.clone(), - state_root_hash, - block_time, - protocol_version, - txn_hash, - initiator_addr, - authorization_keys, - auction_method, - )); - match artifacts.push_bidding_result( - txn_hash, - txn_header.clone(), - bidding_result, - cost, - ) { - ExecutionArtifactOutcome::RootNotFound => { - return Err(BlockExecutionError::RootNotFound(state_root_hash)) - } - ExecutionArtifactOutcome::Effects(bidding_effects) => { - effects.append(bidding_effects.clone()); + TransactionCategory::Auction => { + let auction_method = match AuctionMethod::from_parts( + entry_point, + &runtime_args, + holds_epoch, + chainspec, + ) { + Ok(auction_method) => auction_method, + Err(_) => { + artifacts.push_auction_method_failure( + txn_hash, + txn_header.clone(), + cost, + ); + continue; + } + }; + let bidding_result = scratch_state.bidding(BiddingRequest::new( + native_runtime_config.clone(), + state_root_hash, + block_time, + protocol_version, + txn_hash, + initiator_addr, + authorization_keys, + auction_method, + )); + match artifacts.push_bidding_result( + txn_hash, + txn_header.clone(), + bidding_result, + cost, + ) { + ExecutionArtifactOutcome::RootNotFound => { + return Err(BlockExecutionError::RootNotFound(state_root_hash)) + } + ExecutionArtifactOutcome::Effects(bidding_effects) => { + effects.append(bidding_effects.clone()); + } } } - } - (TransactionCategory::Standard, _) | (TransactionCategory::InstallUpgrade, _) => { - let wasm_v1_result = match WasmV1Request::new_session( - state_root_hash, - block_time, - gas_limit, - txn.clone(), - ) { - Ok(wasm_v1_request) => { - execution_engine_v1.execute(&scratch_state, wasm_v1_request) - } - Err(error) => WasmV1Result::invalid_executable_item(gas_limit, error), - }; - trace!( - %txn_hash, - ?wasm_v1_result, - "transaction execution result" - ); - match artifacts.push_wasm_v1_result(txn_hash, txn_header.clone(), wasm_v1_result) { - ExecutionArtifactOutcome::RootNotFound => { - return Err(BlockExecutionError::RootNotFound(state_root_hash)) - } - ExecutionArtifactOutcome::Effects(wasm_effects) => { - effects.append(wasm_effects.clone()); + TransactionCategory::Standard | TransactionCategory::InstallUpgrade => { + let wasm_v1_result = match WasmV1Request::new_session( + state_root_hash, + block_time, + gas_limit, + txn.clone(), + ) { + Ok(wasm_v1_request) => { + execution_engine_v1.execute(&scratch_state, wasm_v1_request) + } + Err(error) => WasmV1Result::invalid_executable_item(gas_limit, error), + }; + trace!( + %txn_hash, + ?wasm_v1_result, + "transaction execution result" + ); + match artifacts.push_wasm_v1_result( + txn_hash, + txn_header.clone(), + wasm_v1_result, + ) { + ExecutionArtifactOutcome::RootNotFound => { + return Err(BlockExecutionError::RootNotFound(state_root_hash)) + } + ExecutionArtifactOutcome::Effects(wasm_effects) => { + effects.append(wasm_effects.clone()); + } } } } + } else { + debug!(%txn_hash, "skipping execution due to insufficient balance"); } // handle payment per the chainspec determined fee setting @@ -317,11 +330,6 @@ pub fn execute_finalized_block( // data can be verified if necessary for a given block. the block synchronizer in particular // depends on the existence of such checksums. let txns_approvals_hashes = { - let txn_ids = executable_block - .transactions - .iter() - .map(Transaction::fetch_id) - .collect_vec(); let approvals_checksum = types::compute_approvals_checksum(txn_ids.clone()) .map_err(BlockExecutionError::FailedToComputeApprovalsChecksum)?; let execution_results_checksum = @@ -641,7 +649,6 @@ where S: StateProvider, { let state_root_hash = block_header.state_root_hash(); - let protocol_version = block_header.protocol_version(); let block_time = block_header .timestamp() .saturating_add(chainspec.core_config.minimum_block_time); @@ -651,15 +658,16 @@ where return SpeculativeExecutionResult::invalid_gas_limit(transaction); } }; - let request = WasmV1Request::new( + let wasm_v1_result = match WasmV1Request::new_session( *state_root_hash, - protocol_version, block_time.into(), - transaction, gas_limit, - Phase::Session, - ); - SpeculativeExecutionResult::WasmV1(execution_engine_v1.execute(state_provider, request)) + transaction, + ) { + Ok(wasm_v1_request) => execution_engine_v1.execute(state_provider, wasm_v1_request), + Err(error) => WasmV1Result::invalid_executable_item(gas_limit, error), + }; + SpeculativeExecutionResult::WasmV1(wasm_v1_result) } #[allow(clippy::too_many_arguments)] diff --git a/node/src/components/contract_runtime/utils.rs b/node/src/components/contract_runtime/utils.rs index bdb68a4a00..725bc99e1a 100644 --- a/node/src/components/contract_runtime/utils.rs +++ b/node/src/components/contract_runtime/utils.rs @@ -20,10 +20,10 @@ use casper_storage::{ }; use casper_types::{Chainspec, EraId, Key}; use once_cell::sync::Lazy; -use std::fmt::Debug; use std::{ cmp, collections::{BTreeMap, HashMap}, + fmt::Debug, ops::Range, sync::{Arc, Mutex}, }; diff --git a/node/src/components/storage/tests.rs b/node/src/components/storage/tests.rs index a9f73368c1..c3bfb77809 100644 --- a/node/src/components/storage/tests.rs +++ b/node/src/components/storage/tests.rs @@ -2895,7 +2895,7 @@ fn check_block_operations_with_node_1_5_2_storage() { let transfers = get_block_transfers(&mut harness, &mut storage, *hash); if !block_info.deploy_hashes.is_empty() { - let mut stored_transfers: Vec = transfers + let mut stored_transfers: Vec = transfers .unwrap() .iter() .map(|transfer| match transfer { @@ -2904,12 +2904,7 @@ fn check_block_operations_with_node_1_5_2_storage() { }) .collect(); stored_transfers.sort(); - let mut expected_deploys: Vec = block_info - .deploy_hashes - .clone() - .iter() - .map(|dh| TransactionHash::Deploy(*dh)) - .collect(); + let mut expected_deploys = block_info.deploy_hashes.clone(); expected_deploys.sort(); assert_eq!(stored_transfers, expected_deploys); } diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index 0ca7a00bd3..1b5c586772 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -1625,7 +1625,8 @@ "type": "object", "required": [ "gas_price", - "payment_amount" + "payment_amount", + "standard_payment" ], "properties": { "payment_amount": { @@ -1639,6 +1640,10 @@ "type": "integer", "format": "uint64", "minimum": 0.0 + }, + "standard_payment": { + "description": "Standard payment.", + "type": "boolean" } }, "additionalProperties": false @@ -5180,4 +5185,4 @@ ] } } -} +} \ No newline at end of file diff --git a/storage/src/data_access_layer/bidding.rs b/storage/src/data_access_layer/bidding.rs index e32c0b50f4..b9fc16e3b8 100644 --- a/storage/src/data_access_layer/bidding.rs +++ b/storage/src/data_access_layer/bidding.rs @@ -9,17 +9,20 @@ use casper_types::{ bytesrepr::FromBytes, execution::Effects, system::{auction, auction::DelegationRate}, - BlockTime, CLTyped, CLValue, CLValueError, Digest, InitiatorAddr, ProtocolVersion, PublicKey, - RuntimeArgs, TransactionHash, U512, + BlockTime, CLTyped, CLValue, CLValueError, Chainspec, Digest, InitiatorAddr, ProtocolVersion, + PublicKey, RuntimeArgs, TransactionEntryPoint, TransactionHash, U512, }; use crate::{ system::runtime_native::Config as NativeRuntimeConfig, tracking_copy::TrackingCopyError, }; -/// An error returned when constructing an [`AuctionMethod`] using invalid runtime args. +/// An error returned when constructing an [`AuctionMethod`]. #[derive(Clone, Eq, PartialEq, Error, Serialize, Debug)] -pub enum InvalidAuctionRuntimeArgs { +pub enum AuctionMethodError { + /// Provided entry point is not one of the Auction ones. + #[error("invalid entry point for auction: {0}")] + InvalidEntryPoint(TransactionEntryPoint), /// Required arg missing. #[error("missing '{0}' arg")] MissingArg(String), @@ -71,15 +74,42 @@ pub enum AuctionMethod { } impl AuctionMethod { - pub fn new_activate_bid(runtime_args: &RuntimeArgs) -> Result { + pub fn from_parts( + entry_point: TransactionEntryPoint, + runtime_args: &RuntimeArgs, + holds_epoch: Option, + chainspec: &Chainspec, + ) -> Result { + match entry_point { + TransactionEntryPoint::Custom(_) | TransactionEntryPoint::Transfer => { + Err(AuctionMethodError::InvalidEntryPoint(entry_point)) + } + TransactionEntryPoint::ActivateBid => Self::new_activate_bid(runtime_args), + TransactionEntryPoint::AddBid => Self::new_add_bid(runtime_args, holds_epoch), + TransactionEntryPoint::WithdrawBid => Self::new_withdraw_bid(runtime_args), + TransactionEntryPoint::Delegate => Self::new_delegate( + runtime_args, + chainspec.core_config.max_delegators_per_validator, + chainspec.core_config.minimum_delegation_amount, + holds_epoch, + ), + TransactionEntryPoint::Undelegate => Self::new_undelegate(runtime_args), + TransactionEntryPoint::Redelegate => Self::new_redelegate( + runtime_args, + chainspec.core_config.minimum_delegation_amount, + ), + } + } + + fn new_activate_bid(runtime_args: &RuntimeArgs) -> Result { let validator = Self::get_named_argument(runtime_args, auction::ARG_VALIDATOR)?; Ok(Self::ActivateBid { validator }) } - pub fn new_add_bid( + fn new_add_bid( runtime_args: &RuntimeArgs, holds_epoch: Option, - ) -> Result { + ) -> Result { let public_key = Self::get_named_argument(runtime_args, auction::ARG_PUBLIC_KEY)?; let delegation_rate = Self::get_named_argument(runtime_args, auction::ARG_DELEGATION_RATE)?; let amount = Self::get_named_argument(runtime_args, auction::ARG_AMOUNT)?; @@ -91,18 +121,18 @@ impl AuctionMethod { }) } - pub fn new_withdraw_bid(runtime_args: &RuntimeArgs) -> Result { + fn new_withdraw_bid(runtime_args: &RuntimeArgs) -> Result { let public_key = Self::get_named_argument(runtime_args, auction::ARG_PUBLIC_KEY)?; let amount = Self::get_named_argument(runtime_args, auction::ARG_AMOUNT)?; Ok(Self::WithdrawBid { public_key, amount }) } - pub fn new_delegate( + fn new_delegate( runtime_args: &RuntimeArgs, max_delegators_per_validator: u32, minimum_delegation_amount: u64, holds_epoch: Option, - ) -> Result { + ) -> Result { let delegator = Self::get_named_argument(runtime_args, auction::ARG_DELEGATOR)?; let validator = Self::get_named_argument(runtime_args, auction::ARG_VALIDATOR)?; let amount = Self::get_named_argument(runtime_args, auction::ARG_AMOUNT)?; @@ -117,7 +147,7 @@ impl AuctionMethod { }) } - pub fn new_undelegate(runtime_args: &RuntimeArgs) -> Result { + fn new_undelegate(runtime_args: &RuntimeArgs) -> Result { let delegator = Self::get_named_argument(runtime_args, auction::ARG_DELEGATOR)?; let validator = Self::get_named_argument(runtime_args, auction::ARG_VALIDATOR)?; let amount = Self::get_named_argument(runtime_args, auction::ARG_AMOUNT)?; @@ -129,10 +159,10 @@ impl AuctionMethod { }) } - pub fn new_redelegate( + fn new_redelegate( runtime_args: &RuntimeArgs, minimum_delegation_amount: u64, - ) -> Result { + ) -> Result { let delegator = Self::get_named_argument(runtime_args, auction::ARG_DELEGATOR)?; let validator = Self::get_named_argument(runtime_args, auction::ARG_VALIDATOR)?; let amount = Self::get_named_argument(runtime_args, auction::ARG_AMOUNT)?; @@ -150,15 +180,14 @@ impl AuctionMethod { fn get_named_argument( args: &RuntimeArgs, name: &str, - ) -> Result { + ) -> Result { let arg: &CLValue = args .get(name) - .ok_or_else(|| InvalidAuctionRuntimeArgs::MissingArg(name.to_string()))?; - arg.to_t() - .map_err(|error| InvalidAuctionRuntimeArgs::CLValue { - arg: name.to_string(), - error, - }) + .ok_or_else(|| AuctionMethodError::MissingArg(name.to_string()))?; + arg.to_t().map_err(|error| AuctionMethodError::CLValue { + arg: name.to_string(), + error, + }) } } diff --git a/types/src/block_time.rs b/types/src/block_time.rs index 8b420581e6..c913371961 100644 --- a/types/src/block_time.rs +++ b/types/src/block_time.rs @@ -53,9 +53,15 @@ impl From for Timestamp { } } +impl From for BlockTime { + fn from(value: u64) -> Self { + BlockTime(value) + } +} + impl From for BlockTime { fn from(value: Timestamp) -> Self { - BlockTime::new(value.millis()) + BlockTime(value.millis()) } } diff --git a/types/src/lib.rs b/types/src/lib.rs index 6c9b11b97e..fdf4c9603d 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -121,7 +121,7 @@ pub use chainspec::{ MintCosts, NetworkConfig, NextUpgrade, OpcodeCosts, ProtocolConfig, ProtocolUpgradeConfig, RefundHandling, StandardPaymentCosts, StorageCosts, SystemConfig, TransactionConfig, TransactionV1Config, ValidatorConfig, WasmConfig, DEFAULT_BALANCE_HOLD_INTERVAL, - DEFAULT_FEE_HANDLING, DEFAULT_HOST_FUNCTION_NEW_DICTIONARY, DEFAULT_REFUND_HANDLING, + DEFAULT_HOST_FUNCTION_NEW_DICTIONARY, DEFAULT_REFUND_HANDLING, }; #[cfg(any(all(feature = "std", feature = "testing"), test))] pub use chainspec::{ @@ -134,10 +134,10 @@ pub use chainspec::{ DEFAULT_CONTROL_FLOW_IF_OPCODE, DEFAULT_CONTROL_FLOW_LOOP_OPCODE, DEFAULT_CONTROL_FLOW_RETURN_OPCODE, DEFAULT_CONTROL_FLOW_SELECT_OPCODE, DEFAULT_CONVERSION_COST, DEFAULT_CURRENT_MEMORY_COST, DEFAULT_DELEGATE_COST, DEFAULT_DIV_COST, - DEFAULT_GLOBAL_COST, DEFAULT_GROW_MEMORY_COST, DEFAULT_INSTALL_UPGRADE_GAS_LIMIT, - DEFAULT_INTEGER_COMPARISON_COST, DEFAULT_LOAD_COST, DEFAULT_LOCAL_COST, - DEFAULT_MAX_PAYMENT_MOTES, DEFAULT_MAX_STACK_HEIGHT, DEFAULT_MIN_TRANSFER_MOTES, - DEFAULT_MUL_COST, DEFAULT_NEW_DICTIONARY_COST, DEFAULT_NOP_COST, + DEFAULT_FEE_HANDLING, DEFAULT_GLOBAL_COST, DEFAULT_GROW_MEMORY_COST, + DEFAULT_INSTALL_UPGRADE_GAS_LIMIT, DEFAULT_INTEGER_COMPARISON_COST, DEFAULT_LOAD_COST, + DEFAULT_LOCAL_COST, DEFAULT_MAX_PAYMENT_MOTES, DEFAULT_MAX_STACK_HEIGHT, + DEFAULT_MIN_TRANSFER_MOTES, DEFAULT_MUL_COST, DEFAULT_NEW_DICTIONARY_COST, DEFAULT_NOP_COST, DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT, DEFAULT_STORE_COST, DEFAULT_TRANSFER_COST, DEFAULT_UNREACHABLE_COST, DEFAULT_WASM_MAX_MEMORY, }; diff --git a/types/src/transaction/deploy.rs b/types/src/transaction/deploy.rs index aefdc29a73..c02c0a4277 100644 --- a/types/src/transaction/deploy.rs +++ b/types/src/transaction/deploy.rs @@ -48,8 +48,8 @@ use crate::{ METHOD_REDELEGATE, METHOD_UNDELEGATE, METHOD_WITHDRAW_BID, }, testing::TestRng, - AddressableEntityHash, Gas, RuntimeArgs, TransactionConfig, DEFAULT_MAX_PAYMENT_MOTES, - DEFAULT_MIN_TRANSFER_MOTES, U512, + AddressableEntityHash, RuntimeArgs, TransactionConfig, DEFAULT_MAX_PAYMENT_MOTES, + DEFAULT_MIN_TRANSFER_MOTES, }; use crate::{ bytesrepr::{self, FromBytes, ToBytes}, @@ -58,7 +58,7 @@ use crate::{ Digest, DisplayIter, PublicKey, SecretKey, TimeDiff, Timestamp, TransactionCategory, }; #[cfg(any(feature = "std", test))] -use crate::{system::auction::ARG_AMOUNT, transaction::GasLimited, Motes, SystemConfig}; +use crate::{system::auction::ARG_AMOUNT, transaction::GasLimited, Gas, Motes, SystemConfig, U512}; #[cfg(any(feature = "std", test))] pub use deploy_builder::{DeployBuilder, DeployBuilderError}; pub use deploy_category::DeployCategory; From ece291410aabaf21dd5af9faf055e4cef52aabef Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Wed, 20 Mar 2024 14:56:33 +0000 Subject: [PATCH 26/70] avoid cloning transaction when constructing WasmV1Request --- execution_engine/src/engine_state/wasm_v1.rs | 159 ++++--- .../src/execute_request_builder.rs | 55 ++- .../tests/src/test/check_transfer_success.rs | 6 +- .../contract_api/account/authorized_keys.rs | 256 ++++++------ .../account/key_management_thresholds.rs | 34 +- .../test/contract_api/add_contract_version.rs | 14 +- .../tests/src/test/contract_api/dictionary.rs | 2 +- .../src/test/contract_api/get_call_stack.rs | 212 +++++----- .../tests/src/test/contract_api/get_phase.rs | 36 +- .../contract_api/list_authorization_keys.rs | 30 +- .../contract_api/multisig_authorization.rs | 26 +- .../tests/src/test/contract_api/runtime.rs | 34 +- .../src/test/deploy/context_association.rs | 18 +- .../src/test/deploy/non_standard_payment.rs | 33 +- .../tests/src/test/deploy/preconditions.rs | 32 +- .../tests/src/test/deploy/stored_contracts.rs | 303 +++++++------- .../tests/src/test/explorer/faucet.rs | 72 ++-- .../src/test/explorer/faucet_test_helpers.rs | 24 +- .../tests/src/test/gas_counter.rs | 44 +- .../tests/src/test/groups.rs | 391 ++++++++---------- .../src/test/private_chain/management.rs | 308 ++++++-------- .../private_chain/unrestricted_transfers.rs | 116 +++--- .../tests/src/test/regression/ee_1129.rs | 158 ++++--- .../tests/src/test/regression/ee_1163.rs | 2 +- .../tests/src/test/regression/ee_1225.rs | 28 +- .../tests/src/test/regression/ee_441.rs | 28 +- .../tests/src/test/regression/ee_550.rs | 48 +-- .../tests/src/test/regression/ee_598.rs | 30 +- .../tests/src/test/regression/ee_601.rs | 26 +- .../tests/src/test/regression/ee_890.rs | 4 +- .../tests/src/test/regression/ee_966.rs | 4 +- .../tests/src/test/regression/gh_1688.rs | 34 +- .../tests/src/test/regression/gh_1902.rs | 165 ++++---- .../tests/src/test/regression/gh_2280.rs | 342 ++++++++------- .../tests/src/test/regression/gh_3208.rs | 104 +++-- .../tests/src/test/regression/gov_42.rs | 59 ++- ...host_function_metrics_size_and_gas_cost.rs | 38 +- .../test/regression/regression_20210707.rs | 84 ++-- .../test/regression/regression_20210924.rs | 98 +++-- .../test/regression/regression_20211110.rs | 54 ++- .../test/regression/regression_20220224.rs | 30 +- .../regression/transforms_must_be_ordered.rs | 2 +- .../handle_payment/finalize_payment.rs | 24 +- .../handle_payment/refund_purse.rs | 34 +- .../test/system_contracts/standard_payment.rs | 96 ++--- .../tests/src/test/system_costs.rs | 24 +- .../components/contract_runtime/operations.rs | 6 +- 47 files changed, 1725 insertions(+), 2002 deletions(-) diff --git a/execution_engine/src/engine_state/wasm_v1.rs b/execution_engine/src/engine_state/wasm_v1.rs index 5887486210..9d59fe554b 100644 --- a/execution_engine/src/engine_state/wasm_v1.rs +++ b/execution_engine/src/engine_state/wasm_v1.rs @@ -44,7 +44,7 @@ pub enum InvalidRequest { /// The item to be executed. #[derive(Debug)] -pub enum ExecutableItem { +pub enum ExecutableItem<'a> { /// A stored entity or package. Stored(TransactionInvocationTarget), /// Compiled Wasm from a transaction >= V1 as byte code. @@ -52,15 +52,15 @@ pub enum ExecutableItem { /// The kind of session. kind: TransactionSessionKind, /// The compiled Wasm. - module_bytes: Bytes, + module_bytes: &'a Bytes, }, /// Compiled Wasm from a deploy as byte code. - DeploySessionModuleBytes(Bytes), + DeploySessionModuleBytes(&'a Bytes), /// Module bytes to be used as custom payment. - CustomPayment(Bytes), + CustomPayment(&'a Bytes), } -impl ExecutableItem { +impl<'a> ExecutableItem<'a> { pub(super) fn phase(&self) -> Phase { match self { ExecutableItem::Stored(_) @@ -73,7 +73,7 @@ impl ExecutableItem { /// A request to execute the given Wasm on the V1 runtime. #[derive(Debug)] -pub struct WasmV1Request { +pub struct WasmV1Request<'a> { /// State root hash of the global state in which the transaction will be executed. pub state_hash: Digest, /// Block time represented as a unix timestamp. @@ -85,7 +85,7 @@ pub struct WasmV1Request { /// The transaction's initiator. pub initiator_addr: InitiatorAddr, /// The executable item. - pub executable_item: ExecutableItem, + pub executable_item: ExecutableItem<'a>, /// The entry point to call when executing. pub entry_point: String, /// The runtime args. @@ -94,13 +94,13 @@ pub struct WasmV1Request { pub authorization_keys: BTreeSet, } -impl WasmV1Request { +impl<'a> WasmV1Request<'a> { /// Creates a new request from a transaction for use as the session code. pub fn new_session( state_hash: Digest, block_time: BlockTime, gas_limit: Gas, - txn: Transaction, + txn: &'a Transaction, ) -> Result { let transaction_hash = txn.hash(); let initiator_addr = txn.initiator_addr(); @@ -108,9 +108,7 @@ impl WasmV1Request { let session_info = match txn { Transaction::Deploy(deploy) => { - let (hash, _header, _payment, session_deploy_item, _approvals) = - deploy.destructure(); - SessionInfo::try_from((session_deploy_item, hash))? + SessionInfo::try_from((deploy.session(), deploy.hash()))? } Transaction::V1(v1_txn) => SessionInfo::try_from(v1_txn)?, }; @@ -133,7 +131,7 @@ impl WasmV1Request { state_hash: Digest, block_time: BlockTime, gas_limit: Gas, - txn: Transaction, + txn: &'a Transaction, ) -> Result { let transaction_hash = txn.hash(); let initiator_addr = txn.initiator_addr(); @@ -141,9 +139,7 @@ impl WasmV1Request { let payment_info = match txn { Transaction::Deploy(deploy) => { - let (hash, _header, payment_deploy_item, _session, _approvals) = - deploy.destructure(); - PaymentInfo::try_from((payment_deploy_item, hash))? + PaymentInfo::try_from((deploy.payment(), deploy.hash()))? } Transaction::V1(v1_txn) => PaymentInfo::try_from(v1_txn)?, }; @@ -169,24 +165,24 @@ impl WasmV1Request { block_time: BlockTime, gas_limit: Gas, DeployItem { - address, - session, - authorization_keys, - deploy_hash, + ref address, + ref session, + ref authorization_keys, + ref deploy_hash, .. - }: DeployItem, + }: &'a DeployItem, ) -> Result { let session_info = SessionInfo::try_from((session, deploy_hash))?; Ok(Self { state_hash, block_time, - transaction_hash: TransactionHash::Deploy(deploy_hash), + transaction_hash: TransactionHash::Deploy(*deploy_hash), gas_limit, - initiator_addr: InitiatorAddr::AccountHash(address), + initiator_addr: InitiatorAddr::AccountHash(*address), executable_item: session_info.session, entry_point: session_info.entry_point, args: session_info.args, - authorization_keys, + authorization_keys: authorization_keys.clone(), }) } @@ -198,24 +194,24 @@ impl WasmV1Request { block_time: BlockTime, gas_limit: Gas, DeployItem { - address, - payment, - authorization_keys, - deploy_hash, + ref address, + ref payment, + ref authorization_keys, + ref deploy_hash, .. - }: DeployItem, + }: &'a DeployItem, ) -> Result { let payment_info = PaymentInfo::try_from((payment, deploy_hash))?; Ok(Self { state_hash, block_time, - transaction_hash: TransactionHash::Deploy(deploy_hash), + transaction_hash: TransactionHash::Deploy(*deploy_hash), gas_limit, - initiator_addr: InitiatorAddr::AccountHash(address), + initiator_addr: InitiatorAddr::AccountHash(*address), executable_item: payment_info.payment, entry_point: DEFAULT_ENTRY_POINT.to_string(), args: payment_info.args, - authorization_keys, + authorization_keys: authorization_keys.clone(), }) } } @@ -376,36 +372,37 @@ impl WasmV1Result { /// Helper struct to carry the appropriate info for converting an `ExecutableDeployItem` or a /// `TransactionV1` into the corresponding fields of a `WasmV1Request` for execution as session /// code. -struct SessionInfo { - session: ExecutableItem, +struct SessionInfo<'a> { + session: ExecutableItem<'a>, entry_point: String, args: RuntimeArgs, } -impl TryFrom<(ExecutableDeployItem, DeployHash)> for SessionInfo { +impl<'a> TryFrom<(&'a ExecutableDeployItem, &'a DeployHash)> for SessionInfo<'a> { type Error = InvalidRequest; fn try_from( - (session_item, deploy_hash): (ExecutableDeployItem, DeployHash), + (session_item, deploy_hash): (&'a ExecutableDeployItem, &'a DeployHash), ) -> Result { - let session: ExecutableItem; + let session: ExecutableItem<'a>; let session_entry_point: String; let session_args: RuntimeArgs; match session_item { ExecutableDeployItem::ModuleBytes { module_bytes, args } => { session = ExecutableItem::DeploySessionModuleBytes(module_bytes); session_entry_point = DEFAULT_ENTRY_POINT.to_string(); - session_args = args; + session_args = args.clone(); } ExecutableDeployItem::StoredContractByHash { hash, entry_point, args, } => { - session = - ExecutableItem::Stored(TransactionInvocationTarget::new_invocable_entity(hash)); - session_entry_point = entry_point; - session_args = args; + session = ExecutableItem::Stored( + TransactionInvocationTarget::new_invocable_entity(*hash), + ); + session_entry_point = entry_point.clone(); + session_args = args.clone(); } ExecutableDeployItem::StoredContractByName { name, @@ -413,10 +410,10 @@ impl TryFrom<(ExecutableDeployItem, DeployHash)> for SessionInfo { args, } => { session = ExecutableItem::Stored( - TransactionInvocationTarget::new_invocable_entity_alias(name), + TransactionInvocationTarget::new_invocable_entity_alias(name.clone()), ); - session_entry_point = entry_point; - session_args = args; + session_entry_point = entry_point.clone(); + session_args = args.clone(); } ExecutableDeployItem::StoredVersionedContractByHash { hash, @@ -424,10 +421,11 @@ impl TryFrom<(ExecutableDeployItem, DeployHash)> for SessionInfo { entry_point, args, } => { - session = - ExecutableItem::Stored(TransactionInvocationTarget::new_package(hash, version)); - session_entry_point = entry_point; - session_args = args; + session = ExecutableItem::Stored(TransactionInvocationTarget::new_package( + *hash, *version, + )); + session_entry_point = entry_point.clone(); + session_args = args.clone(); } ExecutableDeployItem::StoredVersionedContractByName { name, @@ -436,13 +434,14 @@ impl TryFrom<(ExecutableDeployItem, DeployHash)> for SessionInfo { args, } => { session = ExecutableItem::Stored(TransactionInvocationTarget::new_package_alias( - name, version, + name.clone(), + *version, )); - session_entry_point = entry_point; - session_args = args; + session_entry_point = entry_point.clone(); + session_args = args.clone(); } ExecutableDeployItem::Transfer { .. } => { - return Err(InvalidRequest::InvalidSessionDeployItem(deploy_hash)); + return Err(InvalidRequest::InvalidSessionDeployItem(*deploy_hash)); } } @@ -454,29 +453,31 @@ impl TryFrom<(ExecutableDeployItem, DeployHash)> for SessionInfo { } } -impl TryFrom for SessionInfo { +impl<'a> TryFrom<&'a TransactionV1> for SessionInfo<'a> { type Error = InvalidRequest; - fn try_from(v1_txn: TransactionV1) -> Result { - let (hash, _header, body, _approvals) = v1_txn.destructure(); - let (args, target, entry_point, _scheduling) = body.destructure(); - let session = match target { + fn try_from(v1_txn: &'a TransactionV1) -> Result { + let args = v1_txn.args().clone(); + let session = match v1_txn.target() { TransactionTarget::Native => { - return Err(InvalidRequest::InvalidSessionV1Target(hash)); + return Err(InvalidRequest::InvalidSessionV1Target(*v1_txn.hash())); } - TransactionTarget::Stored { id, .. } => ExecutableItem::Stored(id), + TransactionTarget::Stored { id, .. } => ExecutableItem::Stored(id.clone()), TransactionTarget::Session { kind, module_bytes, .. - } => ExecutableItem::SessionModuleBytes { kind, module_bytes }, + } => ExecutableItem::SessionModuleBytes { + kind: *kind, + module_bytes, + }, }; - let TransactionEntryPoint::Custom(entry_point) = entry_point else { - return Err(InvalidRequest::InvalidSessionV1EntryPoint(hash)); + let TransactionEntryPoint::Custom(entry_point) = v1_txn.entry_point() else { + return Err(InvalidRequest::InvalidSessionV1EntryPoint(*v1_txn.hash())); }; Ok(SessionInfo { session, - entry_point, + entry_point: entry_point.clone(), args, }) } @@ -485,25 +486,25 @@ impl TryFrom for SessionInfo { /// Helper struct to carry the appropriate info for converting an `ExecutableDeployItem` or a /// `TransactionV1` into the corresponding fields of a `WasmV1Request` for execution as custom /// payment. -struct PaymentInfo { - payment: ExecutableItem, +struct PaymentInfo<'a> { + payment: ExecutableItem<'a>, args: RuntimeArgs, } -impl TryFrom<(ExecutableDeployItem, DeployHash)> for PaymentInfo { +impl<'a> TryFrom<(&'a ExecutableDeployItem, &'a DeployHash)> for PaymentInfo<'a> { type Error = InvalidRequest; fn try_from( - (payment_item, deploy_hash): (ExecutableDeployItem, DeployHash), + (payment_item, deploy_hash): (&'a ExecutableDeployItem, &'a DeployHash), ) -> Result { match payment_item { ExecutableDeployItem::ModuleBytes { module_bytes, args } => { if module_bytes.is_empty() { - return Err(InvalidRequest::EmptyCustomPaymentBytes(deploy_hash)); + return Err(InvalidRequest::EmptyCustomPaymentBytes(*deploy_hash)); } Ok(PaymentInfo { payment: ExecutableItem::CustomPayment(module_bytes), - args, + args: args.clone(), }) } ExecutableDeployItem::StoredContractByHash { .. } @@ -511,43 +512,41 @@ impl TryFrom<(ExecutableDeployItem, DeployHash)> for PaymentInfo { | ExecutableDeployItem::StoredVersionedContractByHash { .. } | ExecutableDeployItem::StoredVersionedContractByName { .. } | ExecutableDeployItem::Transfer { .. } => { - Err(InvalidRequest::InvalidPaymentDeployItem(deploy_hash)) + Err(InvalidRequest::InvalidPaymentDeployItem(*deploy_hash)) } } } } -impl TryFrom for PaymentInfo { +impl<'a> TryFrom<&'a TransactionV1> for PaymentInfo<'a> { type Error = InvalidRequest; - fn try_from(v1_txn: TransactionV1) -> Result { - let (hash, header, body, _approvals) = v1_txn.destructure(); - let (_args, target, _entry_point, _scheduling) = body.destructure(); + fn try_from(v1_txn: &'a TransactionV1) -> Result { // TODO - check this is using the correct value (i.e. we don't need to account for gas_price // here). - let payment_amount = match header.pricing_mode() { + let payment_amount = match v1_txn.pricing_mode() { PricingMode::Classic { payment_amount, standard_payment, .. } => { if *standard_payment { - return Err(InvalidRequest::InvalidPricingMode(hash)); + return Err(InvalidRequest::InvalidPricingMode(*v1_txn.hash())); } *payment_amount } PricingMode::Fixed { .. } | PricingMode::Reserved { .. } => { - return Err(InvalidRequest::InvalidPricingMode(hash)); + return Err(InvalidRequest::InvalidPricingMode(*v1_txn.hash())); } }; - let payment = match target { + let payment = match v1_txn.target() { // TODO - should we also consider the session kind here? TransactionTarget::Session { module_bytes, .. } => { ExecutableItem::CustomPayment(module_bytes) } TransactionTarget::Native | TransactionTarget::Stored { .. } => { - return Err(InvalidRequest::InvalidSessionV1Target(hash)); + return Err(InvalidRequest::InvalidSessionV1Target(*v1_txn.hash())); } }; let args = runtime_args! { ARG_AMOUNT => U512::from(payment_amount)}; diff --git a/execution_engine_testing/test_support/src/execute_request_builder.rs b/execution_engine_testing/test_support/src/execute_request_builder.rs index e9ead4d9e1..4bfc9c9a6d 100644 --- a/execution_engine_testing/test_support/src/execute_request_builder.rs +++ b/execution_engine_testing/test_support/src/execute_request_builder.rs @@ -13,31 +13,31 @@ use crate::{DeployItemBuilder, ARG_AMOUNT, DEFAULT_BLOCK_TIME, DEFAULT_PAYMENT}; /// A request comprising a [`WasmV1Request`] for use as session code, and an optional custom /// payment `WasmV1Request`. -pub struct ExecuteRequest { +pub struct ExecuteRequest<'a> { /// The session request. - pub session: WasmV1Request, + pub session: WasmV1Request<'a>, /// The optional custom payment request. - pub custom_payment: Option, + pub custom_payment: Option>, } /// Builds an [`ExecuteRequest`]. #[derive(Debug)] -pub struct ExecuteRequestBuilder { +pub struct ExecuteRequestBuilder<'a> { state_hash: Digest, block_time: BlockTime, transaction_hash: TransactionHash, initiator_addr: InitiatorAddr, - payment: Option, + payment: Option>, payment_gas_limit: Gas, payment_args: RuntimeArgs, - session: ExecutableItem, + session: ExecutableItem<'a>, session_gas_limit: Gas, session_entry_point: String, session_args: RuntimeArgs, authorization_keys: BTreeSet, } -impl ExecuteRequestBuilder { +impl<'a> ExecuteRequestBuilder<'a> { /// The default value used for `WasmV1Request::state_hash`. pub const DEFAULT_STATE_HASH: Digest = Digest::from_raw([1; 32]); /// The default value used for `WasmV1Request::transaction_hash`. @@ -47,13 +47,13 @@ impl ExecuteRequestBuilder { pub const DEFAULT_ENTRY_POINT: &'static str = "call"; /// Converts a `Transaction` into an `ExecuteRequestBuilder`. - pub fn from_transaction(txn: Transaction) -> Self { + pub fn from_transaction(txn: &'a Transaction) -> Self { let authorization_keys = txn.authorization_keys(); let session = WasmV1Request::new_session( Self::DEFAULT_STATE_HASH, BlockTime::new(DEFAULT_BLOCK_TIME), Gas::new(DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT), // TODO - set proper value - txn.clone(), + txn, ) .unwrap(); @@ -94,13 +94,13 @@ impl ExecuteRequestBuilder { } /// Converts a `DeployItem` into an `ExecuteRequestBuilder`. - pub fn from_deploy_item(deploy_item: DeployItem) -> Self { + pub fn from_deploy_item(deploy_item: &'a DeployItem) -> Self { let authorization_keys = deploy_item.authorization_keys.clone(); let session = WasmV1Request::new_session_from_deploy_item( Self::DEFAULT_STATE_HASH, BlockTime::new(DEFAULT_BLOCK_TIME), Gas::new(DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT), // TODO - set proper value - deploy_item.clone(), + deploy_item, ) .unwrap(); @@ -140,7 +140,7 @@ impl ExecuteRequestBuilder { } } - /// Returns an [`WasmV1Request`] derived from a deploy with standard dependencies. + /// Returns an [`ExecuteRequest`] derived from a deploy with standard dependencies. pub fn standard( account_hash: AccountHash, session_file: &str, @@ -154,10 +154,10 @@ impl ExecuteRequestBuilder { }) .with_authorization_keys(&[account_hash]) .build(); - Self::from_deploy_item(deploy_item) + Self::from_deploy_item(Box::leak(Box::new(deploy_item))) } - /// Returns an [`WasmV1Request`] derived from a deploy with session module bytes. + /// Returns an [`ExecuteRequest`] derived from a deploy with session module bytes. pub fn module_bytes( account_hash: AccountHash, module_bytes: Vec, @@ -171,10 +171,10 @@ impl ExecuteRequestBuilder { }) .with_authorization_keys(&[account_hash]) .build(); - Self::from_deploy_item(deploy_item) + Self::from_deploy_item(Box::leak(Box::new(deploy_item))) } - /// Returns an [`WasmV1Request`] derived from a deploy with a session item that will call a + /// Returns an [`ExecuteRequest`] derived from a deploy with a session item that will call a /// stored contract by hash. pub fn contract_call_by_hash( sender: AccountHash, @@ -188,10 +188,10 @@ impl ExecuteRequestBuilder { .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[sender]) .build(); - Self::from_deploy_item(deploy_item) + Self::from_deploy_item(Box::leak(Box::new(deploy_item))) } - /// Returns an [`WasmV1Request`] derived from a deploy with a session item that will call a + /// Returns an [`ExecuteRequest`] derived from a deploy with a session item that will call a /// stored contract by name. pub fn contract_call_by_name( sender: AccountHash, @@ -205,10 +205,10 @@ impl ExecuteRequestBuilder { .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[sender]) .build(); - Self::from_deploy_item(deploy_item) + Self::from_deploy_item(Box::leak(Box::new(deploy_item))) } - /// Returns an [`WasmV1Request`] derived from a deploy with a session item that will call a + /// Returns an [`ExecuteRequest`] derived from a deploy with a session item that will call a /// versioned stored contract by hash. pub fn versioned_contract_call_by_hash( sender: AccountHash, @@ -228,10 +228,10 @@ impl ExecuteRequestBuilder { .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[sender]) .build(); - Self::from_deploy_item(deploy_item) + Self::from_deploy_item(Box::leak(Box::new(deploy_item))) } - /// Returns an [`WasmV1Request`] derived from a deploy with a session item that will call a + /// Returns an [`ExecuteRequest`] derived from a deploy with a session item that will call a /// versioned stored contract by name. pub fn versioned_contract_call_by_name( sender: AccountHash, @@ -246,24 +246,23 @@ impl ExecuteRequestBuilder { .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[sender]) .build(); - Self::from_deploy_item(deploy_item) + Self::from_deploy_item(Box::leak(Box::new(deploy_item))) } - /// Sets the block time of the [`WasmV1Request`]. + /// Sets the block time of the [`WasmV1Request`]s. pub fn with_block_time>(mut self, block_time: T) -> Self { self.block_time = block_time.into(); self } - /// Sets the authorization keys used by the [`WasmV1Request`]. + /// Sets the authorization keys used by the [`WasmV1Request`]s. pub fn with_authorization_keys(mut self, authorization_keys: BTreeSet) -> Self { self.authorization_keys = authorization_keys; self } - /// Consumes self and returns a session `WasmV1Request` and an optional custom payment - /// `WasmV1Request`. - pub fn build(self) -> ExecuteRequest { + /// Consumes self and returns an `ExecuteRequest`. + pub fn build(self) -> ExecuteRequest<'a> { let ExecuteRequestBuilder { state_hash, block_time, diff --git a/execution_engine_testing/tests/src/test/check_transfer_success.rs b/execution_engine_testing/tests/src/test/check_transfer_success.rs index 1e2cd5c079..821bc5fefa 100644 --- a/execution_engine_testing/tests/src/test/check_transfer_success.rs +++ b/execution_engine_testing/tests/src/test/check_transfer_success.rs @@ -56,7 +56,7 @@ fn test_check_transfer_success_with_source_only() { .build(); // build a request to execute the deploy. - let exec_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(genesis_request).commit(); @@ -118,7 +118,7 @@ fn test_check_transfer_success_with_source_only_errors() { .with_deploy_hash([42; 32]) .build(); - let exec_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); // Set up test builder and run genesis. let mut builder = LmdbWasmTestBuilder::default(); @@ -175,7 +175,7 @@ fn test_check_transfer_success_with_source_and_target() { .with_deploy_hash([42; 32]) .build(); - let exec_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(genesis_request).commit(); diff --git a/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs b/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs index f39bdc5498..a7a7cbdca8 100644 --- a/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs +++ b/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs @@ -48,22 +48,20 @@ fn should_raise_auth_failure_with_invalid_key() { // Error::Authorization assert_ne!(*DEFAULT_ACCOUNT_ADDR, KEY_1); - let exec_request = { - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_session_code( - CONTRACT_SET_ACTION_THRESHOLDS, - runtime_args! { - ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(1), - ARG_DEPLOY_THRESHOLD => Weight::new(1) - }, - ) - .with_deploy_hash([1u8; 32]) - .with_authorization_keys(&[KEY_1]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy).build() - }; + let deploy = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_session_code( + CONTRACT_SET_ACTION_THRESHOLDS, + runtime_args! { + ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(1), + ARG_DEPLOY_THRESHOLD => Weight::new(1) + }, + ) + .with_deploy_hash([1u8; 32]) + .with_authorization_keys(&[KEY_1]) + .build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy).build(); // Basic deploy with single key let mut builder = LmdbWasmTestBuilder::default(); @@ -101,22 +99,20 @@ fn should_raise_auth_failure_with_invalid_keys() { assert_ne!(*DEFAULT_ACCOUNT_ADDR, KEY_2); assert_ne!(*DEFAULT_ACCOUNT_ADDR, KEY_3); - let exec_request = { - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_session_code( - CONTRACT_SET_ACTION_THRESHOLDS, - runtime_args! { - ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(1), - ARG_DEPLOY_THRESHOLD => Weight::new(1) - }, - ) - .with_deploy_hash([1u8; 32]) - .with_authorization_keys(&[KEY_2, KEY_1, KEY_3]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy).build() - }; + let deploy = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_session_code( + CONTRACT_SET_ACTION_THRESHOLDS, + runtime_args! { + ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(1), + ARG_DEPLOY_THRESHOLD => Weight::new(1) + }, + ) + .with_deploy_hash([1u8; 32]) + .with_authorization_keys(&[KEY_2, KEY_1, KEY_3]) + .build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy).build(); // Basic deploy with single key let mut builder = LmdbWasmTestBuilder::default(); @@ -201,23 +197,21 @@ fn should_raise_deploy_authorization_failure() { .expect_success() .commit(); - let exec_request_5 = { - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - // Next deploy will see deploy threshold == 4, keymgmnt == 5 - .with_session_code( - CONTRACT_SET_ACTION_THRESHOLDS, - runtime_args! { - ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(5), - ARG_DEPLOY_THRESHOLD => Weight::new(4) - }, //args - ) - .with_deploy_hash([5u8; 32]) - .with_authorization_keys(&[KEY_1]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy).build() - }; + let deploy = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + // Next deploy will see deploy threshold == 4, keymgmnt == 5 + .with_session_code( + CONTRACT_SET_ACTION_THRESHOLDS, + runtime_args! { + ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(5), + ARG_DEPLOY_THRESHOLD => Weight::new(4) + }, //args + ) + .with_deploy_hash([5u8; 32]) + .with_authorization_keys(&[KEY_1]) + .build(); + let exec_request_5 = ExecuteRequestBuilder::from_deploy_item(&deploy).build(); // With deploy threshold == 3 using single secondary key // with weight == 2 should raise deploy authorization failure. @@ -232,23 +226,21 @@ fn should_raise_deploy_authorization_failure() { let message = format!("{}", deploy_result.error().unwrap()); assert!(message.contains(&format!("{}", ExecError::DeploymentAuthorizationFailure))) } - let exec_request_6 = { - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - // change deployment threshold to 4 - .with_session_code( - CONTRACT_SET_ACTION_THRESHOLDS, - runtime_args! { - ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(6), - ARG_DEPLOY_THRESHOLD => Weight::new(5) - }, - ) - .with_deploy_hash([6u8; 32]) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, KEY_1, KEY_2, KEY_3]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy).build() - }; + let deploy = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + // change deployment threshold to 4 + .with_session_code( + CONTRACT_SET_ACTION_THRESHOLDS, + runtime_args! { + ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(6), + ARG_DEPLOY_THRESHOLD => Weight::new(5) + }, + ) + .with_deploy_hash([6u8; 32]) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, KEY_1, KEY_2, KEY_3]) + .build(); + let exec_request_6 = ExecuteRequestBuilder::from_deploy_item(&deploy).build(); // identity key (w: 1) and KEY_1 (w: 2) passes threshold of 3 builder .clear_results() @@ -256,23 +248,21 @@ fn should_raise_deploy_authorization_failure() { .expect_success() .commit(); - let exec_request_7 = { - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - // change deployment threshold to 4 - .with_session_code( - CONTRACT_SET_ACTION_THRESHOLDS, - runtime_args! { - ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(0), - ARG_DEPLOY_THRESHOLD => Weight::new(0) - }, //args - ) - .with_deploy_hash([6u8; 32]) - .with_authorization_keys(&[KEY_2, KEY_1]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy).build() - }; + let deploy = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + // change deployment threshold to 4 + .with_session_code( + CONTRACT_SET_ACTION_THRESHOLDS, + runtime_args! { + ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(0), + ARG_DEPLOY_THRESHOLD => Weight::new(0) + }, //args + ) + .with_deploy_hash([6u8; 32]) + .with_authorization_keys(&[KEY_2, KEY_1]) + .build(); + let exec_request_7 = ExecuteRequestBuilder::from_deploy_item(&deploy).build(); // deployment threshold is now 4 // failure: KEY_2 weight + KEY_1 weight < deployment threshold @@ -289,23 +279,21 @@ fn should_raise_deploy_authorization_failure() { assert!(message.contains(&format!("{}", ExecError::DeploymentAuthorizationFailure))) } - let exec_request_8 = { - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - // change deployment threshold to 4 - .with_session_code( - CONTRACT_SET_ACTION_THRESHOLDS, - runtime_args! { - ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(0), - ARG_DEPLOY_THRESHOLD => Weight::new(0) - }, //args - ) - .with_deploy_hash([8u8; 32]) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, KEY_1, KEY_2, KEY_3]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy).build() - }; + let deploy = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + // change deployment threshold to 4 + .with_session_code( + CONTRACT_SET_ACTION_THRESHOLDS, + runtime_args! { + ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(0), + ARG_DEPLOY_THRESHOLD => Weight::new(0) + }, //args + ) + .with_deploy_hash([8u8; 32]) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, KEY_1, KEY_2, KEY_3]) + .build(); + let exec_request_8 = ExecuteRequestBuilder::from_deploy_item(&deploy).build(); // success: identity key weight + KEY_1 weight + KEY_2 weight >= deployment // threshold @@ -350,22 +338,20 @@ fn should_authorize_deploy_with_multiple_keys() { // KEY_1 (w: 2) KEY_2 (w: 2) each passes default threshold of 1 - let exec_request_3 = { - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_session_code( - CONTRACT_SET_ACTION_THRESHOLDS, - runtime_args! { - ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(0), - ARG_DEPLOY_THRESHOLD => Weight::new(0), - }, - ) - .with_deploy_hash([36; 32]) - .with_authorization_keys(&[KEY_2, KEY_1]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy).build() - }; + let deploy = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_session_code( + CONTRACT_SET_ACTION_THRESHOLDS, + runtime_args! { + ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(0), + ARG_DEPLOY_THRESHOLD => Weight::new(0), + }, + ) + .with_deploy_hash([36; 32]) + .with_authorization_keys(&[KEY_2, KEY_1]) + .build(); + let exec_request_3 = ExecuteRequestBuilder::from_deploy_item(&deploy).build(); builder.exec(exec_request_3).expect_success().commit(); } @@ -418,26 +404,24 @@ fn should_not_authorize_deploy_with_duplicated_keys() { builder.exec(exec_request_3).expect_success().commit(); - let exec_request_3 = { - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => *DEFAULT_PAYMENT, - }) - .with_session_code( - CONTRACT_SET_ACTION_THRESHOLDS, - runtime_args! { - ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(0), - ARG_DEPLOY_THRESHOLD => Weight::new(0) - }, - ) - .with_deploy_hash([3u8; 32]) - .with_authorization_keys(&[ - KEY_1, KEY_1, KEY_1, KEY_1, KEY_1, KEY_1, KEY_1, KEY_1, KEY_1, KEY_1, - ]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy).build() - }; + let deploy = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => *DEFAULT_PAYMENT, + }) + .with_session_code( + CONTRACT_SET_ACTION_THRESHOLDS, + runtime_args! { + ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(0), + ARG_DEPLOY_THRESHOLD => Weight::new(0) + }, + ) + .with_deploy_hash([3u8; 32]) + .with_authorization_keys(&[ + KEY_1, KEY_1, KEY_1, KEY_1, KEY_1, KEY_1, KEY_1, KEY_1, KEY_1, KEY_1, + ]) + .build(); + let exec_request_3 = ExecuteRequestBuilder::from_deploy_item(&deploy).build(); builder.clear_results().exec(exec_request_3).commit(); let deploy_result = builder .get_exec_result_owned(0) diff --git a/execution_engine_testing/tests/src/test/contract_api/account/key_management_thresholds.rs b/execution_engine_testing/tests/src/test/contract_api/account/key_management_thresholds.rs index c145a05484..cedaae2260 100644 --- a/execution_engine_testing/tests/src/test/contract_api/account/key_management_thresholds.rs +++ b/execution_engine_testing/tests/src/test/contract_api/account/key_management_thresholds.rs @@ -42,24 +42,22 @@ fn should_verify_key_management_permission_with_sufficient_weight() { runtime_args! { ARG_STAGE => String::from("init") }, ) .build(); - let exec_request_2 = { - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - // This test verifies that all key management operations succeed - .with_session_code( - "key_management_thresholds.wasm", - runtime_args! { ARG_STAGE => String::from("test-key-mgmnt-succeed") }, - ) - .with_deploy_hash([2u8; 32]) - .with_authorization_keys(&[ - *DEFAULT_ACCOUNT_ADDR, - // Key [42; 32] is created in init stage - AccountHash::new([42; 32]), - ]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy).build() - }; + let deploy = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + // This test verifies that all key management operations succeed + .with_session_code( + "key_management_thresholds.wasm", + runtime_args! { ARG_STAGE => String::from("test-key-mgmnt-succeed") }, + ) + .with_deploy_hash([2u8; 32]) + .with_authorization_keys(&[ + *DEFAULT_ACCOUNT_ADDR, + // Key [42; 32] is created in init stage + AccountHash::new([42; 32]), + ]) + .build(); + let exec_request_2 = ExecuteRequestBuilder::from_deploy_item(&deploy).build(); LmdbWasmTestBuilder::default() .run_genesis(LOCAL_GENESIS_REQUEST.clone()) .exec(exec_request_1) diff --git a/execution_engine_testing/tests/src/test/contract_api/add_contract_version.rs b/execution_engine_testing/tests/src/test/contract_api/add_contract_version.rs index cd4e9d5a90..0c68dd8218 100644 --- a/execution_engine_testing/tests/src/test/contract_api/add_contract_version.rs +++ b/execution_engine_testing/tests/src/test/contract_api/add_contract_version.rs @@ -31,13 +31,15 @@ fn try_add_contract_version(kind: TransactionSessionKind, should_succeed: bool) let module_bytes = utils::read_wasm_file(CONTRACT); - let txn = TransactionV1Builder::new_session(kind, module_bytes, ENTRY_POINT) - .with_secret_key(&DEFAULT_ACCOUNT_SECRET_KEY) - .with_chain_name(CHAIN_NAME) - .build() - .unwrap(); + let txn = Transaction::from( + TransactionV1Builder::new_session(kind, module_bytes, ENTRY_POINT) + .with_secret_key(&DEFAULT_ACCOUNT_SECRET_KEY) + .with_chain_name(CHAIN_NAME) + .build() + .unwrap(), + ); - let txn_request = ExecuteRequestBuilder::from_transaction(Transaction::from(txn)) + let txn_request = ExecuteRequestBuilder::from_transaction(&txn) .with_block_time(BLOCK_TIME) .build(); diff --git a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs index 869735be40..f1257b327c 100644 --- a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs +++ b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs @@ -537,7 +537,7 @@ fn should_query_dictionary_items_with_test_builder() { .with_deploy_hash([42; 32]) .build(); - let exec_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(genesis_request).commit(); diff --git a/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs b/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs index 43af88af4a..b7832283bf 100644 --- a/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs +++ b/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs @@ -3134,24 +3134,22 @@ mod payment { const DEPTHS: &[usize] = &[0, 6, 10]; fn execute(builder: &mut LmdbWasmTestBuilder, call_depth: usize, subcalls: Vec) { - let execute_request = { - let mut rng = rand::thread_rng(); - let deploy_hash = rng.gen(); - let sender = *DEFAULT_ACCOUNT_ADDR; - let args = runtime_args! { - ARG_CALLS => subcalls, - ARG_CURRENT_DEPTH => 0u8, - mint::ARG_AMOUNT => approved_amount(call_depth), - }; - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_payment_code(CONTRACT_CALL_RECURSIVE_SUBCALL, args) - .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let mut rng = rand::thread_rng(); + let deploy_hash = rng.gen(); + let sender = *DEFAULT_ACCOUNT_ADDR; + let args = runtime_args! { + ARG_CALLS => subcalls, + ARG_CURRENT_DEPTH => 0u8, + mint::ARG_AMOUNT => approved_amount(call_depth), }; + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_payment_code(CONTRACT_CALL_RECURSIVE_SUBCALL, args) + .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) + .with_authorization_keys(&[sender]) + .with_deploy_hash(deploy_hash) + .build(); + let execute_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); super::execute_and_assert_result( call_depth, @@ -3166,34 +3164,32 @@ mod payment { call_depth: usize, subcalls: Vec, ) { - let execute_request = { - let mut rng = rand::thread_rng(); - let deploy_hash = rng.gen(); - - let sender = *DEFAULT_ACCOUNT_ADDR; - - let args = runtime_args! { - ARG_CALLS => subcalls, - ARG_CURRENT_DEPTH => 0u8, - mint::ARG_AMOUNT => approved_amount(call_depth), - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_stored_versioned_payment_contract_by_name( - CONTRACT_PACKAGE_NAME, - None, - CONTRACT_FORWARDER_ENTRYPOINT_SESSION, - args, - ) - .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let mut rng = rand::thread_rng(); + let deploy_hash = rng.gen(); + + let sender = *DEFAULT_ACCOUNT_ADDR; + + let args = runtime_args! { + ARG_CALLS => subcalls, + ARG_CURRENT_DEPTH => 0u8, + mint::ARG_AMOUNT => approved_amount(call_depth), }; + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_stored_versioned_payment_contract_by_name( + CONTRACT_PACKAGE_NAME, + None, + CONTRACT_FORWARDER_ENTRYPOINT_SESSION, + args, + ) + .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) + .with_authorization_keys(&[sender]) + .with_deploy_hash(deploy_hash) + .build(); + + let execute_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); + super::execute_and_assert_result( call_depth, builder, @@ -3208,29 +3204,27 @@ mod payment { subcalls: Vec, current_contract_package_hash: HashAddr, ) { - let execute_request = { - let mut rng = rand::thread_rng(); - let deploy_hash = rng.gen(); - let sender = *DEFAULT_ACCOUNT_ADDR; - let args = runtime_args! { - ARG_CALLS => subcalls, - ARG_CURRENT_DEPTH => 0u8, - mint::ARG_AMOUNT => approved_amount(call_depth), - }; - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_stored_versioned_payment_contract_by_hash( - current_contract_package_hash, - None, - CONTRACT_FORWARDER_ENTRYPOINT_SESSION, - args, - ) - .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let mut rng = rand::thread_rng(); + let deploy_hash = rng.gen(); + let sender = *DEFAULT_ACCOUNT_ADDR; + let args = runtime_args! { + ARG_CALLS => subcalls, + ARG_CURRENT_DEPTH => 0u8, + mint::ARG_AMOUNT => approved_amount(call_depth), }; + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_stored_versioned_payment_contract_by_hash( + current_contract_package_hash, + None, + CONTRACT_FORWARDER_ENTRYPOINT_SESSION, + args, + ) + .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) + .with_authorization_keys(&[sender]) + .with_deploy_hash(deploy_hash) + .build(); + let execute_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); super::execute_and_assert_result( call_depth, @@ -3245,33 +3239,31 @@ mod payment { call_depth: usize, subcalls: Vec, ) { - let execute_request = { - let mut rng = rand::thread_rng(); - let deploy_hash = rng.gen(); - - let sender = *DEFAULT_ACCOUNT_ADDR; - - let args = runtime_args! { - ARG_CALLS => subcalls, - ARG_CURRENT_DEPTH => 0u8, - mint::ARG_AMOUNT => approved_amount(call_depth), - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_stored_payment_named_key( - CONTRACT_NAME, - CONTRACT_FORWARDER_ENTRYPOINT_SESSION, - args, - ) - .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let mut rng = rand::thread_rng(); + let deploy_hash = rng.gen(); + + let sender = *DEFAULT_ACCOUNT_ADDR; + + let args = runtime_args! { + ARG_CALLS => subcalls, + ARG_CURRENT_DEPTH => 0u8, + mint::ARG_AMOUNT => approved_amount(call_depth), }; + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_stored_payment_named_key( + CONTRACT_NAME, + CONTRACT_FORWARDER_ENTRYPOINT_SESSION, + args, + ) + .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) + .with_authorization_keys(&[sender]) + .with_deploy_hash(deploy_hash) + .build(); + + let execute_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); + super::execute_and_assert_result( call_depth, builder, @@ -3286,28 +3278,26 @@ mod payment { subcalls: Vec, current_contract_hash: HashAddr, ) { - let execute_request = { - let mut rng = rand::thread_rng(); - let deploy_hash = rng.gen(); - let sender = *DEFAULT_ACCOUNT_ADDR; - let args = runtime_args! { - ARG_CALLS => subcalls, - ARG_CURRENT_DEPTH => 0u8, - mint::ARG_AMOUNT => approved_amount(call_depth), - }; - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_stored_payment_hash( - current_contract_hash.into(), - CONTRACT_FORWARDER_ENTRYPOINT_SESSION, - args, - ) - .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let mut rng = rand::thread_rng(); + let deploy_hash = rng.gen(); + let sender = *DEFAULT_ACCOUNT_ADDR; + let args = runtime_args! { + ARG_CALLS => subcalls, + ARG_CURRENT_DEPTH => 0u8, + mint::ARG_AMOUNT => approved_amount(call_depth), }; + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_stored_payment_hash( + current_contract_hash.into(), + CONTRACT_FORWARDER_ENTRYPOINT_SESSION, + args, + ) + .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) + .with_authorization_keys(&[sender]) + .with_deploy_hash(deploy_hash) + .build(); + let execute_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let is_entry_point_type_session = true; diff --git a/execution_engine_testing/tests/src/test/contract_api/get_phase.rs b/execution_engine_testing/tests/src/test/contract_api/get_phase.rs index 65c1609156..e433d7479c 100644 --- a/execution_engine_testing/tests/src/test/contract_api/get_phase.rs +++ b/execution_engine_testing/tests/src/test/contract_api/get_phase.rs @@ -12,26 +12,24 @@ const ARG_AMOUNT: &str = "amount"; fn should_run_get_phase_contract() { let default_account = *DEFAULT_ACCOUNT_ADDR; - let exec_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_deploy_hash([1; 32]) - .with_session_code( - "get_phase.wasm", - runtime_args! { ARG_PHASE => Phase::Session }, - ) - .with_payment_code( - "get_phase_payment.wasm", - runtime_args! { - ARG_PHASE => Phase::Payment, - ARG_AMOUNT => *DEFAULT_PAYMENT - }, - ) - .with_authorization_keys(&[default_account]) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_deploy_hash([1; 32]) + .with_session_code( + "get_phase.wasm", + runtime_args! { ARG_PHASE => Phase::Session }, + ) + .with_payment_code( + "get_phase_payment.wasm", + runtime_args! { + ARG_PHASE => Phase::Payment, + ARG_AMOUNT => *DEFAULT_PAYMENT + }, + ) + .with_authorization_keys(&[default_account]) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); LmdbWasmTestBuilder::default() .run_genesis(LOCAL_GENESIS_REQUEST.clone()) diff --git a/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs b/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs index 242f5a7db8..182d5f06bb 100644 --- a/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs +++ b/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs @@ -100,23 +100,21 @@ fn test_match( expected_authorization_keys: Vec, ) -> bool { let mut builder = setup(); - let exec_request = { - let session_args = runtime_args! { - ARG_EXPECTED_AUTHORIZATION_KEYS => expected_authorization_keys - }; - let deploy_hash = [42; 32]; - - let deploy_item = DeployItemBuilder::new() - .with_address(caller) - .with_session_code(CONTRACT_LIST_AUTHORIZATION_KEYS, session_args) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => *DEFAULT_PAYMENT - }) - .with_authorization_keys(&signatures) - .with_deploy_hash(deploy_hash) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let session_args = runtime_args! { + ARG_EXPECTED_AUTHORIZATION_KEYS => expected_authorization_keys }; + let deploy_hash = [42; 32]; + + let deploy_item = DeployItemBuilder::new() + .with_address(caller) + .with_session_code(CONTRACT_LIST_AUTHORIZATION_KEYS, session_args) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => *DEFAULT_PAYMENT + }) + .with_authorization_keys(&signatures) + .with_deploy_hash(deploy_hash) + .build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request).commit(); match builder.get_error() { diff --git a/execution_engine_testing/tests/src/test/contract_api/multisig_authorization.rs b/execution_engine_testing/tests/src/test/contract_api/multisig_authorization.rs index 082ce2bb18..b825b15ca3 100644 --- a/execution_engine_testing/tests/src/test/contract_api/multisig_authorization.rs +++ b/execution_engine_testing/tests/src/test/contract_api/multisig_authorization.rs @@ -146,21 +146,19 @@ fn test_multisig_auth( authorization_keys: &[AccountHash], ) -> bool { let mut builder = setup(); - let exec_request = { - let session_args = runtime_args! {}; - let payment_args = runtime_args! { - ARG_AMOUNT => *DEFAULT_PAYMENT - }; - let deploy_hash = [42; 32]; - let deploy_item = DeployItemBuilder::new() - .with_address(caller) - .with_stored_session_named_key(CONTRACT_KEY, entry_point, session_args) - .with_empty_payment_bytes(payment_args) - .with_authorization_keys(authorization_keys) - .with_deploy_hash(deploy_hash) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let session_args = runtime_args! {}; + let payment_args = runtime_args! { + ARG_AMOUNT => *DEFAULT_PAYMENT }; + let deploy_hash = [42; 32]; + let deploy_item = DeployItemBuilder::new() + .with_address(caller) + .with_stored_session_named_key(CONTRACT_KEY, entry_point, session_args) + .with_empty_payment_bytes(payment_args) + .with_authorization_keys(authorization_keys) + .with_deploy_hash(deploy_hash) + .build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request).commit(); match builder.get_error() { diff --git a/execution_engine_testing/tests/src/test/contract_api/runtime.rs b/execution_engine_testing/tests/src/test/contract_api/runtime.rs index 90ea2ce0be..6c093d731e 100644 --- a/execution_engine_testing/tests/src/test/contract_api/runtime.rs +++ b/execution_engine_testing/tests/src/test/contract_api/runtime.rs @@ -44,24 +44,22 @@ fn should_return_different_random_bytes_on_different_phases() { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); - let execute_request = { - let mut rng = rand::thread_rng(); - let deploy_hash = rng.gen(); - let address = *DEFAULT_ACCOUNT_ADDR; - let deploy_item = DeployItemBuilder::new() - .with_address(address) - .with_session_code(RANDOM_BYTES_WASM, runtime_args! {}) - .with_payment_code( - RANDOM_BYTES_PAYMENT_WASM, - runtime_args! { - ARG_AMOUNT => *DEFAULT_PAYMENT - }, - ) - .with_authorization_keys(&[address]) - .with_deploy_hash(deploy_hash) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let mut rng = rand::thread_rng(); + let deploy_hash = rng.gen(); + let address = *DEFAULT_ACCOUNT_ADDR; + let deploy_item = DeployItemBuilder::new() + .with_address(address) + .with_session_code(RANDOM_BYTES_WASM, runtime_args! {}) + .with_payment_code( + RANDOM_BYTES_PAYMENT_WASM, + runtime_args! { + ARG_AMOUNT => *DEFAULT_PAYMENT + }, + ) + .with_authorization_keys(&[address]) + .with_deploy_hash(deploy_hash) + .build(); + let execute_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(execute_request).commit().expect_success(); diff --git a/execution_engine_testing/tests/src/test/deploy/context_association.rs b/execution_engine_testing/tests/src/test/deploy/context_association.rs index de4ceedd23..5a75f1b558 100644 --- a/execution_engine_testing/tests/src/test/deploy/context_association.rs +++ b/execution_engine_testing/tests/src/test/deploy/context_association.rs @@ -17,17 +17,15 @@ fn should_put_system_contract_hashes_to_account_context() { let payment_purse_amount = *DEFAULT_PAYMENT; let mut builder = LmdbWasmTestBuilder::default(); - let request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_session_code(SYSTEM_CONTRACT_HASHES_WASM, runtime_args! {}) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount}) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) - .with_deploy_hash([1; 32]) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_code(SYSTEM_CONTRACT_HASHES_WASM, runtime_args! {}) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount}) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) + .with_deploy_hash([1; 32]) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder .run_genesis(LOCAL_GENESIS_REQUEST.clone()) diff --git a/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs b/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs index bd48713354..cabb21db53 100644 --- a/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs +++ b/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs @@ -68,23 +68,22 @@ fn should_charge_non_main_purse() { ); // should be able to pay for exec using new purse - let account_payment_exec_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(ACCOUNT_1_ADDR) - .with_session_code(DO_NOTHING_WASM, RuntimeArgs::default()) - .with_payment_code( - NAMED_PURSE_PAYMENT_WASM, - runtime_args! { - ARG_PURSE_NAME => TEST_PURSE_NAME, - ARG_AMOUNT => payment_purse_amount - }, - ) - .with_authorization_keys(&[account_1_account_hash]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let deploy_item = DeployItemBuilder::new() + .with_address(ACCOUNT_1_ADDR) + .with_session_code(DO_NOTHING_WASM, RuntimeArgs::default()) + .with_payment_code( + NAMED_PURSE_PAYMENT_WASM, + runtime_args! { + ARG_PURSE_NAME => TEST_PURSE_NAME, + ARG_AMOUNT => payment_purse_amount + }, + ) + .with_authorization_keys(&[account_1_account_hash]) + .with_deploy_hash([3; 32]) + .build(); + + let account_payment_exec_request = + ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let proposer_reward_starting_balance = builder.get_proposer_purse_balance(); diff --git a/execution_engine_testing/tests/src/test/deploy/preconditions.rs b/execution_engine_testing/tests/src/test/deploy/preconditions.rs index 48e83fac37..a7d5964c06 100644 --- a/execution_engine_testing/tests/src/test/deploy/preconditions.rs +++ b/execution_engine_testing/tests/src/test/deploy/preconditions.rs @@ -19,8 +19,7 @@ fn should_raise_precondition_authorization_failure_invalid_account() { let payment_purse_amount = 10_000_000; let transferred_amount = 1; - let exec_request = { - let deploy_item = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_session_code( @@ -32,8 +31,7 @@ fn should_raise_precondition_authorization_failure_invalid_account() { .with_authorization_keys(&[nonexistent_account_addr]) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); builder @@ -56,18 +54,16 @@ fn should_raise_precondition_authorization_failure_invalid_account() { #[test] fn should_raise_precondition_authorization_failure_empty_authorized_keys() { let empty_keys: [AccountHash; 0] = []; - let exec_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_session_code("do_nothing.wasm", RuntimeArgs::default()) - .with_empty_payment_bytes(RuntimeArgs::default()) - .with_deploy_hash([1; 32]) - // empty authorization keys to force error - .with_authorization_keys(&empty_keys) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_code("do_nothing.wasm", RuntimeArgs::default()) + .with_empty_payment_bytes(RuntimeArgs::default()) + .with_deploy_hash([1; 32]) + // empty authorization keys to force error + .with_authorization_keys(&empty_keys) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); builder @@ -94,8 +90,7 @@ fn should_raise_precondition_authorization_failure_invalid_authorized_keys() { let payment_purse_amount = 10_000_000; let transferred_amount = 1; - let exec_request = { - let deploy_item = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_session_code( @@ -107,8 +102,7 @@ fn should_raise_precondition_authorization_failure_invalid_authorized_keys() { .with_authorization_keys(&[nonexistent_account_addr]) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); builder diff --git a/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs b/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs index 1fcb2ab9b7..990214dec6 100644 --- a/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs +++ b/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs @@ -75,25 +75,23 @@ fn should_exec_non_stored_code() { let payment_purse_amount = *DEFAULT_PAYMENT; let transferred_amount = 1; - let exec_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_session_code( - format!("{}.wasm", TRANSFER_PURSE_TO_ACCOUNT_CONTRACT_NAME), - runtime_args! { - ARG_TARGET => account_1_account_hash, - ARG_AMOUNT => U512::from(transferred_amount) - }, - ) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => payment_purse_amount, - }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) - .with_deploy_hash([1; 32]) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_code( + format!("{}.wasm", TRANSFER_PURSE_TO_ACCOUNT_CONTRACT_NAME), + runtime_args! { + ARG_TARGET => account_1_account_hash, + ARG_AMOUNT => U512::from(transferred_amount) + }, + ) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => payment_purse_amount, + }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) + .with_deploy_hash([1; 32]) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); @@ -154,21 +152,19 @@ fn should_fail_if_calling_non_existent_entry_point() { // next make another deploy that attempts to use the stored payment logic // but passing the name for an entry point that does not exist. - let exec_request_stored_payment = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_session_code(format!("{}.wasm", DO_NOTHING_NAME), RuntimeArgs::default()) - .with_stored_payment_hash( - stored_payment_contract_hash.into(), - "electric-boogaloo", - runtime_args! { ARG_AMOUNT => payment_purse_amount }, - ) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) - .with_deploy_hash([1; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_code(format!("{}.wasm", DO_NOTHING_NAME), RuntimeArgs::default()) + .with_stored_payment_hash( + stored_payment_contract_hash.into(), + "electric-boogaloo", + runtime_args! { ARG_AMOUNT => payment_purse_amount }, + ) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) + .with_deploy_hash([1; 32]) + .build(); + + let exec_request_stored_payment = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_stored_payment).commit(); @@ -209,27 +205,26 @@ fn should_exec_stored_code_by_hash() { // next make another deploy that USES stored payment logic { - let transfer_using_stored_payment = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_payment_contract_by_hash( - custom_payment_package_hash.value(), - Some(ENTITY_INITIAL_VERSION), - PAY_ENTRYPOINT, - runtime_args! { - ARG_AMOUNT => default_payment, - }, - ) - .with_session_code( - format!("{}.wasm", TRANSFER_PURSE_TO_ACCOUNT_CONTRACT_NAME), - runtime_args! { ARG_TARGET => ACCOUNT_1_ADDR, ARG_AMOUNT => transferred_amount }, - ) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) - .with_deploy_hash([2; 32]) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_stored_versioned_payment_contract_by_hash( + custom_payment_package_hash.value(), + Some(ENTITY_INITIAL_VERSION), + PAY_ENTRYPOINT, + runtime_args! { + ARG_AMOUNT => default_payment, + }, + ) + .with_session_code( + format!("{}.wasm", TRANSFER_PURSE_TO_ACCOUNT_CONTRACT_NAME), + runtime_args! { ARG_TARGET => ACCOUNT_1_ADDR, ARG_AMOUNT => transferred_amount }, + ) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) + .with_deploy_hash([2; 32]) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let transfer_using_stored_payment = + ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(transfer_using_stored_payment).expect_failure(); } @@ -254,9 +249,8 @@ fn should_not_transfer_above_balance_using_stored_payment_code_by_hash() { let transferred_amount = starting_balance - *DEFAULT_PAYMENT + U512::one(); - let exec_request_stored_payment = { - let account_1_account_hash = ACCOUNT_1_ADDR; - let deploy_item = DeployItemBuilder::new() + let account_1_account_hash = ACCOUNT_1_ADDR; + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code( format!("{}.wasm", TRANSFER_PURSE_TO_ACCOUNT_CONTRACT_NAME), @@ -274,8 +268,7 @@ fn should_not_transfer_above_balance_using_stored_payment_code_by_hash() { .with_deploy_hash([2; 32]) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request_stored_payment = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder .exec(exec_request_stored_payment) @@ -306,9 +299,8 @@ fn should_empty_account_using_stored_payment_code_by_hash() { let transferred_amount = starting_balance - *DEFAULT_PAYMENT; { - let exec_request_stored_payment = { - let account_1_account_hash = ACCOUNT_1_ADDR; - let deploy_item = DeployItemBuilder::new() + let account_1_account_hash = ACCOUNT_1_ADDR; + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code( format!("{}.wasm", TRANSFER_PURSE_TO_ACCOUNT_CONTRACT_NAME), @@ -326,8 +318,8 @@ fn should_empty_account_using_stored_payment_code_by_hash() { .with_deploy_hash([2; 32]) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request_stored_payment = + ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_stored_payment).expect_failure(); } @@ -353,9 +345,8 @@ fn should_exec_stored_code_by_named_hash() { let transferred_amount = 1; { - let exec_request_stored_payment = { - let account_1_account_hash = ACCOUNT_1_ADDR; - let deploy_item = DeployItemBuilder::new() + let account_1_account_hash = ACCOUNT_1_ADDR; + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code( format!("{}.wasm", TRANSFER_PURSE_TO_ACCOUNT_CONTRACT_NAME), @@ -373,8 +364,8 @@ fn should_exec_stored_code_by_named_hash() { .with_deploy_hash([2; 32]) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request_stored_payment = + ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_stored_payment).expect_failure(); @@ -437,21 +428,19 @@ fn should_fail_payment_stored_at_hash_with_incompatible_major_version() { .expect_upgrade_success(); // next make another deploy that USES stored payment logic - let exec_request_stored_payment = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_session_code(format!("{}.wasm", DO_NOTHING_NAME), RuntimeArgs::default()) - .with_stored_payment_hash( - stored_payment_contract_hash.into(), - PAY_ENTRYPOINT, - runtime_args! { ARG_AMOUNT => payment_purse_amount }, - ) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) - .with_deploy_hash([2; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_code(format!("{}.wasm", DO_NOTHING_NAME), RuntimeArgs::default()) + .with_stored_payment_hash( + stored_payment_contract_hash.into(), + PAY_ENTRYPOINT, + runtime_args! { ARG_AMOUNT => payment_purse_amount }, + ) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) + .with_deploy_hash([2; 32]) + .build(); + + let exec_request_stored_payment = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_stored_payment).commit(); @@ -529,25 +518,23 @@ fn should_fail_session_stored_at_named_key_with_incompatible_major_version() { // Call stored session code - let exec_request_stored_payment = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_session_named_key( - DO_NOTHING_CONTRACT_HASH_NAME, - ENTRY_FUNCTION_NAME, - RuntimeArgs::new(), - ) - .with_stored_payment_hash( - stored_payment_contract_hash.into(), - PAY_ENTRYPOINT, - runtime_args! { ARG_AMOUNT => payment_purse_amount }, - ) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) - .with_deploy_hash([2; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_stored_session_named_key( + DO_NOTHING_CONTRACT_HASH_NAME, + ENTRY_FUNCTION_NAME, + RuntimeArgs::new(), + ) + .with_stored_payment_hash( + stored_payment_contract_hash.into(), + PAY_ENTRYPOINT, + runtime_args! { ARG_AMOUNT => payment_purse_amount }, + ) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) + .with_deploy_hash([2; 32]) + .build(); + + let exec_request_stored_payment = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_stored_payment).commit(); @@ -608,27 +595,25 @@ fn should_fail_session_stored_at_named_key_with_missing_new_major_version() { // Call stored session code - let exec_request_stored_payment = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_contract_by_name( - DO_NOTHING_CONTRACT_PACKAGE_HASH_NAME, - Some(INITIAL_VERSION), - ENTRY_FUNCTION_NAME, - RuntimeArgs::new(), - ) - .with_payment_code( - STORED_PAYMENT_CONTRACT_NAME, - runtime_args! { - ARG_AMOUNT => payment_purse_amount, - }, - ) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) - .with_deploy_hash([2; 32]) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_stored_versioned_contract_by_name( + DO_NOTHING_CONTRACT_PACKAGE_HASH_NAME, + Some(INITIAL_VERSION), + ENTRY_FUNCTION_NAME, + RuntimeArgs::new(), + ) + .with_payment_code( + STORED_PAYMENT_CONTRACT_NAME, + runtime_args! { + ARG_AMOUNT => payment_purse_amount, + }, + ) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) + .with_deploy_hash([2; 32]) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request_stored_payment = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_stored_payment).commit(); @@ -700,25 +685,23 @@ fn should_fail_session_stored_at_hash_with_incompatible_major_version() { .into_entity_hash_addr() .expect("standard_payment named key should be hash"); - let exec_request_stored_payment = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_session_named_key( - DO_NOTHING_CONTRACT_HASH_NAME, - ENTRY_FUNCTION_NAME, - RuntimeArgs::new(), - ) - .with_stored_payment_hash( - test_payment_stored_hash.into(), - PAY_ENTRYPOINT, - runtime_args! { ARG_AMOUNT => payment_purse_amount }, - ) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) - .with_deploy_hash([2; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_stored_session_named_key( + DO_NOTHING_CONTRACT_HASH_NAME, + ENTRY_FUNCTION_NAME, + RuntimeArgs::new(), + ) + .with_stored_payment_hash( + test_payment_stored_hash.into(), + PAY_ENTRYPOINT, + runtime_args! { ARG_AMOUNT => payment_purse_amount }, + ) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) + .with_deploy_hash([2; 32]) + .build(); + + let exec_request_stored_payment = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_stored_payment).commit(); @@ -793,26 +776,24 @@ fn should_execute_stored_payment_and_session_code_with_new_major_version() { .into_entity_hash_addr() .expect("standard_payment named key should be hash"); - let exec_request_stored_payment = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_contract_by_name( - DO_NOTHING_CONTRACT_PACKAGE_HASH_NAME, - Some(INITIAL_VERSION), - ENTRY_FUNCTION_NAME, - RuntimeArgs::new(), - ) - .with_stored_payment_hash( - test_payment_stored_hash.into(), - PAY_ENTRYPOINT, - runtime_args! { ARG_AMOUNT => payment_purse_amount }, - ) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_stored_versioned_contract_by_name( + DO_NOTHING_CONTRACT_PACKAGE_HASH_NAME, + Some(INITIAL_VERSION), + ENTRY_FUNCTION_NAME, + RuntimeArgs::new(), + ) + .with_stored_payment_hash( + test_payment_stored_hash.into(), + PAY_ENTRYPOINT, + runtime_args! { ARG_AMOUNT => payment_purse_amount }, + ) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) + .with_deploy_hash([3; 32]) + .build(); + + let exec_request_stored_payment = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder .clear_results() diff --git a/execution_engine_testing/tests/src/test/explorer/faucet.rs b/execution_engine_testing/tests/src/test/explorer/faucet.rs index 503cd3b5bf..ba2ba14fa0 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet.rs @@ -45,10 +45,8 @@ fn should_install_faucet_contract() { .transfer_and_commit(fund_installer_account_request) .expect_success(); - let install_faucet_request = FaucetInstallSessionRequestBuilder::new().build(); - builder - .exec(install_faucet_request) + .exec(FaucetInstallSessionRequestBuilder::new().build()) .expect_success() .commit(); @@ -960,25 +958,24 @@ fn faucet_costs() { let assigned_time_interval = 10_000u64; let assigned_distributions_per_interval = 2u64; - let installer_set_variable_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(installer_account) - .with_authorization_keys(&[installer_account]) - .with_stored_session_named_key( - &format!("{}_{}", FAUCET_CONTRACT_NAMED_KEY, FAUCET_ID), - ENTRY_POINT_SET_VARIABLES, - runtime_args! { - ARG_AVAILABLE_AMOUNT => Some(faucet_fund_amount), - ARG_TIME_INTERVAL => Some(assigned_time_interval), - ARG_DISTRIBUTIONS_PER_INTERVAL => Some(assigned_distributions_per_interval) - }, - ) - .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT}) - .with_deploy_hash([3; 32]) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(installer_account) + .with_authorization_keys(&[installer_account]) + .with_stored_session_named_key( + &format!("{}_{}", FAUCET_CONTRACT_NAMED_KEY, FAUCET_ID), + ENTRY_POINT_SET_VARIABLES, + runtime_args! { + ARG_AVAILABLE_AMOUNT => Some(faucet_fund_amount), + ARG_TIME_INTERVAL => Some(assigned_time_interval), + ARG_DISTRIBUTIONS_PER_INTERVAL => Some(assigned_distributions_per_interval) + }, + ) + .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT}) + .with_deploy_hash([3; 32]) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let installer_set_variable_request = + ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder .exec(installer_set_variable_request) @@ -988,8 +985,8 @@ fn faucet_costs() { let faucet_set_variables_cost = builder.last_exec_gas_cost(); let user_fund_amount = U512::from(10_000_000_000u64); - let faucet_call_by_installer = { - let deploy_item = DeployItemBuilder::new() + + let deploy_item = DeployItemBuilder::new() .with_address(installer_account) .with_authorization_keys(&[installer_account]) .with_stored_session_named_key( @@ -1001,8 +998,7 @@ fn faucet_costs() { .with_deploy_hash([4; 32]) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let faucet_call_by_installer = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder .exec(faucet_call_by_installer) @@ -1013,21 +1009,19 @@ fn faucet_costs() { let faucet_contract_hash = get_faucet_entity_hash(&builder, installer_account); - let faucet_call_by_user_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(user_account) - .with_authorization_keys(&[user_account]) - .with_stored_session_hash( - faucet_contract_hash, - ENTRY_POINT_FAUCET, - runtime_args! {ARG_TARGET => user_account, ARG_ID => >::None}, - ) - .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => user_fund_amount}) - .with_deploy_hash([4; 32]) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(user_account) + .with_authorization_keys(&[user_account]) + .with_stored_session_hash( + faucet_contract_hash, + ENTRY_POINT_FAUCET, + runtime_args! {ARG_TARGET => user_account, ARG_ID => >::None}, + ) + .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => user_fund_amount}) + .with_deploy_hash([4; 32]) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let faucet_call_by_user_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder .exec(faucet_call_by_user_request) diff --git a/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs b/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs index ef0fb894d5..5a5f1b1a2c 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs @@ -97,7 +97,7 @@ impl FaucetInstallSessionRequestBuilder { self } - pub fn build(&self) -> ExecuteRequest { + pub fn build(&self) -> ExecuteRequest<'static> { ExecuteRequestBuilder::standard( self.installer_account, &self.faucet_installer_session, @@ -159,7 +159,7 @@ impl FaucetConfigRequestBuilder { self } - pub fn build(&self) -> ExecuteRequest { + pub fn build(&self) -> ExecuteRequest<'static> { ExecuteRequestBuilder::contract_call_by_hash( self.installer_account, self.faucet_contract_hash @@ -219,7 +219,7 @@ impl FaucetAuthorizeAccountRequestBuilder { self } - pub fn build(self) -> ExecuteRequest { + pub fn build<'a>(self) -> ExecuteRequest<'a> { ExecuteRequestBuilder::contract_call_by_hash( self.installer_account, self.faucet_contract_hash @@ -315,7 +315,7 @@ impl FaucetFundRequestBuilder { self } - pub fn build(self) -> ExecuteRequest { + pub fn build(self) -> ExecuteRequest<'static> { let mut rng = rand::thread_rng(); let deploy_item = DeployItemBuilder::new() @@ -342,10 +342,14 @@ impl FaucetFundRequestBuilder { .build(); match self.block_time { - Some(block_time) => ExecuteRequestBuilder::from_deploy_item(deploy_item) - .with_block_time(block_time) - .build(), - None => ExecuteRequestBuilder::from_deploy_item(deploy_item).build(), + Some(block_time) => { + ExecuteRequestBuilder::from_deploy_item(Box::leak(Box::new(deploy_item))) + .with_block_time(block_time) + .build() + } + None => { + ExecuteRequestBuilder::from_deploy_item(Box::leak(Box::new(deploy_item))).build() + } } } } @@ -555,7 +559,7 @@ impl FaucetDeployHelper { .build() } - pub fn faucet_install_request(&self) -> ExecuteRequest { + pub fn faucet_install_request(&self) -> ExecuteRequest<'static> { self.faucet_install_session_request_builder .clone() .with_installer_account(self.installer_account) @@ -565,7 +569,7 @@ impl FaucetDeployHelper { .build() } - pub fn faucet_config_request(&self) -> ExecuteRequest { + pub fn faucet_config_request(&self) -> ExecuteRequest<'static> { self.faucet_config_request_builder .with_installer_account(self.installer_account()) .with_faucet_contract_hash( diff --git a/execution_engine_testing/tests/src/test/gas_counter.rs b/execution_engine_testing/tests/src/test/gas_counter.rs index e12d960e5a..61f4712e92 100644 --- a/execution_engine_testing/tests/src/test/gas_counter.rs +++ b/execution_engine_testing/tests/src/test/gas_counter.rs @@ -43,18 +43,16 @@ fn should_fail_to_overflow_gas_counter() { let session_bytes = make_gas_counter_overflow(); - let exec_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_session_bytes(session_bytes, RuntimeArgs::default()) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => *DEFAULT_PAYMENT - }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([42; 32]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_bytes(session_bytes, RuntimeArgs::default()) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => *DEFAULT_PAYMENT + }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([42; 32]) + .build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); @@ -151,18 +149,16 @@ fn should_correctly_measure_gas_for_opcodes() { builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); - let exec_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_session_bytes(session_bytes, RuntimeArgs::default()) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => *DEFAULT_PAYMENT - }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([42; 32]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_bytes(session_bytes, RuntimeArgs::default()) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => *DEFAULT_PAYMENT + }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([42; 32]) + .build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request).commit().expect_success(); diff --git a/execution_engine_testing/tests/src/test/groups.rs b/execution_engine_testing/tests/src/test/groups.rs index ea25ba314f..fa8b200574 100644 --- a/execution_engine_testing/tests/src/test/groups.rs +++ b/execution_engine_testing/tests/src/test/groups.rs @@ -138,23 +138,21 @@ fn should_not_call_restricted_session_from_wrong_account() { .get(PACKAGE_ACCESS_KEY) .expect("should have package hash"); - let exec_request_3 = { - let args = runtime_args! {}; - let deploy_item = DeployItemBuilder::new() - .with_address(ACCOUNT_1_ADDR) - .with_stored_versioned_contract_by_hash( - package_hash.into_package_addr().expect("should be hash"), - None, - RESTRICTED_SESSION, - args, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[ACCOUNT_1_ADDR]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let args = runtime_args! {}; + let deploy_item = DeployItemBuilder::new() + .with_address(ACCOUNT_1_ADDR) + .with_stored_versioned_contract_by_hash( + package_hash.into_package_addr().expect("should be hash"), + None, + RESTRICTED_SESSION, + args, + ) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_authorization_keys(&[ACCOUNT_1_ADDR]) + .with_deploy_hash([3; 32]) + .build(); + + let exec_request_3 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_3).commit(); @@ -199,25 +197,23 @@ fn should_not_call_restricted_session_caller_from_wrong_account() { .get(PACKAGE_ACCESS_KEY) .expect("should have package hash"); - let exec_request_3 = { - let args = runtime_args! { - "package_hash" => *package_hash, - }; - let deploy_item = DeployItemBuilder::new() - .with_address(ACCOUNT_1_ADDR) - .with_stored_versioned_contract_by_hash( - package_hash.into_package_addr().expect("should be hash"), - None, - RESTRICTED_SESSION_CALLER, - args, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[ACCOUNT_1_ADDR]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let args = runtime_args! { + "package_hash" => *package_hash, }; + let deploy_item = DeployItemBuilder::new() + .with_address(ACCOUNT_1_ADDR) + .with_stored_versioned_contract_by_hash( + package_hash.into_package_addr().expect("should be hash"), + None, + RESTRICTED_SESSION_CALLER, + args, + ) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_authorization_keys(&[ACCOUNT_1_ADDR]) + .with_deploy_hash([3; 32]) + .build(); + + let exec_request_3 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_3).commit(); @@ -261,28 +257,21 @@ fn should_call_group_restricted_contract() { .get(PACKAGE_ACCESS_KEY) .expect("should have package hash"); - let exec_request_2 = { - // This inserts package as an argument because this test - // can work from different accounts which might not have the same keys in their session - // code. - let args = runtime_args! { - PACKAGE_HASH_ARG => *package_hash, - }; - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_contract_by_name( - PACKAGE_HASH_KEY, - None, - RESTRICTED_CONTRACT, - args, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + // This inserts package as an argument because this test + // can work from different accounts which might not have the same keys in their session + // code. + let args = runtime_args! { + PACKAGE_HASH_ARG => *package_hash, }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_stored_versioned_contract_by_name(PACKAGE_HASH_KEY, None, RESTRICTED_CONTRACT, args) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([3; 32]) + .build(); + + let exec_request_2 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_2).expect_success().commit(); @@ -320,28 +309,26 @@ fn should_not_call_group_restricted_contract_from_wrong_account() { .get(PACKAGE_ACCESS_KEY) .expect("should have package hash"); - let exec_request_3 = { - // This inserts package as an argument because this test - // can work from different accounts which might not have the same keys in their session - // code. - let args = runtime_args! { - PACKAGE_HASH_ARG => *package_hash, - }; - let deploy_item = DeployItemBuilder::new() - .with_address(ACCOUNT_1_ADDR) - .with_stored_versioned_contract_by_hash( - package_hash.into_package_addr().expect("should be hash"), - None, - RESTRICTED_CONTRACT, - args, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[ACCOUNT_1_ADDR]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + // This inserts package as an argument because this test + // can work from different accounts which might not have the same keys in their session + // code. + let args = runtime_args! { + PACKAGE_HASH_ARG => *package_hash, }; + let deploy_item = DeployItemBuilder::new() + .with_address(ACCOUNT_1_ADDR) + .with_stored_versioned_contract_by_hash( + package_hash.into_package_addr().expect("should be hash"), + None, + RESTRICTED_CONTRACT, + args, + ) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_authorization_keys(&[ACCOUNT_1_ADDR]) + .with_deploy_hash([3; 32]) + .build(); + + let exec_request_3 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_3).commit(); @@ -370,25 +357,23 @@ fn should_call_group_unrestricted_contract_caller() { .get(PACKAGE_ACCESS_KEY) .expect("should have package hash"); - let exec_request_2 = { - let args = runtime_args! { - PACKAGE_HASH_ARG => *package_hash, - }; - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_contract_by_name( - PACKAGE_HASH_KEY, - None, - UNRESTRICTED_CONTRACT_CALLER, - args, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let args = runtime_args! { + PACKAGE_HASH_ARG => *package_hash, }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_stored_versioned_contract_by_name( + PACKAGE_HASH_KEY, + None, + UNRESTRICTED_CONTRACT_CALLER, + args, + ) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([3; 32]) + .build(); + + let exec_request_2 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_2).expect_success().commit(); let _account = builder @@ -557,28 +542,21 @@ fn should_not_call_uncallable_contract_from_deploy() { .get(PACKAGE_ACCESS_KEY) .expect("should have package hash"); - let exec_request_2 = { - // This inserts package as an argument because this test - // can work from different accounts which might not have the same keys in their session - // code. - let args = runtime_args! { - PACKAGE_HASH_ARG => *package_hash, - }; - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_contract_by_name( - PACKAGE_HASH_KEY, - None, - UNCALLABLE_SESSION, - args, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + // This inserts package as an argument because this test + // can work from different accounts which might not have the same keys in their session + // code. + let args = runtime_args! { + PACKAGE_HASH_ARG => *package_hash, }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_stored_versioned_contract_by_name(PACKAGE_HASH_KEY, None, UNCALLABLE_SESSION, args) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([3; 32]) + .build(); + + let exec_request_2 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_2).commit(); let response = builder @@ -587,25 +565,23 @@ fn should_not_call_uncallable_contract_from_deploy() { let error = response.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::InvalidContext)); - let exec_request_3 = { - let args = runtime_args! { - PACKAGE_HASH_ARG => *package_hash, - }; - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_contract_by_name( - PACKAGE_HASH_KEY, - None, - CALL_RESTRICTED_ENTRY_POINTS, - args, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([6; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let args = runtime_args! { + PACKAGE_HASH_ARG => *package_hash, }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_stored_versioned_contract_by_name( + PACKAGE_HASH_KEY, + None, + CALL_RESTRICTED_ENTRY_POINTS, + args, + ) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([6; 32]) + .build(); + + let exec_request_3 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_3).expect_failure(); @@ -630,28 +606,21 @@ fn should_not_call_uncallable_session_from_deploy() { .get(PACKAGE_ACCESS_KEY) .expect("should have package hash"); - let exec_request_2 = { - // This inserts package as an argument because this test - // can work from different accounts which might not have the same keys in their session - // code. - let args = runtime_args! { - PACKAGE_HASH_ARG => *package_hash, - }; - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_contract_by_name( - PACKAGE_HASH_KEY, - None, - UNCALLABLE_CONTRACT, - args, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + // This inserts package as an argument because this test + // can work from different accounts which might not have the same keys in their session + // code. + let args = runtime_args! { + PACKAGE_HASH_ARG => *package_hash, }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_stored_versioned_contract_by_name(PACKAGE_HASH_KEY, None, UNCALLABLE_CONTRACT, args) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([3; 32]) + .build(); + + let exec_request_2 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_2).commit(); let response = builder @@ -660,25 +629,23 @@ fn should_not_call_uncallable_session_from_deploy() { let error = response.error().expect("should have error"); assert_matches!(error, Error::Exec(ExecError::InvalidContext)); - let exec_request_3 = { - let args = runtime_args! { - PACKAGE_HASH_ARG => *package_hash, - }; - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_contract_by_name( - PACKAGE_HASH_KEY, - None, - CALL_RESTRICTED_ENTRY_POINTS, - args, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([6; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let args = runtime_args! { + PACKAGE_HASH_ARG => *package_hash, }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_stored_versioned_contract_by_name( + PACKAGE_HASH_KEY, + None, + CALL_RESTRICTED_ENTRY_POINTS, + args, + ) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([6; 32]) + .build(); + + let exec_request_3 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_3).expect_failure(); builder.assert_error(Error::Exec(ExecError::InvalidContext)) @@ -713,27 +680,25 @@ fn should_not_call_group_restricted_stored_payment_code_from_invalid_account() { .get(PACKAGE_ACCESS_KEY) .expect("should have package hash"); - let exec_request_3 = { - let args = runtime_args! { - "amount" => *DEFAULT_PAYMENT, - }; - let deploy_item = DeployItemBuilder::new() - .with_address(ACCOUNT_1_ADDR) - .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) - .with_stored_versioned_payment_contract_by_hash( - package_hash - .into_package_addr() - .expect("must have created package hash"), - None, - "restricted_standard_payment", - args, - ) - .with_authorization_keys(&[ACCOUNT_1_ADDR]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let args = runtime_args! { + "amount" => *DEFAULT_PAYMENT, }; + let deploy_item = DeployItemBuilder::new() + .with_address(ACCOUNT_1_ADDR) + .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) + .with_stored_versioned_payment_contract_by_hash( + package_hash + .into_package_addr() + .expect("must have created package hash"), + None, + "restricted_standard_payment", + args, + ) + .with_authorization_keys(&[ACCOUNT_1_ADDR]) + .with_deploy_hash([3; 32]) + .build(); + + let exec_request_3 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_3).commit(); @@ -781,28 +746,26 @@ fn should_call_group_restricted_stored_payment_code() { .get(PACKAGE_ACCESS_KEY) .expect("should have package hash"); - let exec_request_3 = { - let args = runtime_args! { - "amount" => *DEFAULT_PAYMENT, - }; - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) - // .with_stored_versioned_contract_by_name(name, version, entry_point, args) - .with_stored_versioned_payment_contract_by_hash( - package_hash - .into_package_addr() - .expect("must have created package hash"), - None, - "restricted_standard_payment", - args, - ) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let args = runtime_args! { + "amount" => *DEFAULT_PAYMENT, }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) + // .with_stored_versioned_contract_by_name(name, version, entry_point, args) + .with_stored_versioned_payment_contract_by_hash( + package_hash + .into_package_addr() + .expect("must have created package hash"), + None, + "restricted_standard_payment", + args, + ) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([3; 32]) + .build(); + + let exec_request_3 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_3).expect_failure(); diff --git a/execution_engine_testing/tests/src/test/private_chain/management.rs b/execution_engine_testing/tests/src/test/private_chain/management.rs index a2a03f12d9..5832c0e65b 100644 --- a/execution_engine_testing/tests/src/test/private_chain/management.rs +++ b/execution_engine_testing/tests/src/test/private_chain/management.rs @@ -226,27 +226,25 @@ fn genesis_accounts_should_not_remove_associated_keys() { let mut builder = super::private_chain_setup(); - let add_associated_key_request = { - let session_args = runtime_args! { - ARG_ACCOUNT => secondary_account_hash, - ARG_WEIGHT => Weight::MAX, - }; - - let account_hash = *ACCOUNT_1_ADDR; - let deploy_hash: [u8; 32] = [55; 32]; + let session_args = runtime_args! { + ARG_ACCOUNT => secondary_account_hash, + ARG_WEIGHT => Weight::MAX, + }; - let deploy_item = DeployItemBuilder::new() - .with_address(account_hash) - .with_session_code(ADD_ASSOCIATED_KEY_CONTRACT, session_args) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => *DEFAULT_PAYMENT - }) - .with_authorization_keys(&[*ADMIN_1_ACCOUNT_ADDR]) - .with_deploy_hash(deploy_hash) - .build(); + let account_hash = *ACCOUNT_1_ADDR; + let deploy_hash: [u8; 32] = [55; 32]; + + let deploy_item = DeployItemBuilder::new() + .with_address(account_hash) + .with_session_code(ADD_ASSOCIATED_KEY_CONTRACT, session_args) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => *DEFAULT_PAYMENT + }) + .with_authorization_keys(&[*ADMIN_1_ACCOUNT_ADDR]) + .with_deploy_hash(deploy_hash) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let add_associated_key_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder .exec(add_associated_key_request) @@ -300,29 +298,25 @@ fn administrator_account_should_disable_any_account() { builder.exec(exec_request_1).expect_success().commit(); // Disable account 1 - let disable_request_1 = { - let session_args = runtime_args! { - ARG_DEPLOY_THRESHOLD => Weight::MAX, - ARG_KEY_MANAGEMENT_THRESHOLD => Weight::MAX, - }; - - { - let sender = *ACCOUNT_1_ADDR; - let deploy_hash = [54; 32]; - - // Here, deploy is sent as an account, but signed by an administrator. - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_session_code(SET_ACTION_THRESHOLDS_CONTRACT, session_args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ADMIN_ACCOUNT_ADDR]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - } + let session_args = runtime_args! { + ARG_DEPLOY_THRESHOLD => Weight::MAX, + ARG_KEY_MANAGEMENT_THRESHOLD => Weight::MAX, }; + let sender = *ACCOUNT_1_ADDR; + let deploy_hash = [54; 32]; + + // Here, deploy is sent as an account, but signed by an administrator. + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_session_code(SET_ACTION_THRESHOLDS_CONTRACT, session_args) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_authorization_keys(&[*DEFAULT_ADMIN_ACCOUNT_ADDR]) + .with_deploy_hash(deploy_hash) + .build(); + + let disable_request_1 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); + builder.exec(disable_request_1).expect_success().commit(); // Account 1 can not deploy after freezing let exec_request_2 = ExecuteRequestBuilder::module_bytes( @@ -348,47 +342,43 @@ fn administrator_account_should_disable_any_account() { ); // Unfreeze account 1 - let enable_request_1 = { - let session_args = runtime_args! { - ARG_DEPLOY_THRESHOLD => Weight::new(1), - ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(0), - }; + let session_args = runtime_args! { + ARG_DEPLOY_THRESHOLD => Weight::new(1), + ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(0), + }; - let sender = *ACCOUNT_1_ADDR; - let deploy_hash = [53; 32]; + let sender = *ACCOUNT_1_ADDR; + let deploy_hash = [53; 32]; - // Here, deploy is sent as an account, but signed by an administrator. - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_session_code(SET_ACTION_THRESHOLDS_CONTRACT, session_args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ADMIN_ACCOUNT_ADDR]) - .with_deploy_hash(deploy_hash) - .build(); + // Here, deploy is sent as an account, but signed by an administrator. + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_session_code(SET_ACTION_THRESHOLDS_CONTRACT, session_args) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_authorization_keys(&[*DEFAULT_ADMIN_ACCOUNT_ADDR]) + .with_deploy_hash(deploy_hash) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let enable_request_1 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); - let enable_request_2 = { - let session_args = runtime_args! { - ARG_DEPLOY_THRESHOLD => Weight::new(0), - ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(1), - }; + let session_args = runtime_args! { + ARG_DEPLOY_THRESHOLD => Weight::new(0), + ARG_KEY_MANAGEMENT_THRESHOLD => Weight::new(1), + }; - let sender = *ACCOUNT_1_ADDR; - let deploy_hash = [52; 32]; + let sender = *ACCOUNT_1_ADDR; + let deploy_hash = [52; 32]; - // Here, deploy is sent as an account, but signed by an administrator. - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_session_code(SET_ACTION_THRESHOLDS_CONTRACT, session_args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ADMIN_ACCOUNT_ADDR]) - .with_deploy_hash(deploy_hash) - .build(); + // Here, deploy is sent as an account, but signed by an administrator. + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_session_code(SET_ACTION_THRESHOLDS_CONTRACT, session_args) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_authorization_keys(&[*DEFAULT_ADMIN_ACCOUNT_ADDR]) + .with_deploy_hash(deploy_hash) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let enable_request_2 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(enable_request_1).expect_success().commit(); builder.exec(enable_request_2).expect_success().commit(); @@ -706,28 +696,22 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { ); // Account 1 can deploy after genesis - let exec_request_1 = { - let sender = *ACCOUNT_1_ADDR; - let deploy_hash = [100; 32]; + let sender = *ACCOUNT_1_ADDR; + let deploy_hash = [100; 32]; - let payment_args = runtime_args! { - standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT, - }; - let session_args = RuntimeArgs::default(); - - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) - .with_stored_payment_named_key( - TEST_PAYMENT_STORED_HASH_NAME, - PAY_ENTRYPOINT, - payment_args, - ) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let payment_args = runtime_args! { + standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT, }; + let session_args = RuntimeArgs::default(); + + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) + .with_stored_payment_named_key(TEST_PAYMENT_STORED_HASH_NAME, PAY_ENTRYPOINT, payment_args) + .with_authorization_keys(&[sender]) + .with_deploy_hash(deploy_hash) + .build(); + let exec_request_1 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_1).expect_failure(); @@ -757,48 +741,37 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { ); assert!(!contract_package_after_disable.is_entity_enabled(&stored_entity_hash),); - let call_stored_payment_requests_1 = { - let payment_args = runtime_args! { - standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT, - }; - let session_args = RuntimeArgs::default(); - - let call_by_name = { - let sender = *ACCOUNT_1_ADDR; - let deploy_hash = [100; 32]; - - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args.clone()) - .with_stored_payment_named_key( - TEST_PAYMENT_STORED_HASH_NAME, - PAY_ENTRYPOINT, - payment_args.clone(), - ) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; - - let call_by_hash = { - let sender = *ACCOUNT_1_ADDR; - let deploy_hash = [100; 32]; - - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) - .with_stored_payment_hash(stored_entity_hash, PAY_ENTRYPOINT, payment_args) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; - - vec![call_by_name, call_by_hash] + let payment_args = runtime_args! { + standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT, }; + let session_args = RuntimeArgs::default(); + + let sender = *ACCOUNT_1_ADDR; + let deploy_hash = [100; 32]; + + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args.clone()) + .with_stored_payment_named_key( + TEST_PAYMENT_STORED_HASH_NAME, + PAY_ENTRYPOINT, + payment_args.clone(), + ) + .with_authorization_keys(&[sender]) + .with_deploy_hash(deploy_hash) + .build(); + let call_by_name = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); + + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) + .with_stored_payment_hash(stored_entity_hash, PAY_ENTRYPOINT, payment_args) + .with_authorization_keys(&[sender]) + .with_deploy_hash(deploy_hash) + .build(); + let call_by_hash = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); - for execute_request in call_stored_payment_requests_1 { + for execute_request in [call_by_name, call_by_hash] { builder.exec(execute_request).expect_failure().commit(); let error = builder.get_error().expect("should have error"); assert!( @@ -825,48 +798,33 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { builder.exec(enable_request).expect_success().commit(); - let call_stored_payment_requests_2 = { - let payment_args = runtime_args! { - standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT, - }; - let session_args = RuntimeArgs::default(); - - let call_by_name = { - let sender = *ACCOUNT_1_ADDR; - let deploy_hash = [100; 32]; - - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args.clone()) - .with_stored_payment_named_key( - TEST_PAYMENT_STORED_HASH_NAME, - PAY_ENTRYPOINT, - payment_args.clone(), - ) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; - - let call_by_hash = { - let sender = *ACCOUNT_1_ADDR; - let deploy_hash = [100; 32]; - - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) - .with_stored_payment_hash(stored_entity_hash, PAY_ENTRYPOINT, payment_args) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; - - vec![call_by_name, call_by_hash] - }; + let payment_args = runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }; + let session_args = RuntimeArgs::default(); + let sender = *ACCOUNT_1_ADDR; + let deploy_hash = [100; 32]; + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args.clone()) + .with_stored_payment_named_key( + TEST_PAYMENT_STORED_HASH_NAME, + PAY_ENTRYPOINT, + payment_args.clone(), + ) + .with_authorization_keys(&[sender]) + .with_deploy_hash(deploy_hash) + .build(); + let call_by_name = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); + + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) + .with_stored_payment_hash(stored_entity_hash, PAY_ENTRYPOINT, payment_args) + .with_authorization_keys(&[sender]) + .with_deploy_hash(deploy_hash) + .build(); + let call_by_hash = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); - for exec_request in call_stored_payment_requests_2 { + for exec_request in [call_by_name, call_by_hash] { builder.exec(exec_request).expect_failure(); } } diff --git a/execution_engine_testing/tests/src/test/private_chain/unrestricted_transfers.rs b/execution_engine_testing/tests/src/test/private_chain/unrestricted_transfers.rs index 4441b17f90..0a1c9f6176 100644 --- a/execution_engine_testing/tests/src/test/private_chain/unrestricted_transfers.rs +++ b/execution_engine_testing/tests/src/test/private_chain/unrestricted_transfers.rs @@ -436,29 +436,23 @@ fn should_not_allow_payment_to_purse_in_stored_payment() { .commit(); // Account 1 can deploy after genesis - let exec_request_1 = { - let sender = *ACCOUNT_1_ADDR; - let deploy_hash = [100; 32]; - - let payment_args = runtime_args! { - standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT, - }; - let session_args = RuntimeArgs::default(); - - const PAY_ENTRYPOINT: &str = "pay"; - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) - .with_stored_payment_named_key( - TEST_PAYMENT_STORED_HASH_NAME, - PAY_ENTRYPOINT, - payment_args, - ) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let sender = *ACCOUNT_1_ADDR; + let deploy_hash = [100; 32]; + + let payment_args = runtime_args! { + standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT, }; + let session_args = RuntimeArgs::default(); + + const PAY_ENTRYPOINT: &str = "pay"; + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) + .with_stored_payment_named_key(TEST_PAYMENT_STORED_HASH_NAME, PAY_ENTRYPOINT, payment_args) + .with_authorization_keys(&[sender]) + .with_deploy_hash(deploy_hash) + .build(); + let exec_request_1 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_1).expect_failure().commit(); @@ -674,26 +668,24 @@ fn should_allow_custom_payment_by_paying_to_system_account() { let mut builder = super::private_chain_setup(); // Account 1 can deploy after genesis - let exec_request_1 = { - let sender = *ACCOUNT_1_ADDR; - let deploy_hash = [100; 32]; - - let payment_amount = *DEFAULT_PAYMENT + U512::from(1u64); - - let payment_args = runtime_args! { - standard_payment::ARG_AMOUNT => payment_amount, - }; - let session_args = RuntimeArgs::default(); - - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) - .with_payment_code("non_standard_payment.wasm", payment_args) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let sender = *ACCOUNT_1_ADDR; + let deploy_hash = [100; 32]; + + let payment_amount = *DEFAULT_PAYMENT + U512::from(1u64); + + let payment_args = runtime_args! { + standard_payment::ARG_AMOUNT => payment_amount, }; + let session_args = RuntimeArgs::default(); + + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) + .with_payment_code("non_standard_payment.wasm", payment_args) + .with_authorization_keys(&[sender]) + .with_deploy_hash(deploy_hash) + .build(); + let exec_request_1 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_1).expect_success().commit(); @@ -717,29 +709,27 @@ fn should_allow_wasm_transfer_to_system() { let mut builder = super::private_chain_setup(); // Account 1 can deploy after genesis - let exec_request_1 = { - let sender = *ACCOUNT_1_ADDR; - let deploy_hash = [100; 32]; - - let payment_amount = *DEFAULT_PAYMENT + U512::from(1u64); - - let payment_args = runtime_args! { - standard_payment::ARG_AMOUNT => payment_amount, - }; - let session_args = runtime_args! { - "target" => *SYSTEM_ADDR, - "amount" => U512::one(), - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_session_code("transfer_to_account_u512.wasm", session_args) - .with_payment_bytes(Vec::new(), payment_args) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let sender = *ACCOUNT_1_ADDR; + let deploy_hash = [100; 32]; + + let payment_amount = *DEFAULT_PAYMENT + U512::from(1u64); + + let payment_args = runtime_args! { + standard_payment::ARG_AMOUNT => payment_amount, }; + let session_args = runtime_args! { + "target" => *SYSTEM_ADDR, + "amount" => U512::one(), + }; + + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_session_code("transfer_to_account_u512.wasm", session_args) + .with_payment_bytes(Vec::new(), payment_args) + .with_authorization_keys(&[sender]) + .with_deploy_hash(deploy_hash) + .build(); + let exec_request_1 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request_1).expect_success().commit(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1129.rs b/execution_engine_testing/tests/src/test/regression/ee_1129.rs index bdff6ff77c..5706e40a61 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1129.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1129.rs @@ -86,7 +86,7 @@ fn should_run_ee_1129_underfunded_delegate_call() { .with_deploy_hash(deploy_hash) .build(); - let exec_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request).commit(); @@ -146,7 +146,7 @@ fn should_run_ee_1129_underfunded_add_bid_call() { .with_deploy_hash(deploy_hash) .build(); - let exec_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request).commit(); @@ -178,19 +178,17 @@ fn should_run_ee_1129_underfunded_mint_contract_call() { ) .build(); - let exec_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_session_named_key(CONTRACT_KEY, ENTRY_POINT_NAME, RuntimeArgs::default()) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => *CALL_STORED_CONTRACT_OVERHEAD, - }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([42; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_stored_session_named_key(CONTRACT_KEY, ENTRY_POINT_NAME, RuntimeArgs::default()) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => *CALL_STORED_CONTRACT_OVERHEAD, + }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([42; 32]) + .build(); + + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(install_exec_request).expect_success().commit(); @@ -224,19 +222,17 @@ fn should_not_panic_when_calling_session_contract_by_uref() { ) .build(); - let exec_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_session_named_key(ACCESS_KEY, ENTRY_POINT_NAME, RuntimeArgs::default()) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => *CALL_STORED_CONTRACT_OVERHEAD, - }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([42; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_stored_session_named_key(ACCESS_KEY, ENTRY_POINT_NAME, RuntimeArgs::default()) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => *CALL_STORED_CONTRACT_OVERHEAD, + }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([42; 32]) + .build(); + + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(install_exec_request).expect_success().commit(); @@ -270,17 +266,15 @@ fn should_not_panic_when_calling_payment_contract_by_uref() { ) .build(); - let exec_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::new()) - .with_stored_payment_named_key(ACCESS_KEY, ENTRY_POINT_NAME, RuntimeArgs::new()) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([42; 32]) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::new()) + .with_stored_payment_named_key(ACCESS_KEY, ENTRY_POINT_NAME, RuntimeArgs::new()) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([42; 32]) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(install_exec_request).expect_success().commit(); @@ -314,24 +308,22 @@ fn should_not_panic_when_calling_contract_package_by_uref() { ) .build(); - let exec_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_contract_by_name( - ACCESS_KEY, - None, - ENTRY_POINT_NAME, - RuntimeArgs::default(), - ) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => *CALL_STORED_CONTRACT_OVERHEAD, - }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([42; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_stored_versioned_contract_by_name( + ACCESS_KEY, + None, + ENTRY_POINT_NAME, + RuntimeArgs::default(), + ) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => *CALL_STORED_CONTRACT_OVERHEAD, + }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([42; 32]) + .build(); + + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(install_exec_request).expect_success().commit(); @@ -365,22 +357,20 @@ fn should_not_panic_when_calling_payment_versioned_contract_by_uref() { ) .build(); - let exec_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::new()) - .with_stored_versioned_payment_contract_by_name( - ACCESS_KEY, - None, - ENTRY_POINT_NAME, - RuntimeArgs::new(), - ) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([42; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::new()) + .with_stored_versioned_payment_contract_by_name( + ACCESS_KEY, + None, + ENTRY_POINT_NAME, + RuntimeArgs::new(), + ) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([42; 32]) + .build(); + + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(install_exec_request).expect_success().commit(); @@ -423,19 +413,17 @@ fn should_not_panic_when_calling_module_without_memory() { builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); - let exec_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_session_bytes(do_nothing_without_memory(), RuntimeArgs::new()) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => *DEFAULT_PAYMENT, - }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([42; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_bytes(do_nothing_without_memory(), RuntimeArgs::new()) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => *DEFAULT_PAYMENT, + }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([42; 32]) + .build(); + + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request).commit(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1163.rs b/execution_engine_testing/tests/src/test/regression/ee_1163.rs index ba35d27ffd..47cd8b9145 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1163.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1163.rs @@ -91,7 +91,7 @@ fn should_properly_charge_fixed_cost_with_nondefault_gas_price() { // .with_deploy_hash([42; 32]) // .with_gas_price(PRIORITIZED_GAS_PRICE) // .build(); - // ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + // ExecuteRequestBuilder::from_deploy_item(&deploy_item).build() // }; // // let mut builder = setup(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1225.rs b/execution_engine_testing/tests/src/test/regression/ee_1225.rs index 3b08db303f..57721fa098 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1225.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1225.rs @@ -16,22 +16,20 @@ fn should_run_ee_1225_verify_finalize_payment_invariants() { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); - let exec_request = { - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_payment_code( - EE_1225_REGRESSION_CONTRACT, - runtime_args! { - ARG_AMOUNT => *DEFAULT_PAYMENT, - }, - ) - .with_session_code(DO_NOTHING_CONTRACT, RuntimeArgs::default()) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([2; 32]) - .build(); + let deploy = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_payment_code( + EE_1225_REGRESSION_CONTRACT, + runtime_args! { + ARG_AMOUNT => *DEFAULT_PAYMENT, + }, + ) + .with_session_code(DO_NOTHING_CONTRACT, RuntimeArgs::default()) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([2; 32]) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy).build() - }; + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy).build(); builder.exec(exec_request).expect_success().commit(); } diff --git a/execution_engine_testing/tests/src/test/regression/ee_441.rs b/execution_engine_testing/tests/src/test/regression/ee_441.rs index 91d6005189..2e635c4cb5 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_441.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_441.rs @@ -16,21 +16,19 @@ fn get_uref(key: Key) -> URef { fn do_pass(pass: &str) -> (URef, URef) { // This test runs a contract that's after every call extends the same key with // more data - let exec_request = { - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_session_code( - EE_441_RNG_STATE, - runtime_args! { - "flag" => pass, - }, - ) - .with_deploy_hash([1u8; 32]) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy).build() - }; + let deploy = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_session_code( + EE_441_RNG_STATE, + runtime_args! { + "flag" => pass, + }, + ) + .with_deploy_hash([1u8; 32]) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy).build(); let mut builder = LmdbWasmTestBuilder::default(); builder diff --git a/execution_engine_testing/tests/src/test/regression/ee_550.rs b/execution_engine_testing/tests/src/test/regression/ee_550.rs index 90e43c3e60..62ac5f0a9d 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_550.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_550.rs @@ -24,20 +24,18 @@ fn should_run_ee_550_remove_with_saturated_threshold_regression() { ) .build(); - let exec_request_2 = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_session_code( - CONTRACT_EE_550_REGRESSION, - runtime_args! { ARG_PASS => String::from(PASS_TEST_REMOVE) }, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, AccountHash::new(KEY_2_ADDR)]) - .with_deploy_hash(DEPLOY_HASH) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_code( + CONTRACT_EE_550_REGRESSION, + runtime_args! { ARG_PASS => String::from(PASS_TEST_REMOVE) }, + ) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, AccountHash::new(KEY_2_ADDR)]) + .with_deploy_hash(DEPLOY_HASH) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request_2 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); @@ -61,20 +59,18 @@ fn should_run_ee_550_update_with_saturated_threshold_regression() { ) .build(); - let exec_request_2 = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_session_code( - CONTRACT_EE_550_REGRESSION, - runtime_args! { ARG_PASS => String::from(PASS_TEST_UPDATE) }, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, AccountHash::new(KEY_2_ADDR)]) - .with_deploy_hash(DEPLOY_HASH) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_code( + CONTRACT_EE_550_REGRESSION, + runtime_args! { ARG_PASS => String::from(PASS_TEST_UPDATE) }, + ) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, AccountHash::new(KEY_2_ADDR)]) + .with_deploy_hash(DEPLOY_HASH) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request_2 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_598.rs b/execution_engine_testing/tests/src/test/regression/ee_598.rs index 53d1a54234..f380d68977 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_598.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_598.rs @@ -60,22 +60,20 @@ fn should_handle_unbond_for_more_than_stake_as_full_unbond_of_stake_ee_598_regre }, ) .build(); - let combined_bond_and_unbond_request = { - let deploy = DeployItemBuilder::new() - .with_address(*ACCOUNT_1_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *ACCOUNT_1_FUND }) - .with_session_code( - "ee_598_regression.wasm", - runtime_args! { - ARG_AMOUNT => *ACCOUNT_1_BOND, - ARG_PUBLIC_KEY => ACCOUNT_1_PK.clone(), - }, - ) - .with_deploy_hash([2u8; 32]) - .with_authorization_keys(&[*ACCOUNT_1_ADDR]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy).build() - }; + let deploy = DeployItemBuilder::new() + .with_address(*ACCOUNT_1_ADDR) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *ACCOUNT_1_FUND }) + .with_session_code( + "ee_598_regression.wasm", + runtime_args! { + ARG_AMOUNT => *ACCOUNT_1_BOND, + ARG_PUBLIC_KEY => ACCOUNT_1_PK.clone(), + }, + ) + .with_deploy_hash([2u8; 32]) + .with_authorization_keys(&[*ACCOUNT_1_ADDR]) + .build(); + let combined_bond_and_unbond_request = ExecuteRequestBuilder::from_deploy_item(&deploy).build(); let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(run_genesis_request); diff --git a/execution_engine_testing/tests/src/test/regression/ee_601.rs b/execution_engine_testing/tests/src/test/regression/ee_601.rs index c30f58e40e..c0160a4ba8 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_601.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_601.rs @@ -14,20 +14,18 @@ const ARG_AMOUNT: &str = "amount"; fn should_run_ee_601_pay_session_new_uref_collision() { let genesis_account_hash = *DEFAULT_ACCOUNT_ADDR; - let exec_request = { - let deploy_item = DeployItemBuilder::new() - .with_deploy_hash([1; 32]) - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_payment_code( - "ee_601_regression.wasm", - runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }, - ) - .with_session_code("ee_601_regression.wasm", RuntimeArgs::default()) - .with_authorization_keys(&[genesis_account_hash]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let deploy_item = DeployItemBuilder::new() + .with_deploy_hash([1; 32]) + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_payment_code( + "ee_601_regression.wasm", + runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }, + ) + .with_session_code("ee_601_regression.wasm", RuntimeArgs::default()) + .with_authorization_keys(&[genesis_account_hash]) + .build(); + + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_890.rs b/execution_engine_testing/tests/src/test/regression/ee_890.rs index 5e48cd4b04..3651f864fa 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_890.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_890.rs @@ -48,7 +48,7 @@ fn should_run_ee_890_gracefully_reject_start_node_in_session() { .with_deploy_hash([123; 32]) .build(); - let exec_request_1 = ExecuteRequestBuilder::from_deploy_item(deploy_item).build(); + let exec_request_1 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); builder @@ -76,7 +76,7 @@ fn should_run_ee_890_gracefully_reject_start_node_in_payment() { .with_deploy_hash([123; 32]) .build(); - let exec_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); builder diff --git a/execution_engine_testing/tests/src/test/regression/ee_966.rs b/execution_engine_testing/tests/src/test/regression/ee_966.rs index 087e5e9dcb..75da639a98 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_966.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_966.rs @@ -57,7 +57,7 @@ fn make_session_code_with_memory_pages(initial_pages: u32, max_pages: Option) -> ExecuteRequest { +fn make_request_with_session_bytes<'a>(session_code: Vec) -> ExecuteRequest<'a> { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_bytes(session_code, RuntimeArgs::new()) @@ -68,7 +68,7 @@ fn make_request_with_session_bytes(session_code: Vec) -> ExecuteRequest { .with_deploy_hash([42; 32]) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + ExecuteRequestBuilder::from_deploy_item(Box::leak(Box::new(deploy_item))).build() } #[ignore] diff --git a/execution_engine_testing/tests/src/test/regression/gh_1688.rs b/execution_engine_testing/tests/src/test/regression/gh_1688.rs index 673165c740..6afbbf0a02 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1688.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1688.rs @@ -1,7 +1,8 @@ use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequest, ExecuteRequestBuilder, LmdbWasmTestBuilder, - DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, + DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, + DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; +use casper_execution_engine::engine_state::DeployItem; use casper_types::{ runtime_args, system::standard_payment::ARG_AMOUNT, AddressableEntityHash, PackageHash, RuntimeArgs, @@ -57,11 +58,11 @@ fn setup() -> (LmdbWasmTestBuilder, PackageHash, AddressableEntityHash) { (builder, contract_package_hash, entity_hash) } -fn test(request_builder: impl FnOnce(PackageHash, AddressableEntityHash) -> ExecuteRequest) { +fn test(deploy_item_builder: impl FnOnce(PackageHash, AddressableEntityHash) -> DeployItem) { let (mut builder, contract_package_hash, contract_hash) = setup(); - let exec_request = request_builder(contract_package_hash, contract_hash); - + let deploy_item = deploy_item_builder(contract_package_hash, contract_hash); + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request).expect_success().commit(); let account = builder @@ -89,7 +90,7 @@ fn test(request_builder: impl FnOnce(PackageHash, AddressableEntityHash) -> Exec #[test] fn should_run_gh_1688_regression_stored_versioned_contract_by_hash() { test(|contract_package_hash, _contract_hash| { - let deploy_item = DeployItemBuilder::new() + DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_hash( contract_package_hash.value(), @@ -100,8 +101,7 @@ fn should_run_gh_1688_regression_stored_versioned_contract_by_hash() { .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([42; 32]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + .build() }); } @@ -109,7 +109,7 @@ fn should_run_gh_1688_regression_stored_versioned_contract_by_hash() { #[test] fn should_run_gh_1688_regression_stored_versioned_contract_by_name() { test(|_contract_package_hash, _contract_hash| { - let deploy_item = DeployItemBuilder::new() + DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_KEY, @@ -120,9 +120,7 @@ fn should_run_gh_1688_regression_stored_versioned_contract_by_name() { .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([42; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + .build() }); } @@ -130,15 +128,13 @@ fn should_run_gh_1688_regression_stored_versioned_contract_by_name() { #[test] fn should_run_gh_1688_regression_stored_contract_by_hash() { test(|_contract_package_hash, contract_hash| { - let deploy_item = DeployItemBuilder::new() + DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_session_hash(contract_hash, METHOD_PUT_KEY, RuntimeArgs::default()) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([42; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + .build() }); } @@ -146,7 +142,7 @@ fn should_run_gh_1688_regression_stored_contract_by_hash() { #[test] fn should_run_gh_1688_regression_stored_contract_by_name() { test(|_contract_package_hash, _contract_hash| { - let deploy_item = DeployItemBuilder::new() + DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_session_named_key( CONTRACT_HASH_KEY, @@ -156,8 +152,6 @@ fn should_run_gh_1688_regression_stored_contract_by_name() { .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([42; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + .build() }); } diff --git a/execution_engine_testing/tests/src/test/regression/gh_1902.rs b/execution_engine_testing/tests/src/test/regression/gh_1902.rs index 013e09f03a..ae620241ae 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1902.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1902.rs @@ -110,29 +110,26 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { let add_bid_payment_amount = U512::from(add_bid_cost + pay_cost) * 2; - let add_bid_request = { - let sender = *DEFAULT_ACCOUNT_ADDR; - let contract_hash = builder.get_auction_contract_hash(); - let entry_point = auction::METHOD_ADD_BID; - let payment_args = - runtime_args! { standard_payment::ARG_AMOUNT => add_bid_payment_amount, }; - let session_args = runtime_args! { - auction::ARG_PUBLIC_KEY => DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), - auction::ARG_AMOUNT => bond_amount, - auction::ARG_DELEGATION_RATE => DELEGATION_RATE, - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_stored_session_hash(contract_hash, entry_point, session_args) - .with_empty_payment_bytes(payment_args) - .with_authorization_keys(&[sender]) - .with_deploy_hash([43; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let sender = *DEFAULT_ACCOUNT_ADDR; + let contract_hash = builder.get_auction_contract_hash(); + let entry_point = auction::METHOD_ADD_BID; + let payment_args = runtime_args! { standard_payment::ARG_AMOUNT => add_bid_payment_amount, }; + let session_args = runtime_args! { + auction::ARG_PUBLIC_KEY => DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), + auction::ARG_AMOUNT => bond_amount, + auction::ARG_DELEGATION_RATE => DELEGATION_RATE, }; + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_stored_session_hash(contract_hash, entry_point, session_args) + .with_empty_payment_bytes(payment_args) + .with_authorization_keys(&[sender]) + .with_deploy_hash([43; 32]) + .build(); + + let add_bid_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); + exec_and_assert_costs( &mut builder, add_bid_request, @@ -146,30 +143,28 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { let delegate_payment_amount = U512::from(delegate_cost); let delegate_amount = U512::from(DELEGATE_AMOUNT); - let delegate_request = { - let sender = *ACCOUNT_1_ADDR; - let contract_hash = builder.get_auction_contract_hash(); - let entry_point = auction::METHOD_DELEGATE; - let payment_args = runtime_args! { - standard_payment::ARG_AMOUNT => delegate_payment_amount, - }; - let session_args = runtime_args! { - auction::ARG_DELEGATOR => ACCOUNT_1_PUBLIC_KEY.clone(), - auction::ARG_VALIDATOR => DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), - auction::ARG_AMOUNT => delegate_amount, - }; - let deploy_hash = [55; 32]; - - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_stored_session_hash(contract_hash, entry_point, session_args) - .with_empty_payment_bytes(payment_args) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let sender = *ACCOUNT_1_ADDR; + let contract_hash = builder.get_auction_contract_hash(); + let entry_point = auction::METHOD_DELEGATE; + let payment_args = runtime_args! { + standard_payment::ARG_AMOUNT => delegate_payment_amount, + }; + let session_args = runtime_args! { + auction::ARG_DELEGATOR => ACCOUNT_1_PUBLIC_KEY.clone(), + auction::ARG_VALIDATOR => DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), + auction::ARG_AMOUNT => delegate_amount, }; + let deploy_hash = [55; 32]; + + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_stored_session_hash(contract_hash, entry_point, session_args) + .with_empty_payment_bytes(payment_args) + .with_authorization_keys(&[sender]) + .with_deploy_hash(deploy_hash) + .build(); + + let delegate_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); exec_and_assert_costs( &mut builder, @@ -184,30 +179,28 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { let undelegate_payment_amount = U512::from(undelegate_cost); let undelegate_amount = delegate_amount; - let undelegate_request = { - let sender = *ACCOUNT_1_ADDR; - let contract_hash = builder.get_auction_contract_hash(); - let entry_point = auction::METHOD_UNDELEGATE; - let payment_args = runtime_args! { - standard_payment::ARG_AMOUNT => undelegate_payment_amount, - }; - let session_args = runtime_args! { - auction::ARG_DELEGATOR => ACCOUNT_1_PUBLIC_KEY.clone(), - auction::ARG_VALIDATOR => DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), - auction::ARG_AMOUNT => undelegate_amount, - }; - let deploy_hash = [56; 32]; - - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_stored_session_hash(contract_hash, entry_point, session_args) - .with_empty_payment_bytes(payment_args) - .with_authorization_keys(&[sender]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let sender = *ACCOUNT_1_ADDR; + let contract_hash = builder.get_auction_contract_hash(); + let entry_point = auction::METHOD_UNDELEGATE; + let payment_args = runtime_args! { + standard_payment::ARG_AMOUNT => undelegate_payment_amount, }; + let session_args = runtime_args! { + auction::ARG_DELEGATOR => ACCOUNT_1_PUBLIC_KEY.clone(), + auction::ARG_VALIDATOR => DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), + auction::ARG_AMOUNT => undelegate_amount, + }; + let deploy_hash = [56; 32]; + + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_stored_session_hash(contract_hash, entry_point, session_args) + .with_empty_payment_bytes(payment_args) + .with_authorization_keys(&[sender]) + .with_deploy_hash(deploy_hash) + .build(); + + let undelegate_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); exec_and_assert_costs( &mut builder, @@ -223,28 +216,26 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { let withdraw_bid_cost = builder.get_auction_costs().withdraw_bid; let withdraw_bid_payment_amount = U512::from(withdraw_bid_cost); - let withdraw_bid_request = { - let sender = *DEFAULT_ACCOUNT_ADDR; - let contract_hash = builder.get_auction_contract_hash(); - let entry_point = auction::METHOD_WITHDRAW_BID; - let payment_args = - runtime_args! { standard_payment::ARG_AMOUNT => withdraw_bid_payment_amount, }; - let session_args = runtime_args! { - auction::ARG_PUBLIC_KEY => DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), - auction::ARG_AMOUNT => unbond_amount, - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_stored_session_hash(contract_hash, entry_point, session_args) - .with_empty_payment_bytes(payment_args) - .with_authorization_keys(&[sender]) - .with_deploy_hash([58; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let sender = *DEFAULT_ACCOUNT_ADDR; + let contract_hash = builder.get_auction_contract_hash(); + let entry_point = auction::METHOD_WITHDRAW_BID; + let payment_args = + runtime_args! { standard_payment::ARG_AMOUNT => withdraw_bid_payment_amount, }; + let session_args = runtime_args! { + auction::ARG_PUBLIC_KEY => DEFAULT_ACCOUNT_PUBLIC_KEY.clone(), + auction::ARG_AMOUNT => unbond_amount, }; + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_stored_session_hash(contract_hash, entry_point, session_args) + .with_empty_payment_bytes(payment_args) + .with_authorization_keys(&[sender]) + .with_deploy_hash([58; 32]) + .build(); + + let withdraw_bid_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); + exec_and_assert_costs( &mut builder, withdraw_bid_request, diff --git a/execution_engine_testing/tests/src/test/regression/gh_2280.rs b/execution_engine_testing/tests/src/test/regression/gh_2280.rs index c629e2e80a..7b6f38477c 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_2280.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_2280.rs @@ -82,26 +82,24 @@ fn gh_2280_transfer_should_always_cost_the_same_gas() { // should be able to pay next time. let payment_amount = Motes::from_gas(gas_cost_1, 1).unwrap(); - let fund_request_2 = { - let deploy_hash: [u8; 32] = [55; 32]; - let faucet_args_2 = runtime_args! { - ARG_TARGET => *ACCOUNT_2_ADDR, - ARG_AMOUNT => TOKEN_AMOUNT, - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(account_hash) - .with_session_code(session_file, faucet_args_2) - // + default_create_purse_cost - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => payment_amount.value() - }) - .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let deploy_hash: [u8; 32] = [55; 32]; + let faucet_args_2 = runtime_args! { + ARG_TARGET => *ACCOUNT_2_ADDR, + ARG_AMOUNT => TOKEN_AMOUNT, }; + + let deploy_item = DeployItemBuilder::new() + .with_address(account_hash) + .with_session_code(session_file, faucet_args_2) + // + default_create_purse_cost + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => payment_amount.value() + }) + .with_authorization_keys(&[account_hash]) + .with_deploy_hash(deploy_hash) + .build(); + + let fund_request_2 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(fund_request_2).expect_success().commit(); let gas_cost_2 = builder.last_exec_gas_cost(); @@ -144,26 +142,24 @@ fn gh_2280_transfer_should_always_cost_the_same_gas() { let mut upgrade_request = make_upgrade_request(); builder.upgrade(&mut upgrade_request); - let fund_request_3 = { - let deploy_hash: [u8; 32] = [77; 32]; - let faucet_args_3 = runtime_args! { - ARG_TARGET => *ACCOUNT_3_ADDR, - ARG_AMOUNT => TOKEN_AMOUNT, - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(account_hash) - .with_session_code(session_file, faucet_args_3) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE - }) - .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let deploy_hash: [u8; 32] = [77; 32]; + let faucet_args_3 = runtime_args! { + ARG_TARGET => *ACCOUNT_3_ADDR, + ARG_AMOUNT => TOKEN_AMOUNT, }; + let deploy_item = DeployItemBuilder::new() + .with_address(account_hash) + .with_session_code(session_file, faucet_args_3) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE + }) + .with_authorization_keys(&[account_hash]) + .with_deploy_hash(deploy_hash) + .build(); + + let fund_request_3 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); + builder.exec(fund_request_3).expect_success().commit(); let gas_cost_3 = builder.last_exec_gas_cost(); @@ -200,25 +196,23 @@ fn gh_2280_create_purse_should_always_cost_the_same_gas() { // should be able to pay next time. let payment_amount = Motes::from_gas(gas_cost_1, 1).unwrap(); - let fund_request_2 = { - let deploy_hash: [u8; 32] = [55; 32]; - let create_purse_args_2 = runtime_args! { - ARG_PURSE_NAME => TEST_PURSE_NAME, - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(account_hash) - .with_session_code(session_file, create_purse_args_2) - // + default_create_purse_cost - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => payment_amount.value() - }) - .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let deploy_hash: [u8; 32] = [55; 32]; + let create_purse_args_2 = runtime_args! { + ARG_PURSE_NAME => TEST_PURSE_NAME, }; + + let deploy_item = DeployItemBuilder::new() + .with_address(account_hash) + .with_session_code(session_file, create_purse_args_2) + // + default_create_purse_cost + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => payment_amount.value() + }) + .with_authorization_keys(&[account_hash]) + .with_deploy_hash(deploy_hash) + .build(); + + let fund_request_2 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(fund_request_2).expect_success().commit(); let gas_cost_2 = builder.last_exec_gas_cost(); @@ -263,25 +257,23 @@ fn gh_2280_create_purse_should_always_cost_the_same_gas() { .upgrade(&mut upgrade_request) .expect_upgrade_success(); - let fund_request_3 = { - let deploy_hash: [u8; 32] = [77; 32]; - let create_purse_args_3 = runtime_args! { - ARG_PURSE_NAME => TEST_PURSE_NAME, - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(account_hash) - .with_session_code(session_file, create_purse_args_3) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE - }) - .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let deploy_hash: [u8; 32] = [77; 32]; + let create_purse_args_3 = runtime_args! { + ARG_PURSE_NAME => TEST_PURSE_NAME, }; + let deploy_item = DeployItemBuilder::new() + .with_address(account_hash) + .with_session_code(session_file, create_purse_args_3) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE + }) + .with_authorization_keys(&[account_hash]) + .with_deploy_hash(deploy_hash) + .build(); + + let fund_request_3 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); + builder.exec(fund_request_3).expect_success().commit(); let gas_cost_3 = builder.last_exec_gas_cost(); @@ -319,26 +311,24 @@ fn gh_2280_transfer_purse_to_account_should_always_cost_the_same_gas() { // should be able to pay next time. let payment_amount = Motes::from_gas(gas_cost_1, 1).unwrap(); - let fund_request_2 = { - let deploy_hash: [u8; 32] = [55; 32]; - let faucet_args_2 = runtime_args! { - ARG_TARGET => *ACCOUNT_2_ADDR, - ARG_AMOUNT => U512::from(TOKEN_AMOUNT), - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(account_hash) - .with_session_code(TRANSFER_PURSE_TO_ACCOUNT_CONTRACT, faucet_args_2) - // + default_create_purse_cost - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => payment_amount.value() - }) - .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let deploy_hash: [u8; 32] = [55; 32]; + let faucet_args_2 = runtime_args! { + ARG_TARGET => *ACCOUNT_2_ADDR, + ARG_AMOUNT => U512::from(TOKEN_AMOUNT), }; + + let deploy_item = DeployItemBuilder::new() + .with_address(account_hash) + .with_session_code(TRANSFER_PURSE_TO_ACCOUNT_CONTRACT, faucet_args_2) + // + default_create_purse_cost + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => payment_amount.value() + }) + .with_authorization_keys(&[account_hash]) + .with_deploy_hash(deploy_hash) + .build(); + + let fund_request_2 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(fund_request_2).expect_success().commit(); let gas_cost_2 = builder.last_exec_gas_cost(); @@ -385,26 +375,24 @@ fn gh_2280_transfer_purse_to_account_should_always_cost_the_same_gas() { .with_chainspec(updated_chainspec) .upgrade(&mut upgrade_request); - let fund_request_3 = { - let deploy_hash: [u8; 32] = [77; 32]; - let faucet_args_3 = runtime_args! { - ARG_TARGET => *ACCOUNT_3_ADDR, - ARG_AMOUNT => U512::from(TOKEN_AMOUNT), - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(account_hash) - .with_session_code(session_file, faucet_args_3) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE - }) - .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let deploy_hash: [u8; 32] = [77; 32]; + let faucet_args_3 = runtime_args! { + ARG_TARGET => *ACCOUNT_3_ADDR, + ARG_AMOUNT => U512::from(TOKEN_AMOUNT), }; + let deploy_item = DeployItemBuilder::new() + .with_address(account_hash) + .with_session_code(session_file, faucet_args_3) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE + }) + .with_authorization_keys(&[account_hash]) + .with_deploy_hash(deploy_hash) + .build(); + + let fund_request_3 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); + builder.exec(fund_request_3).expect_success().commit(); let gas_cost_3 = builder.last_exec_gas_cost(); @@ -446,25 +434,23 @@ fn gh_2280_stored_transfer_to_account_should_always_cost_the_same_gas() { // should be able to pay next time. let payment_amount = Motes::from_gas(gas_cost_1, 1).unwrap(); - let fund_request_2 = { - let deploy_hash: [u8; 32] = [55; 32]; - let faucet_args_2 = runtime_args! { - ARG_TARGET => *ACCOUNT_2_ADDR, - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(account_hash) - .with_stored_session_hash(gh_2280_regression, entry_point, faucet_args_2) - // + default_create_purse_cost - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => payment_amount.value() - }) - .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let deploy_hash: [u8; 32] = [55; 32]; + let faucet_args_2 = runtime_args! { + ARG_TARGET => *ACCOUNT_2_ADDR, }; + + let deploy_item = DeployItemBuilder::new() + .with_address(account_hash) + .with_stored_session_hash(gh_2280_regression, entry_point, faucet_args_2) + // + default_create_purse_cost + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => payment_amount.value() + }) + .with_authorization_keys(&[account_hash]) + .with_deploy_hash(deploy_hash) + .build(); + + let fund_request_2 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(fund_request_2).expect_success().commit(); let gas_cost_2 = builder.last_exec_gas_cost(); @@ -511,25 +497,23 @@ fn gh_2280_stored_transfer_to_account_should_always_cost_the_same_gas() { .with_chainspec(updated_chainspec) .upgrade(&mut upgrade_request); - let fund_request_3 = { - let deploy_hash: [u8; 32] = [77; 32]; - let faucet_args_3 = runtime_args! { - ARG_TARGET => *ACCOUNT_3_ADDR, - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(account_hash) - .with_stored_session_hash(gh_2280_regression, entry_point, faucet_args_3) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE - }) - .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let deploy_hash: [u8; 32] = [77; 32]; + let faucet_args_3 = runtime_args! { + ARG_TARGET => *ACCOUNT_3_ADDR, }; + let deploy_item = DeployItemBuilder::new() + .with_address(account_hash) + .with_stored_session_hash(gh_2280_regression, entry_point, faucet_args_3) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE + }) + .with_authorization_keys(&[account_hash]) + .with_deploy_hash(deploy_hash) + .build(); + + let fund_request_3 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); + builder.exec(fund_request_3).expect_success().commit(); let gas_cost_3 = builder.last_exec_gas_cost(); @@ -567,26 +551,24 @@ fn gh_2280_stored_faucet_call_should_cost_the_same() { // should be able to pay next time. let payment_amount = Motes::from_gas(gas_cost_1, 1).unwrap(); - let fund_request_2 = { - let deploy_hash: [u8; 32] = [55; 32]; - let faucet_args_2 = runtime_args! { - ARG_CONTRACT_HASH => gh_2280_regression, - ARG_TARGET => *ACCOUNT_2_ADDR, - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(account_hash) - .with_session_code(session_file, faucet_args_2) - // + default_create_purse_cost - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => payment_amount.value() - }) - .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let deploy_hash: [u8; 32] = [55; 32]; + let faucet_args_2 = runtime_args! { + ARG_CONTRACT_HASH => gh_2280_regression, + ARG_TARGET => *ACCOUNT_2_ADDR, }; + + let deploy_item = DeployItemBuilder::new() + .with_address(account_hash) + .with_session_code(session_file, faucet_args_2) + // + default_create_purse_cost + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => payment_amount.value() + }) + .with_authorization_keys(&[account_hash]) + .with_deploy_hash(deploy_hash) + .build(); + + let fund_request_2 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(fund_request_2).expect_success().commit(); let gas_cost_2 = builder.last_exec_gas_cost(); @@ -633,26 +615,24 @@ fn gh_2280_stored_faucet_call_should_cost_the_same() { .with_chainspec(updated_chainspec) .upgrade(&mut upgrade_request); - let fund_request_3 = { - let deploy_hash: [u8; 32] = [77; 32]; - let faucet_args_3 = runtime_args! { - ARG_CONTRACT_HASH => gh_2280_regression, - ARG_TARGET => *ACCOUNT_3_ADDR, - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(account_hash) - .with_session_code(session_file, faucet_args_3) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE - }) - .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let deploy_hash: [u8; 32] = [77; 32]; + let faucet_args_3 = runtime_args! { + ARG_CONTRACT_HASH => gh_2280_regression, + ARG_TARGET => *ACCOUNT_3_ADDR, }; + let deploy_item = DeployItemBuilder::new() + .with_address(account_hash) + .with_session_code(session_file, faucet_args_3) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE + }) + .with_authorization_keys(&[account_hash]) + .with_deploy_hash(deploy_hash) + .build(); + + let fund_request_3 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); + builder.exec(fund_request_3).expect_success().commit(); let gas_cost_3 = builder.last_exec_gas_cost(); diff --git a/execution_engine_testing/tests/src/test/regression/gh_3208.rs b/execution_engine_testing/tests/src/test/regression/gh_3208.rs index cce1df0315..6b34845ce1 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_3208.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_3208.rs @@ -197,47 +197,43 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule() builder.exec(add_bid_request).expect_success().commit(); - let withdraw_bid_request_1 = { - let sender = *DEFAULT_PROPOSER_ADDR; - let contract_hash = builder.get_auction_contract_hash(); - let entry_point = auction::METHOD_WITHDRAW_BID; - let payment_args = runtime_args! { standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT, }; - let session_args = runtime_args! { - auction::ARG_PUBLIC_KEY => DEFAULT_PROPOSER_PUBLIC_KEY.clone(), - auction::ARG_AMOUNT => *DEFAULT_PROPOSER_ACCOUNT_INITIAL_STAKE, - }; - - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_stored_session_hash(contract_hash, entry_point, session_args) - .with_empty_payment_bytes(payment_args) - .with_authorization_keys(&[sender]) - .with_deploy_hash([58; 32]) - .build(); + let sender = *DEFAULT_PROPOSER_ADDR; + let contract_hash = builder.get_auction_contract_hash(); + let entry_point = auction::METHOD_WITHDRAW_BID; + let payment_args = runtime_args! { standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT, }; + let session_args = runtime_args! { + auction::ARG_PUBLIC_KEY => DEFAULT_PROPOSER_PUBLIC_KEY.clone(), + auction::ARG_AMOUNT => *DEFAULT_PROPOSER_ACCOUNT_INITIAL_STAKE, + }; - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_stored_session_hash(contract_hash, entry_point, session_args) + .with_empty_payment_bytes(payment_args) + .with_authorization_keys(&[sender]) + .with_deploy_hash([58; 32]) + .build(); + + let withdraw_bid_request_1 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); + + let sender = *DEFAULT_PROPOSER_ADDR; + let contract_hash = builder.get_auction_contract_hash(); + let entry_point = auction::METHOD_WITHDRAW_BID; + let payment_args = runtime_args! { standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT, }; + let session_args = runtime_args! { + auction::ARG_PUBLIC_KEY => DEFAULT_PROPOSER_PUBLIC_KEY.clone(), + auction::ARG_AMOUNT => *DEFAULT_PROPOSER_ACCOUNT_INITIAL_STAKE, }; - let withdraw_bid_request_2 = { - let sender = *DEFAULT_PROPOSER_ADDR; - let contract_hash = builder.get_auction_contract_hash(); - let entry_point = auction::METHOD_WITHDRAW_BID; - let payment_args = runtime_args! { standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT, }; - let session_args = runtime_args! { - auction::ARG_PUBLIC_KEY => DEFAULT_PROPOSER_PUBLIC_KEY.clone(), - auction::ARG_AMOUNT => *DEFAULT_PROPOSER_ACCOUNT_INITIAL_STAKE, - }; + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_stored_session_hash(contract_hash, entry_point, session_args) + .with_empty_payment_bytes(payment_args) + .with_authorization_keys(&[sender]) + .with_deploy_hash([59; 32]) + .build(); - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_stored_session_hash(contract_hash, entry_point, session_args) - .with_empty_payment_bytes(payment_args) - .with_authorization_keys(&[sender]) - .with_deploy_hash([59; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let withdraw_bid_request_2 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder .exec(withdraw_bid_request_1) @@ -345,26 +341,24 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule_a "should run step to initialize a schedule" ); - let withdraw_bid_request_1 = { - let sender = *DEFAULT_PROPOSER_ADDR; - let contract_hash = builder.get_auction_contract_hash(); - let entry_point = auction::METHOD_WITHDRAW_BID; - let payment_args = runtime_args! { standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT, }; - let session_args = runtime_args! { - auction::ARG_PUBLIC_KEY => DEFAULT_PROPOSER_PUBLIC_KEY.clone(), - auction::ARG_AMOUNT => *DEFAULT_PROPOSER_ACCOUNT_INITIAL_STAKE, - }; + let sender = *DEFAULT_PROPOSER_ADDR; + let contract_hash = builder.get_auction_contract_hash(); + let entry_point = auction::METHOD_WITHDRAW_BID; + let payment_args = runtime_args! { standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT, }; + let session_args = runtime_args! { + auction::ARG_PUBLIC_KEY => DEFAULT_PROPOSER_PUBLIC_KEY.clone(), + auction::ARG_AMOUNT => *DEFAULT_PROPOSER_ACCOUNT_INITIAL_STAKE, + }; - let deploy_item = DeployItemBuilder::new() - .with_address(sender) - .with_stored_session_hash(contract_hash, entry_point, session_args) - .with_empty_payment_bytes(payment_args) - .with_authorization_keys(&[sender]) - .with_deploy_hash([58; 32]) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(sender) + .with_stored_session_hash(contract_hash, entry_point, session_args) + .with_empty_payment_bytes(payment_args) + .with_authorization_keys(&[sender]) + .with_deploy_hash([58; 32]) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let withdraw_bid_request_1 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder .exec(withdraw_bid_request_1) diff --git a/execution_engine_testing/tests/src/test/regression/gov_42.rs b/execution_engine_testing/tests/src/test/regression/gov_42.rs index 9742c3d186..c201c6e198 100644 --- a/execution_engine_testing/tests/src/test/regression/gov_42.rs +++ b/execution_engine_testing/tests/src/test/regression/gov_42.rs @@ -39,40 +39,33 @@ enum ExecutionPhase { fn run_test_case(input_wasm_bytes: &[u8], expected_error: &str, execution_phase: ExecutionPhase) { let payment_amount = *DEFAULT_PAYMENT; - let (do_minimum_request_builder, expected_error_message) = { - let account_hash = *DEFAULT_ACCOUNT_ADDR; - let session_args = RuntimeArgs::default(); - let deploy_hash = [42; 32]; - - let (deploy_item_builder, expected_error_message) = match execution_phase { - ExecutionPhase::Payment => ( - DeployItemBuilder::new() - .with_payment_bytes( - input_wasm_bytes.to_vec(), - runtime_args! {ARG_AMOUNT => payment_amount,}, - ) - .with_session_bytes(wasm_utils::do_nothing_bytes(), session_args), - expected_error, - ), - ExecutionPhase::Session => ( - DeployItemBuilder::new() - .with_session_bytes(input_wasm_bytes.to_vec(), session_args) - .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => payment_amount,}), - expected_error, - ), - }; - let deploy_item = deploy_item_builder - .with_address(account_hash) - .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) - .build(); - - ( - ExecuteRequestBuilder::from_deploy_item(deploy_item), - expected_error_message, - ) + let account_hash = *DEFAULT_ACCOUNT_ADDR; + let session_args = RuntimeArgs::default(); + let deploy_hash = [42; 32]; + + let (deploy_item_builder, expected_error_message) = match execution_phase { + ExecutionPhase::Payment => ( + DeployItemBuilder::new() + .with_payment_bytes( + input_wasm_bytes.to_vec(), + runtime_args! {ARG_AMOUNT => payment_amount,}, + ) + .with_session_bytes(wasm_utils::do_nothing_bytes(), session_args), + expected_error, + ), + ExecutionPhase::Session => ( + DeployItemBuilder::new() + .with_session_bytes(input_wasm_bytes.to_vec(), session_args) + .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => payment_amount,}), + expected_error, + ), }; - let do_minimum_request = do_minimum_request_builder.build(); + let deploy_item = deploy_item_builder + .with_address(account_hash) + .with_authorization_keys(&[account_hash]) + .with_deploy_hash(deploy_hash) + .build(); + let do_minimum_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); diff --git a/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs b/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs index 050bdeb5ec..085e2319f4 100644 --- a/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs +++ b/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs @@ -59,7 +59,7 @@ fn host_function_metrics_has_acceptable_size() { ) } -fn create_account_exec_request(address: AccountHash) -> ExecuteRequest { +fn create_account_exec_request<'a>(address: AccountHash) -> ExecuteRequest<'a> { ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, CONTRACT_TRANSFER_TO_ACCOUNT_U512, @@ -85,25 +85,23 @@ fn host_function_metrics_has_acceptable_gas_cost() { random_bytes }; - let exec_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(ACCOUNT0_ADDR) - .with_deploy_hash([55; 32]) - .with_session_code( - CONTRACT_HOST_FUNCTION_METRICS, - runtime_args! { - ARG_SEED => seed, - ARG_OTHERS => (Bytes::from(random_bytes), ACCOUNT0_ADDR, ACCOUNT1_ADDR), - ARG_AMOUNT => TRANSFER_FROM_MAIN_PURSE_AMOUNT, - }, - ) - .with_empty_payment_bytes( - runtime_args! { standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT }, - ) - .with_authorization_keys(&[ACCOUNT0_ADDR]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let deploy_item = DeployItemBuilder::new() + .with_address(ACCOUNT0_ADDR) + .with_deploy_hash([55; 32]) + .with_session_code( + CONTRACT_HOST_FUNCTION_METRICS, + runtime_args! { + ARG_SEED => seed, + ARG_OTHERS => (Bytes::from(random_bytes), ACCOUNT0_ADDR, ACCOUNT1_ADDR), + ARG_AMOUNT => TRANSFER_FROM_MAIN_PURSE_AMOUNT, + }, + ) + .with_empty_payment_bytes( + runtime_args! { standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT }, + ) + .with_authorization_keys(&[ACCOUNT0_ADDR]) + .build(); + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20210707.rs b/execution_engine_testing/tests/src/test/regression/regression_20210707.rs index ee0010a450..3f061c664f 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20210707.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20210707.rs @@ -42,7 +42,7 @@ static BOB_KEY: Lazy = Lazy::new(|| { }); static BOB_ADDR: Lazy = Lazy::new(|| AccountHash::from(&*BOB_KEY)); -fn setup_regression_contract() -> ExecuteRequest { +fn setup_regression_contract<'a>() -> ExecuteRequest<'a> { ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, REGRESSION_20210707, @@ -375,22 +375,20 @@ fn should_not_refund_to_bob_and_charge_alice() { let contract_hash = get_account_entity_hash(&account); - let call_request = { - let args = runtime_args! { - ARG_SOURCE => bob_main_purse, - ARG_AMOUNT => *DEFAULT_PAYMENT, - }; - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - // Just do nothing if ever we'd get into session execution - .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) - .with_stored_payment_hash(contract_hash, METHOD_STORED_PAYMENT, args) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([77; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let args = runtime_args! { + ARG_SOURCE => bob_main_purse, + ARG_AMOUNT => *DEFAULT_PAYMENT, }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + // Just do nothing if ever we'd get into session execution + .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) + .with_stored_payment_hash(contract_hash, METHOD_STORED_PAYMENT, args) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([77; 32]) + .build(); + + let call_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(call_request).commit(); @@ -433,22 +431,20 @@ fn should_not_charge_alice_for_execution() { let contract_hash = get_account_entity_hash(&account); - let call_request = { - let args = runtime_args! { - ARG_SOURCE => bob_main_purse, - ARG_AMOUNT => *DEFAULT_PAYMENT, - }; - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - // Just do nothing if ever we'd get into session execution - .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) - .with_stored_payment_hash(contract_hash, METHOD_STORED_PAYMENT, args) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([77; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let args = runtime_args! { + ARG_SOURCE => bob_main_purse, + ARG_AMOUNT => *DEFAULT_PAYMENT, }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + // Just do nothing if ever we'd get into session execution + .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) + .with_stored_payment_hash(contract_hash, METHOD_STORED_PAYMENT, args) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([77; 32]) + .build(); + + let call_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(call_request).commit(); @@ -488,21 +484,19 @@ fn should_not_charge_for_execution_from_hardcoded_purse() { let contract_hash = get_account_entity_hash(&account); - let call_request = { - let args = runtime_args! { - ARG_AMOUNT => *DEFAULT_PAYMENT, - }; - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - // Just do nothing if ever we'd get into session execution - .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) - .with_stored_payment_hash(contract_hash, METHOD_HARDCODED_PAYMENT, args) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([77; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let args = runtime_args! { + ARG_AMOUNT => *DEFAULT_PAYMENT, }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + // Just do nothing if ever we'd get into session execution + .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) + .with_stored_payment_hash(contract_hash, METHOD_HARDCODED_PAYMENT, args) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([77; 32]) + .build(); + + let call_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(call_request).commit(); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20210924.rs b/execution_engine_testing/tests/src/test/regression/regression_20210924.rs index d3e6dd7fcf..d901a87b54 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20210924.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20210924.rs @@ -14,23 +14,21 @@ const ARG_AMOUNT: &str = "amount"; fn should_charge_minimum_for_do_nothing_session() { let minimum_deploy_payment = U512::from(0); - let do_nothing_request = { - let account_hash = *DEFAULT_ACCOUNT_ADDR; - let session_args = RuntimeArgs::default(); - let deploy_hash = [42; 32]; - - let deploy_item = DeployItemBuilder::new() - .with_address(account_hash) - .with_session_bytes(wasm_utils::do_nothing_bytes(), session_args) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => minimum_deploy_payment, - }) - .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let account_hash = *DEFAULT_ACCOUNT_ADDR; + let session_args = RuntimeArgs::default(); + let deploy_hash = [42; 32]; + + let deploy_item = DeployItemBuilder::new() + .with_address(account_hash) + .with_session_bytes(wasm_utils::do_nothing_bytes(), session_args) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => minimum_deploy_payment, + }) + .with_authorization_keys(&[account_hash]) + .with_deploy_hash(deploy_hash) + .build(); + + let do_nothing_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); @@ -71,23 +69,21 @@ fn should_charge_minimum_for_do_nothing_session() { fn should_execute_do_minimum_session() { let minimum_deploy_payment = U512::from(DEFAULT_NOP_COST); - let do_minimum_request = { - let account_hash = *DEFAULT_ACCOUNT_ADDR; - let session_args = RuntimeArgs::default(); - let deploy_hash = [42; 32]; + let account_hash = *DEFAULT_ACCOUNT_ADDR; + let session_args = RuntimeArgs::default(); + let deploy_hash = [42; 32]; - let deploy_item = DeployItemBuilder::new() - .with_address(account_hash) - .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => minimum_deploy_payment, - }) - .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(account_hash) + .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => minimum_deploy_payment, + }) + .with_authorization_keys(&[account_hash]) + .with_deploy_hash(deploy_hash) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let do_minimum_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); @@ -124,26 +120,24 @@ fn should_execute_do_minimum_session() { fn should_charge_minimum_for_do_nothing_payment() { let minimum_deploy_payment = U512::from(0); - let do_nothing_request = { - let account_hash = *DEFAULT_ACCOUNT_ADDR; - let session_args = RuntimeArgs::default(); - let deploy_hash = [42; 32]; - - let deploy_item = DeployItemBuilder::new() - .with_address(account_hash) - .with_session_bytes(wasm_utils::do_nothing_bytes(), session_args) - .with_payment_bytes( - wasm_utils::do_nothing_bytes(), - runtime_args! { - ARG_AMOUNT => minimum_deploy_payment, - }, - ) - .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let account_hash = *DEFAULT_ACCOUNT_ADDR; + let session_args = RuntimeArgs::default(); + let deploy_hash = [42; 32]; + + let deploy_item = DeployItemBuilder::new() + .with_address(account_hash) + .with_session_bytes(wasm_utils::do_nothing_bytes(), session_args) + .with_payment_bytes( + wasm_utils::do_nothing_bytes(), + runtime_args! { + ARG_AMOUNT => minimum_deploy_payment, + }, + ) + .with_authorization_keys(&[account_hash]) + .with_deploy_hash(deploy_hash) + .build(); + + let do_nothing_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20211110.rs b/execution_engine_testing/tests/src/test/regression/regression_20211110.rs index 360dff5958..20d6624918 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20211110.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20211110.rs @@ -26,21 +26,19 @@ fn regression_20211110() { let transfer_request = TransferRequestBuilder::new(funds, ACCOUNT_1_ADDR).build(); - let install_request = { - let session_args = runtime_args! {}; - let payment_args = runtime_args! { - standard_payment::ARG_AMOUNT => U512::from(INSTALL_COST) - }; - let deploy_item = DeployItemBuilder::new() - .with_address(ACCOUNT_1_ADDR) - .with_empty_payment_bytes(payment_args) - .with_session_code(REGRESSION_20211110_CONTRACT, session_args) - .with_authorization_keys(&[ACCOUNT_1_ADDR]) - .with_deploy_hash([42; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let session_args = runtime_args! {}; + let payment_args = runtime_args! { + standard_payment::ARG_AMOUNT => U512::from(INSTALL_COST) }; + let deploy_item = DeployItemBuilder::new() + .with_address(ACCOUNT_1_ADDR) + .with_empty_payment_bytes(payment_args) + .with_session_code(REGRESSION_20211110_CONTRACT, session_args) + .with_authorization_keys(&[ACCOUNT_1_ADDR]) + .with_deploy_hash([42; 32]) + .build(); + + let install_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder .transfer_and_commit(transfer_request) @@ -60,22 +58,20 @@ fn regression_20211110() { _ => panic!("Couldn't find regression contract."), }; - let recurse_request = { - let payment_args = runtime_args! { - standard_payment::ARG_AMOUNT => U512::from(funds), - }; - let session_args = runtime_args! { - ARG_TARGET => contract_hash - }; - let deploy_item = DeployItemBuilder::new() - .with_address(ACCOUNT_1_ADDR) - .with_empty_payment_bytes(payment_args) - .with_stored_session_hash(contract_hash, RECURSE_ENTRYPOINT, session_args) - .with_authorization_keys(&[ACCOUNT_1_ADDR]) - .with_deploy_hash([43; 32]) - .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() + let payment_args = runtime_args! { + standard_payment::ARG_AMOUNT => U512::from(funds), + }; + let session_args = runtime_args! { + ARG_TARGET => contract_hash }; + let deploy_item = DeployItemBuilder::new() + .with_address(ACCOUNT_1_ADDR) + .with_empty_payment_bytes(payment_args) + .with_stored_session_hash(contract_hash, RECURSE_ENTRYPOINT, session_args) + .with_authorization_keys(&[ACCOUNT_1_ADDR]) + .with_deploy_hash([43; 32]) + .build(); + let recurse_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(recurse_request).expect_failure(); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220224.rs b/execution_engine_testing/tests/src/test/regression/regression_20220224.rs index 2723f318a3..f6e6e34b12 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220224.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220224.rs @@ -14,24 +14,22 @@ fn should_not_transfer_above_approved_limit_in_payment_code() { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); - let exec_request = { - let account_hash = *DEFAULT_ACCOUNT_ADDR; - let deploy_hash: [u8; 32] = [42; 32]; - let payment_args = runtime_args! { - "amount" => *DEFAULT_PAYMENT, - }; - let session_args = RuntimeArgs::default(); + let account_hash = *DEFAULT_ACCOUNT_ADDR; + let deploy_hash: [u8; 32] = [42; 32]; + let payment_args = runtime_args! { + "amount" => *DEFAULT_PAYMENT, + }; + let session_args = RuntimeArgs::default(); - let deploy_item = DeployItemBuilder::new() - .with_address(account_hash) - .with_session_code(CONTRACT_REVERT, session_args) - .with_payment_code(CONTRACT_REGRESSION_PAYMENT, payment_args) - .with_authorization_keys(&[account_hash]) - .with_deploy_hash(deploy_hash) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(account_hash) + .with_session_code(CONTRACT_REVERT, session_args) + .with_payment_code(CONTRACT_REGRESSION_PAYMENT, payment_args) + .with_authorization_keys(&[account_hash]) + .with_deploy_hash(deploy_hash) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(exec_request).expect_failure().commit(); diff --git a/execution_engine_testing/tests/src/test/regression/transforms_must_be_ordered.rs b/execution_engine_testing/tests/src/test/regression/transforms_must_be_ordered.rs index 3392f02b67..ffa479fef0 100644 --- a/execution_engine_testing/tests/src/test/regression/transforms_must_be_ordered.rs +++ b/execution_engine_testing/tests/src/test/regression/transforms_must_be_ordered.rs @@ -66,7 +66,7 @@ fn contract_transforms_should_be_ordered_in_the_effects() { builder .exec( ExecuteRequestBuilder::from_deploy_item( - DeployItemBuilder::new() + &DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_empty_payment_bytes(runtime_args! { standard_payment::ARG_AMOUNT => U512::from(150_000_000_000_u64), diff --git a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/finalize_payment.rs b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/finalize_payment.rs index 5ad151b2fe..ff2612421d 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/finalize_payment.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/finalize_payment.rs @@ -125,19 +125,17 @@ fn finalize_payment_should_refund_to_specified_purse() { "payment purse should start with zero balance" ); - let exec_request = { - let genesis_account_hash = *DEFAULT_ACCOUNT_ADDR; - - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_deploy_hash([1; 32]) - .with_session_code("do_nothing.wasm", RuntimeArgs::default()) - .with_payment_code(FINALIZE_PAYMENT, args) - .with_authorization_keys(&[genesis_account_hash]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let genesis_account_hash = *DEFAULT_ACCOUNT_ADDR; + + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_deploy_hash([1; 32]) + .with_session_code("do_nothing.wasm", RuntimeArgs::default()) + .with_payment_code(FINALIZE_PAYMENT, args) + .with_authorization_keys(&[genesis_account_hash]) + .build(); + + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let proposer_reward_starting_balance = builder.get_proposer_purse_balance(); diff --git a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/refund_purse.rs b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/refund_purse.rs index 0b61a805d9..494be66035 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/refund_purse.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/refund_purse.rs @@ -89,25 +89,23 @@ fn refund_tests(builder: &mut LmdbWasmTestBuilder, account_hash: AccountHash) { .expect_success() .commit(); - let refund_purse_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(account_hash) - .with_deploy_hash([2; 32]) - .with_session_code("do_nothing.wasm", RuntimeArgs::default()) - .with_payment_code( - "refund_purse.wasm", - runtime_args! { - ARG_PAYMENT_AMOUNT => *DEFAULT_PAYMENT, - mint::ARG_AMOUNT => *DEFAULT_PAYMENT, - ARG_PURSE_NAME_1 => LOCAL_REFUND_PURSE_1, - ARG_PURSE_NAME_2 => LOCAL_REFUND_PURSE_2, - }, - ) - .with_authorization_keys(&[account_hash]) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(account_hash) + .with_deploy_hash([2; 32]) + .with_session_code("do_nothing.wasm", RuntimeArgs::default()) + .with_payment_code( + "refund_purse.wasm", + runtime_args! { + ARG_PAYMENT_AMOUNT => *DEFAULT_PAYMENT, + mint::ARG_AMOUNT => *DEFAULT_PAYMENT, + ARG_PURSE_NAME_1 => LOCAL_REFUND_PURSE_1, + ARG_PURSE_NAME_2 => LOCAL_REFUND_PURSE_2, + }, + ) + .with_authorization_keys(&[account_hash]) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let refund_purse_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); builder.exec(refund_purse_request).expect_success().commit(); } diff --git a/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs b/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs index 2d97056597..3c7e5f454a 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs @@ -78,8 +78,7 @@ fn should_forward_payment_execution_runtime_error() { let account_1_account_hash = ACCOUNT_1_ADDR; let transferred_amount = U512::from(1); - let exec_request = { - let deploy_item = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_payment_code(REVERT_WASM, RuntimeArgs::default()) @@ -90,8 +89,7 @@ fn should_forward_payment_execution_runtime_error() { .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); @@ -147,8 +145,7 @@ fn should_forward_payment_execution_gas_limit_error() { builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); - let exec_request = { - let deploy_item = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_payment_code(ENDLESS_LOOP_WASM, RuntimeArgs::default()) @@ -159,8 +156,7 @@ fn should_forward_payment_execution_gas_limit_error() { .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let proposer_reward_starting_balance = builder.get_proposer_purse_balance(); @@ -216,8 +212,7 @@ fn should_run_out_of_gas_when_session_code_exceeds_gas_limit() { let payment_purse_amount = *DEFAULT_PAYMENT; let transferred_amount = 1; - let exec_request = { - let deploy_item = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) @@ -228,8 +223,7 @@ fn should_run_out_of_gas_when_session_code_exceeds_gas_limit() { .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); @@ -258,17 +252,15 @@ fn should_run_out_of_gas_when_session_code_exceeds_gas_limit() { fn should_correctly_charge_when_session_code_runs_out_of_gas() { let payment_purse_amount = *DEFAULT_PAYMENT; - let exec_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_deploy_hash([1; 32]) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) - .with_session_code(ENDLESS_LOOP_WASM, RuntimeArgs::default()) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_deploy_hash([1; 32]) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) + .with_session_code(ENDLESS_LOOP_WASM, RuntimeArgs::default()) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); @@ -320,8 +312,7 @@ fn should_correctly_charge_when_session_code_fails() { let payment_purse_amount = *DEFAULT_PAYMENT; let transferred_amount = 1; - let exec_request = { - let deploy_item = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) @@ -332,8 +323,7 @@ fn should_correctly_charge_when_session_code_fails() { .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); @@ -370,8 +360,7 @@ fn should_correctly_charge_when_session_code_succeeds() { let payment_purse_amount = *DEFAULT_PAYMENT; let transferred_amount = 1; - let exec_request = { - let deploy_item = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) .with_session_code( @@ -382,8 +371,7 @@ fn should_correctly_charge_when_session_code_succeeds() { .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); @@ -427,8 +415,7 @@ fn should_finalize_to_rewards_purse() { let payment_purse_amount = *DEFAULT_PAYMENT; let transferred_amount = 1; - let exec_request = { - let deploy_item = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code( TRANSFER_PURSE_TO_ACCOUNT_WASM, @@ -439,8 +426,7 @@ fn should_finalize_to_rewards_purse() { .with_deploy_hash([1; 32]) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let mut builder = LmdbWasmTestBuilder::default(); @@ -467,8 +453,7 @@ fn independent_standard_payments_should_not_write_the_same_keys() { let mut builder = LmdbWasmTestBuilder::default(); - let setup_exec_request = { - let deploy_item = DeployItemBuilder::new() + let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code( TRANSFER_PURSE_TO_ACCOUNT_WASM, @@ -479,8 +464,7 @@ fn independent_standard_payments_should_not_write_the_same_keys() { .with_deploy_hash([1; 32]) .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let setup_exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); // create another account via transfer builder @@ -489,29 +473,25 @@ fn independent_standard_payments_should_not_write_the_same_keys() { .expect_success() .commit(); - let exec_request_from_genesis = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_session_code(DO_NOTHING_WASM, RuntimeArgs::default()) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) - .with_deploy_hash([2; 32]) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_code(DO_NOTHING_WASM, RuntimeArgs::default()) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) + .with_deploy_hash([2; 32]) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request_from_genesis = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); - let exec_request_from_account_1 = { - let deploy_item = DeployItemBuilder::new() - .with_address(ACCOUNT_1_ADDR) - .with_session_code(DO_NOTHING_WASM, RuntimeArgs::default()) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) - .with_authorization_keys(&[account_1_account_hash]) - .with_deploy_hash([1; 32]) - .build(); + let deploy_item = DeployItemBuilder::new() + .with_address(ACCOUNT_1_ADDR) + .with_session_code(DO_NOTHING_WASM, RuntimeArgs::default()) + .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) + .with_authorization_keys(&[account_1_account_hash]) + .with_deploy_hash([1; 32]) + .build(); - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let exec_request_from_account_1 = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); // run two independent deploys builder diff --git a/execution_engine_testing/tests/src/test/system_costs.rs b/execution_engine_testing/tests/src/test/system_costs.rs index 75d8b3da60..6a78776f56 100644 --- a/execution_engine_testing/tests/src/test/system_costs.rs +++ b/execution_engine_testing/tests/src/test/system_costs.rs @@ -758,19 +758,17 @@ fn should_verify_do_nothing_charges_only_for_standard_payment() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should have default account"); - let do_nothing_request = { - let deploy_item = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) - .with_empty_payment_bytes(runtime_args! { - ARG_AMOUNT => *DEFAULT_PAYMENT - }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([42; 32]) - .build(); - - ExecuteRequestBuilder::from_deploy_item(deploy_item).build() - }; + let deploy_item = DeployItemBuilder::new() + .with_address(*DEFAULT_ACCOUNT_ADDR) + .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) + .with_empty_payment_bytes(runtime_args! { + ARG_AMOUNT => *DEFAULT_PAYMENT + }) + .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) + .with_deploy_hash([42; 32]) + .build(); + + let do_nothing_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); let user_funds_before = builder.get_purse_balance(default_account.main_purse()); diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 7cdc6465d1..0446e3fb25 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -135,7 +135,7 @@ pub fn execute_finalized_block( state_root_hash, block_time, custom_payment_gas_limit, - txn.clone(), + &txn, ) { Ok(pay_request) => execution_engine_v1.execute(&scratch_state, pay_request), Err(error) => { @@ -239,7 +239,7 @@ pub fn execute_finalized_block( state_root_hash, block_time, gas_limit, - txn.clone(), + &txn, ) { Ok(wasm_v1_request) => { execution_engine_v1.execute(&scratch_state, wasm_v1_request) @@ -662,7 +662,7 @@ where *state_root_hash, block_time.into(), gas_limit, - transaction, + &transaction, ) { Ok(wasm_v1_request) => execution_engine_v1.execute(state_provider, wasm_v1_request), Err(error) => WasmV1Result::invalid_executable_item(gas_limit, error), From 7b9f06eb04fbb6c68e91fcda566230aaae7022e5 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Thu, 21 Mar 2024 03:01:14 -0700 Subject: [PATCH 27/70] initial merge of Fraser's last PR; compiling but a lot of failing tests to be worked thru --- .../src/engine_state/execution_result.rs | 34 +- execution_engine/src/execution/executor.rs | 347 +----------------- execution_engine/src/runtime/stack.rs | 10 +- .../src/execute_request_builder.rs | 2 +- .../private_chain/burn_fees_and_refund.rs | 26 +- .../components/contract_runtime/operations.rs | 72 ++-- node/src/components/storage.rs | 9 +- resources/local/chainspec.toml.in | 20 +- resources/production/chainspec.toml | 22 +- resources/test/sse_data_schema.json | 2 +- types/src/chainspec.rs | 2 + types/src/chainspec/core_config.rs | 31 +- types/src/chainspec/pricing_handling.rs | 81 ++++ 13 files changed, 216 insertions(+), 442 deletions(-) create mode 100644 types/src/chainspec/pricing_handling.rs diff --git a/execution_engine/src/engine_state/execution_result.rs b/execution_engine/src/engine_state/execution_result.rs index a29c5b55b6..27281073cc 100644 --- a/execution_engine/src/engine_state/execution_result.rs +++ b/execution_engine/src/engine_state/execution_result.rs @@ -6,10 +6,9 @@ use tracing::{debug, trace}; use casper_storage::data_access_layer::BiddingResult; use casper_types::{ - bytesrepr::FromBytes, contract_messages::Messages, execution::{Effects, ExecutionResultV2 as TypesExecutionResult, TransformKindV2, TransformV2}, - CLTyped, CLValue, Gas, Key, Motes, StoredValue, TransferAddr, + CLValue, Gas, Key, Motes, StoredValue, TransferAddr, }; use super::Error; @@ -306,16 +305,6 @@ impl ExecutionResult { }) } - /// Returns a wrapped `ret` by consuming object. - pub(crate) fn take_with_ret(self, ret: T) -> (Option, Self) { - (Some(ret), self) - } - - /// Returns a self and has a return type compatible with [`ExecutionResult::take_with_ret`]. - pub(crate) fn take_without_ret(self) -> (Option, Self) { - (None, self) - } - /// Converts a bidding result to an execution result. pub fn from_bidding_result(bidding_result: BiddingResult, gas: Gas) -> Option { match bidding_result { @@ -338,27 +327,6 @@ impl ExecutionResult { } } - /// Should charge for wasm errors? - pub(crate) fn should_charge_for_errors_in_wasm(&self) -> bool { - match self { - ExecutionResult::Failure { - error, - transfers: _, - gas: _, - effects: _, - messages: _, - } => match error { - Error::Exec(err) => matches!( - err, - ExecError::WasmPreprocessing(_) | ExecError::UnsupportedWasmStart - ), - Error::WasmPreprocessing(_) => true, - _ => false, - }, - ExecutionResult::Success { .. } => false, - } - } - /// Logs execution results. pub fn log_execution_result(&self, preamble: &'static str) { trace!("{}: {:?}", preamble, self); diff --git a/execution_engine/src/execution/executor.rs b/execution_engine/src/execution/executor.rs index 31cf18e7e5..d59ab3bc49 100644 --- a/execution_engine/src/execution/executor.rs +++ b/execution_engine/src/execution/executor.rs @@ -1,25 +1,18 @@ -use std::{cell::RefCell, collections::BTreeSet, convert::TryFrom, rc::Rc}; +use std::{cell::RefCell, collections::BTreeSet, rc::Rc}; use casper_storage::{ global_state::{error::Error as GlobalStateError, state::StateReader}, - system::transfer::TransferArgs, - tracking_copy::{TrackingCopy, TrackingCopyEntityExt, TrackingCopyExt}, + tracking_copy::TrackingCopy, AddressGenerator, }; use casper_types::{ - account::AccountHash, - addressable_entity::NamedKeys, - bytesrepr::FromBytes, - system::{handle_payment, mint, HANDLE_PAYMENT, MINT}, - AddressableEntity, AddressableEntityHash, ApiError, BlockTime, CLTyped, ContextAccessRights, - EntryPointType, Gas, Key, Phase, ProtocolVersion, RuntimeArgs, StoredValue, Tagged, - TransactionHash, URef, U512, + account::AccountHash, addressable_entity::NamedKeys, AddressableEntity, AddressableEntityHash, + BlockTime, ContextAccessRights, EntryPointType, Gas, Key, Phase, ProtocolVersion, RuntimeArgs, + StoredValue, Tagged, TransactionHash, U512, }; use crate::{ - engine_state::{ - execution_kind::ExecutionKind, EngineConfig, Error as EngineStateError, ExecutionResult, - }, + engine_state::{execution_kind::ExecutionKind, EngineConfig, ExecutionResult}, execution::ExecError, runtime::{Runtime, RuntimeStack}, runtime_context::{CallingAddContractVersion, RuntimeContext}, @@ -152,142 +145,6 @@ impl Executor { } } - /// Handles necessary address resolution and orchestration to securely call a system contract - /// using the runtime. - #[allow(clippy::too_many_arguments)] - pub(crate) fn call_system_contract( - &self, - direct_system_contract_call: DirectSystemContractCall, - runtime_args: RuntimeArgs, - entity: &AddressableEntity, - authorization_keys: BTreeSet, - account_hash: AccountHash, - blocktime: BlockTime, - txn_hash: TransactionHash, - gas_limit: Gas, - protocol_version: ProtocolVersion, - tracking_copy: Rc>>, - phase: Phase, - stack: RuntimeStack, - remaining_spending_limit: U512, - ) -> (Option, ExecutionResult) - where - R: StateReader, - T: FromBytes + CLTyped, - { - let address_generator = { - let generator = AddressGenerator::new(txn_hash.as_ref(), phase); - Rc::new(RefCell::new(generator)) - }; - - // Today lack of existence of the system entity registry and lack of entry - // for the minimum defined system contracts (mint, auction, handle_payment) - // should cause the EE to panic. Do not remove the panics. - let system_entity_registry = tracking_copy - .borrow_mut() - .get_system_entity_registry() - .unwrap_or_else(|error| panic!("Could not retrieve system contracts: {:?}", error)); - - // Snapshot of effects before execution, so in case of error only nonce update - // can be returned. - let effects = tracking_copy.borrow().effects(); - let messages = tracking_copy.borrow().messages(); - - let entry_point_name = direct_system_contract_call.entry_point_name(); - - let entity_hash = match direct_system_contract_call { - DirectSystemContractCall::Transfer => { - let mint_hash = system_entity_registry - .get(MINT) - .expect("should have mint hash"); - *mint_hash - } - DirectSystemContractCall::FinalizePayment - | DirectSystemContractCall::GetPaymentPurse => { - let handle_payment_hash = system_entity_registry - .get(HANDLE_PAYMENT) - .expect("should have handle payment"); - *handle_payment_hash - } - }; - - let contract = match tracking_copy - .borrow_mut() - .get_addressable_entity_by_hash(entity_hash) - { - Ok(contract) => contract, - Err(error) => return (None, ExecutionResult::precondition_failure(error.into())), - }; - - let entity_addr = entity.entity_addr(entity_hash); - let entity_key = entity_addr.into(); - - let mut named_keys = match tracking_copy.borrow_mut().get_named_keys(entity_addr) { - Ok(named_key) => named_key, - Err(error) => return (None, ExecutionResult::precondition_failure(error.into())), - }; - - let access_rights = contract.extract_access_rights(entity_hash, &named_keys); - let calling_add_contract_version = CallingAddContractVersion::Forbidden; - let runtime_context = self.create_runtime_context( - &mut named_keys, - entity, - entity_key, - authorization_keys, - access_rights, - account_hash, - address_generator, - tracking_copy, - blocktime, - protocol_version, - txn_hash, - phase, - runtime_args.clone(), - gas_limit, - remaining_spending_limit, - EntryPointType::Called, - calling_add_contract_version, - ); - - let mut runtime = Runtime::new(runtime_context); - - // DO NOT alter this logic to call a system contract directly (such as via mint_internal, - // etc). Doing so would bypass necessary context based security checks in some use cases. It - // is intentional to use the runtime machinery for this interaction with the system - // contracts, to force all such security checks for usage via the executor into a single - // execution path. - let result = - runtime.call_contract_with_stack(entity_hash, entry_point_name, runtime_args, stack); - - match result { - Ok(value) => match value.into_t() { - Ok(ret) => ExecutionResult::Success { - effects: runtime.context().effects(), - transfers: runtime.context().transfers().to_owned(), - gas: runtime.context().gas_counter(), - messages: runtime.context().messages(), - } - .take_with_ret(ret), - Err(error) => ExecutionResult::Failure { - effects, - error: ExecError::CLValue(error).into(), - transfers: runtime.context().transfers().to_owned(), - gas: runtime.context().gas_counter(), - messages, - } - .take_without_ret(), - }, - Err(error) => ExecutionResult::Failure { - effects, - error: error.into(), - transfers: runtime.context().transfers().to_owned(), - gas: runtime.context().gas_counter(), - messages, - } - .take_without_ret(), - } - } - /// Creates new runtime context. #[allow(clippy::too_many_arguments)] fn create_runtime_context<'a, R>( @@ -339,196 +196,4 @@ impl Executor { calling_add_contract_version, ) } - - /// Executes standard payment code natively. - #[allow(clippy::too_many_arguments)] - pub(crate) fn exec_standard_payment( - &self, - payment_args: RuntimeArgs, - entity: &AddressableEntity, - authorization_keys: BTreeSet, - account_hash: AccountHash, - blocktime: BlockTime, - txn_hash: TransactionHash, - payment_gas_limit: Gas, - protocol_version: ProtocolVersion, - tracking_copy: Rc>>, - max_stack_height: usize, - ) -> Result - where - R: StateReader, - R::Error: Into, - { - let payment_amount: U512 = match try_get_amount(&payment_args) { - Ok(payment_amount) => payment_amount, - Err(error) => { - return Ok(ExecutionResult::precondition_failure(error.into())); - } - }; - - let get_payment_purse_stack = RuntimeStack::new_system_call_stack(max_stack_height); - - let (maybe_purse, get_payment_result) = self.get_payment_purse( - entity, - authorization_keys.clone(), - account_hash, - blocktime, - txn_hash, - payment_gas_limit, - protocol_version, - Rc::clone(&tracking_copy), - get_payment_purse_stack, - ); - - if get_payment_result.as_error().is_some() { - return Ok(get_payment_result); - } - - let payment_purse = match maybe_purse { - Some(payment_purse) => payment_purse, - None => return Err(EngineStateError::reverter(ApiError::HandlePayment(12))), - }; - - let runtime_args = { - let transfer_args = TransferArgs::new( - None, - entity.main_purse(), - payment_purse, - payment_amount, - None, - ); - - match RuntimeArgs::try_from(transfer_args) { - Ok(runtime_args) => runtime_args, - Err(error) => { - return Ok(ExecutionResult::precondition_failure( - ExecError::CLValue(error).into(), - )) - } - } - }; - - let transfer_stack = RuntimeStack::new_system_call_stack(max_stack_height); - - let (transfer_result, payment_result) = self.invoke_mint_to_transfer( - runtime_args, - entity, - authorization_keys, - account_hash, - blocktime, - txn_hash, - payment_gas_limit, - protocol_version, - Rc::clone(&tracking_copy), - transfer_stack, - payment_amount, - ); - - if payment_result.as_error().is_some() { - return Ok(payment_result); - } - - let transfer_result = match transfer_result { - Some(Ok(())) => Ok(()), - Some(Err(mint_error)) => match mint::Error::try_from(mint_error) { - Ok(mint_error) => Err(EngineStateError::reverter(mint_error)), - Err(_) => Err(EngineStateError::reverter(ApiError::Transfer)), - }, - None => Err(EngineStateError::reverter(ApiError::Transfer)), - }; - - transfer_result?; - - Ok(payment_result) - } - - #[allow(clippy::too_many_arguments)] - pub(crate) fn get_payment_purse( - &self, - entity: &AddressableEntity, - authorization_keys: BTreeSet, - account_hash: AccountHash, - blocktime: BlockTime, - txn_hash: TransactionHash, - payment_gas_limit: Gas, - protocol_version: ProtocolVersion, - tracking_copy: Rc>>, - stack: RuntimeStack, - ) -> (Option, ExecutionResult) - where - R: StateReader, - R::Error: Into, - { - self.call_system_contract( - DirectSystemContractCall::GetPaymentPurse, - RuntimeArgs::new(), - entity, - authorization_keys, - account_hash, - blocktime, - txn_hash, - payment_gas_limit, - protocol_version, - Rc::clone(&tracking_copy), - Phase::Payment, - stack, - U512::zero(), - ) - } - - #[allow(clippy::too_many_arguments)] - pub(crate) fn invoke_mint_to_transfer( - &self, - runtime_args: RuntimeArgs, - entity: &AddressableEntity, - authorization_keys: BTreeSet, - account_hash: AccountHash, - blocktime: BlockTime, - txn_hash: TransactionHash, - gas_limit: Gas, - protocol_version: ProtocolVersion, - tracking_copy: Rc>>, - stack: RuntimeStack, - spending_limit: U512, - ) -> (Option>, ExecutionResult) - where - R: StateReader, - R::Error: Into, - { - self.call_system_contract( - DirectSystemContractCall::Transfer, - runtime_args, - entity, - authorization_keys, - account_hash, - blocktime, - txn_hash, - gas_limit, - protocol_version, - Rc::clone(&tracking_copy), - Phase::Payment, - stack, - spending_limit, - ) - } -} - -/// Represents a variant of a system contract call. -pub(crate) enum DirectSystemContractCall { - /// Calls handle payment's `finalize` entry point. - FinalizePayment, - /// Calls mint's `transfer` entry point. - Transfer, - /// Calls handle payment's `get_payment_purse` entry point. - GetPaymentPurse, -} - -impl DirectSystemContractCall { - fn entry_point_name(&self) -> &str { - match self { - DirectSystemContractCall::FinalizePayment => handle_payment::METHOD_FINALIZE_PAYMENT, - DirectSystemContractCall::Transfer => mint::METHOD_TRANSFER, - DirectSystemContractCall::GetPaymentPurse => handle_payment::METHOD_GET_PAYMENT_PURSE, - } - } } diff --git a/execution_engine/src/runtime/stack.rs b/execution_engine/src/runtime/stack.rs index fbc13d1373..824ecea251 100644 --- a/execution_engine/src/runtime/stack.rs +++ b/execution_engine/src/runtime/stack.rs @@ -1,5 +1,5 @@ //! Runtime stacks. -use casper_types::{account::AccountHash, system::Caller, PublicKey}; +use casper_types::{account::AccountHash, system::Caller}; /// A runtime stack frame. /// @@ -41,14 +41,6 @@ impl RuntimeStack { Self { frames, max_height } } - /// Creates a new call instance that starts with a system account. - pub(crate) fn new_system_call_stack(max_height: usize) -> Self { - RuntimeStack::new_with_frame( - max_height, - Caller::initiator(PublicKey::System.to_account_hash()), - ) - } - /// Is the stack empty? pub fn is_empty(&self) -> bool { self.frames.is_empty() diff --git a/execution_engine_testing/test_support/src/execute_request_builder.rs b/execution_engine_testing/test_support/src/execute_request_builder.rs index 0d6db66d07..b684663ed5 100644 --- a/execution_engine_testing/test_support/src/execute_request_builder.rs +++ b/execution_engine_testing/test_support/src/execute_request_builder.rs @@ -6,7 +6,7 @@ use casper_execution_engine::engine_state::{ use casper_types::{ account::AccountHash, runtime_args, AddressableEntityHash, BlockTime, Digest, EntityVersion, Gas, InitiatorAddr, PackageHash, Phase, RuntimeArgs, Transaction, TransactionHash, - TransactionV1Hash, DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT, + TransactionV1Hash, }; use crate::{DeployItemBuilder, ARG_AMOUNT, DEFAULT_BLOCK_TIME, DEFAULT_PAYMENT}; diff --git a/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs b/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs index 74291ff804..d839cb0149 100644 --- a/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs +++ b/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs @@ -1,20 +1,17 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, TransferRequestBuilder, DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, + TransferRequestBuilder, DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_types::{ system::handle_payment::ACCUMULATION_PURSE_KEY, EntityAddr, FeeHandling, MintCosts, - RefundHandling, RuntimeArgs, DEFAULT_NOP_COST, U512, + RefundHandling, DEFAULT_NOP_COST, U512, }; use num_rational::Ratio; use num_traits::{One, Zero}; -use crate::{ - test::private_chain::{ - self, ACCOUNT_1_ADDR, DEFAULT_ADMIN_ACCOUNT_ADDR, PRIVATE_CHAIN_ALLOW_AUCTION_BIDS, - PRIVATE_CHAIN_ALLOW_UNRESTRICTED_TRANSFERS, PRIVATE_CHAIN_COMPUTE_REWARDS, - }, - wasm_utils, +use crate::test::private_chain::{ + self, ACCOUNT_1_ADDR, DEFAULT_ADMIN_ACCOUNT_ADDR, PRIVATE_CHAIN_ALLOW_AUCTION_BIDS, + PRIVATE_CHAIN_ALLOW_UNRESTRICTED_TRANSFERS, PRIVATE_CHAIN_COMPUTE_REWARDS, }; #[ignore] @@ -117,13 +114,14 @@ fn test_burning_fees( .expect("should have rewards purse"); let rewards_purse_uref = rewards_purse_key.into_uref().expect("should be uref"); assert_eq!(builder.get_purse_balance(rewards_purse_uref), U512::zero()); - let exec_request_1 = ExecuteRequestBuilder::module_bytes( - *DEFAULT_ADMIN_ACCOUNT_ADDR, - wasm_utils::do_minimum_bytes(), - RuntimeArgs::default(), - ) - .build(); let total_supply_before = builder.total_supply(None, protocol_version); + // TODO: reevaluate this test, considering fee / refund / pricing modes + // let exec_request_1 = ExecuteRequestBuilder::module_bytes( + // *DEFAULT_ADMIN_ACCOUNT_ADDR, + // wasm_utils::do_minimum_bytes(), + // RuntimeArgs::default(), + // ) + // .build(); // let exec_request_1_proposer = exec_request_1.proposer.clone(); // let proposer_account_1 = builder // .get_entity_by_account_hash(exec_request_1_proposer.to_account_hash()) diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 9a8988e3dd..7270bd77eb 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -101,7 +101,7 @@ pub fn execute_finalized_block( let gas_limit = match txn.gas_limit(&system_costs, None) { Ok(gas) => gas, Err(ite) => { - debug!(%ite, "invalid transaction"); + debug!(%ite, "invalid transaction (gas limit)"); artifacts.push_invalid_transaction(txn_hash, txn_header, ite); continue; } @@ -111,7 +111,7 @@ pub fn execute_finalized_block( let cost = match txn.gas_limit(&system_costs, gas_price) { Ok(gas) => gas, Err(ite) => { - debug!(%ite, "invalid transaction"); + debug!(%ite, "invalid transaction (cost)"); artifacts.push_invalid_transaction(txn_hash, txn_header, ite); continue; } @@ -156,7 +156,6 @@ pub fn execute_finalized_block( initiator_addr.clone().into() } }; - let initial_balance_result = scratch_state.balance(BalanceRequest::new( state_root_hash, protocol_version, @@ -164,7 +163,8 @@ pub fn execute_finalized_block( balance_handling, )); - if initial_balance_result.is_sufficient(cost.value()) { + let sufficient_balance = initial_balance_result.is_sufficient(cost.value()); + if sufficient_balance { match txn.category() { TransactionCategory::Mint => { let transfer_result = @@ -194,45 +194,50 @@ pub fn execute_finalized_block( } } TransactionCategory::Auction => { - let auction_method = match AuctionMethod::from_parts( + match AuctionMethod::from_parts( entry_point, &runtime_args, holds_epoch, chainspec, ) { - Ok(auction_method) => auction_method, - Err(_) => { + Ok(auction_method) => { + let bidding_result = scratch_state.bidding(BiddingRequest::new( + native_runtime_config.clone(), + state_root_hash, + block_time, + protocol_version, + txn_hash, + initiator_addr, + authorization_keys, + auction_method, + )); + match artifacts.push_bidding_result( + txn_hash, + txn_header.clone(), + bidding_result, + cost, + ) { + ExecutionArtifactOutcome::RootNotFound => { + return Err(BlockExecutionError::RootNotFound(state_root_hash)) + } + ExecutionArtifactOutcome::Effects(bidding_effects) => { + effects.append(bidding_effects.clone()); + } + } + } + Err(ame) => { + error!( + %txn_hash, + ?ame, + "failed to determine auction method" + ); artifacts.push_auction_method_failure( txn_hash, txn_header.clone(), cost, ); - continue; } }; - let bidding_result = scratch_state.bidding(BiddingRequest::new( - native_runtime_config.clone(), - state_root_hash, - block_time, - protocol_version, - txn_hash, - initiator_addr, - authorization_keys, - auction_method, - )); - match artifacts.push_bidding_result( - txn_hash, - txn_header.clone(), - bidding_result, - cost, - ) { - ExecutionArtifactOutcome::RootNotFound => { - return Err(BlockExecutionError::RootNotFound(state_root_hash)) - } - ExecutionArtifactOutcome::Effects(bidding_effects) => { - effects.append(bidding_effects.clone()); - } - } } TransactionCategory::Standard | TransactionCategory::InstallUpgrade => { let wasm_v1_result = match WasmV1Request::new_session( @@ -269,8 +274,11 @@ pub fn execute_finalized_block( debug!(%txn_hash, "skipping execution due to insufficient balance"); } + let fee_handling = chainspec.core_config.fee_handling; + debug!(%txn_hash, ?fee_handling, ?sufficient_balance, "fee handling"); + // handle payment per the chainspec determined fee setting - match chainspec.core_config.fee_handling { + match fee_handling { FeeHandling::NoFee => { // this is the "fee elimination" model...a BalanceHold for the full cost is placed // on the initiator's purse. diff --git a/node/src/components/storage.rs b/node/src/components/storage.rs index 71e18c1b67..bf8211ee72 100644 --- a/node/src/components/storage.rs +++ b/node/src/components/storage.rs @@ -941,9 +941,12 @@ impl Storage { ref transaction_hash, ref finalized_approvals, responder, - } => responder - .respond(self.store_finalized_approvals(transaction_hash, finalized_approvals)?) - .ignore(), + } => { + info!(txt=?transaction_hash, count=finalized_approvals.len(), "storing finalized approvals {:?}", finalized_approvals); + responder + .respond(self.store_finalized_approvals(transaction_hash, finalized_approvals)?) + .ignore() + } StorageRequest::PutExecutedBlock { block, approvals_hashes, diff --git a/resources/local/chainspec.toml.in b/resources/local/chainspec.toml.in index b005b250a4..3f06f5b9ae 100644 --- a/resources/local/chainspec.toml.in +++ b/resources/local/chainspec.toml.in @@ -89,18 +89,34 @@ allow_unrestricted_transfers = true compute_rewards = true # Defines how refunds of the unused portion of payment amounts are calculated and handled. # -# The only valid value for 'type' is currently 'refund'. This causes excess payment amounts to be sent to either a +# Valid options are: +# 'refund': a ratio of the unspent token is returned to the spender. +# 'burn': unspent token is burned +# This causes excess payment amounts to be sent to either a # pre-defined purse, or back to the sender. The refunded amount is calculated as the given ratio of the payment amount # minus the execution costs. refund_handling = { type = 'refund', refund_ratio = [99, 100] } # Defines how fees are handled. # # Valid options are: +# 'no_fee': fees are eliminated. # 'pay_to_proposer': fees are paid to the block proposer # 'accumulate': fees are accumulated in a special purse and distributed at the end of each era evenly among all # administrator accounts # 'burn': fees are burned -fee_handling = { type = 'pay_to_proposer' } +fee_handling = { type = 'no_fee' } +# Defines how fees are handled. +# +# Valid options are: +# 'classic': senders of transaction self-specify how much they pay. +# 'fixed': costs are fixed, per the cost table +# 'reserved': prepaid transaction (currently not supported) +pricing_handling = { type = 'fixed' } +# Does the network allow pre-payment / reservations for future +# execution? Currently not supported. +# +allow_reservations = false +# # How long does it take for a balance hold to fade away? balance_hold_interval = '24 hours' # List of public keys of administrator accounts. Setting this option makes only on private chains which require diff --git a/resources/production/chainspec.toml b/resources/production/chainspec.toml index 3e15df9bea..5fa207078d 100644 --- a/resources/production/chainspec.toml +++ b/resources/production/chainspec.toml @@ -100,18 +100,32 @@ compute_rewards = true # Defines how refunds of the unused portion of payment amounts are calculated and handled. # # Valid options are: -# 'refund': this causes excess payment amounts to be sent to either a pre-defined purse, or back to the sender. -# the refunded amount is calculated as the given ratio of the payment amount minus the execution costs. -# 'burn': similar to what refund does; except the refund amount is burned. +# 'refund': a ratio of the unspent token is returned to the spender. +# 'burn': unspent token is burned +# This causes excess payment amounts to be sent to either a +# pre-defined purse, or back to the sender. The refunded amount is calculated as the given ratio of the payment amount +# minus the execution costs. refund_handling = { type = 'refund', refund_ratio = [99, 100] } # Defines how fees are handled. # # Valid options are: +# 'no_fee': fees are eliminated. # 'pay_to_proposer': fees are paid to the block proposer # 'accumulate': fees are accumulated in a special purse and distributed at the end of each era evenly among all # administrator accounts # 'burn': fees are burned -fee_handling = { type = 'pay_to_proposer' } +fee_handling = { type = 'no_fee' } +# Defines how fees are handled. +# +# Valid options are: +# 'classic': senders of transaction self-specify how much they pay. +# 'fixed': costs are fixed, per the cost table +# 'reserved': prepaid transaction (currently not supported) +pricing_handling = { type = 'fixed' } +# Does the network allow pre-payment / reservations for future +# execution? Currently not supported. +# +allow_reservations = false # How long does it take for a balance hold to fade away? balance_hold_interval = '24 hours' # List of public keys of administrator accounts. Setting this option makes only on private chains which require diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index 1b5c586772..79f2624a82 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -1636,7 +1636,7 @@ "minimum": 0.0 }, "gas_price": { - "description": "User-specified gas_price tolerance (minimum 1).", + "description": "User-specified gas_price (minimum 1).", "type": "integer", "format": "uint64", "minimum": 0.0 diff --git a/types/src/chainspec.rs b/types/src/chainspec.rs index e22c570f04..65212c0315 100644 --- a/types/src/chainspec.rs +++ b/types/src/chainspec.rs @@ -11,6 +11,7 @@ mod global_state_update; mod highway_config; mod network_config; mod next_upgrade; +mod pricing_handling; mod protocol_config; mod refund_handling; mod transaction_config; @@ -55,6 +56,7 @@ pub use global_state_update::{GlobalStateUpdate, GlobalStateUpdateConfig, Global pub use highway_config::HighwayConfig; pub use network_config::NetworkConfig; pub use next_upgrade::NextUpgrade; +pub use pricing_handling::PricingHandling; pub use protocol_config::ProtocolConfig; pub use refund_handling::RefundHandling; pub use transaction_config::{DeployConfig, TransactionConfig, TransactionV1Config}; diff --git a/types/src/chainspec/core_config.rs b/types/src/chainspec/core_config.rs index 32a29e33a3..c46b0f9c95 100644 --- a/types/src/chainspec/core_config.rs +++ b/types/src/chainspec/core_config.rs @@ -20,7 +20,9 @@ use crate::{ ProtocolVersion, PublicKey, TimeDiff, }; -use super::{fee_handling::FeeHandling, refund_handling::RefundHandling}; +use super::{ + fee_handling::FeeHandling, pricing_handling::PricingHandling, refund_handling::RefundHandling, +}; /// Default value for maximum associated keys configuration option. pub const DEFAULT_MAX_ASSOCIATED_KEYS: u32 = 100; @@ -33,6 +35,8 @@ pub const DEFAULT_REFUND_HANDLING: RefundHandling = RefundHandling::Refund { refund_ratio: Ratio::new_raw(99, 100), }; +pub const DEFAULT_PRICING_HANDLING: PricingHandling = PricingHandling::Fixed; + /// Default fee handling. pub const DEFAULT_FEE_HANDLING: FeeHandling = FeeHandling::PayToProposer; @@ -136,6 +140,10 @@ pub struct CoreConfig { pub refund_handling: RefundHandling, /// Fee handling. pub fee_handling: FeeHandling, + /// Pricing handling. + pub pricing_handling: PricingHandling, + /// Allow reservations. + pub allow_reservations: bool, /// How long does it take for a balance hold to fade away? pub balance_hold_interval: TimeDiff, /// Administrative accounts are a valid option for a private chain only. @@ -209,10 +217,18 @@ impl CoreConfig { RefundHandling::Refund { refund_ratio } }; + let pricing_handling = if rng.gen() { + PricingHandling::Classic + } else { + PricingHandling::Fixed + }; + + let allow_reservations = false; + let fee_handling = if rng.gen() { FeeHandling::PayToProposer } else { - FeeHandling::Accumulate + FeeHandling::NoFee }; let balance_hold_interval = TimeDiff::from_seconds(rng.gen_range(600..604_800)); @@ -246,6 +262,8 @@ impl CoreConfig { allow_unrestricted_transfers, compute_rewards, refund_handling, + pricing_handling, + allow_reservations, fee_handling, balance_hold_interval, } @@ -284,7 +302,9 @@ impl Default for CoreConfig { compute_rewards: true, administrators: Default::default(), refund_handling: DEFAULT_REFUND_HANDLING, + pricing_handling: DEFAULT_PRICING_HANDLING, fee_handling: DEFAULT_FEE_HANDLING, + allow_reservations: false, balance_hold_interval: DEFAULT_BALANCE_HOLD_INTERVAL, } } @@ -324,6 +344,7 @@ impl ToBytes for CoreConfig { buffer.extend(self.compute_rewards.to_bytes()?); buffer.extend(self.administrators.to_bytes()?); buffer.extend(self.refund_handling.to_bytes()?); + buffer.extend(self.pricing_handling.to_bytes()?); buffer.extend(self.fee_handling.to_bytes()?); buffer.extend(self.balance_hold_interval.to_bytes()?); Ok(buffer) @@ -360,7 +381,9 @@ impl ToBytes for CoreConfig { + self.compute_rewards.serialized_length() + self.administrators.serialized_length() + self.refund_handling.serialized_length() + + self.pricing_handling.serialized_length() + self.fee_handling.serialized_length() + + self.allow_reservations.serialized_length() + self.balance_hold_interval.serialized_length() } } @@ -396,7 +419,9 @@ impl FromBytes for CoreConfig { let (compute_rewards, remainder) = bool::from_bytes(remainder)?; let (administrative_accounts, remainder) = FromBytes::from_bytes(remainder)?; let (refund_handling, remainder) = FromBytes::from_bytes(remainder)?; + let (pricing_handling, remainder) = FromBytes::from_bytes(remainder)?; let (fee_handling, remainder) = FromBytes::from_bytes(remainder)?; + let (allow_reservations, remainder) = FromBytes::from_bytes(remainder)?; let (balance_hold_interval, remainder) = TimeDiff::from_bytes(remainder)?; let config = CoreConfig { era_duration, @@ -427,7 +452,9 @@ impl FromBytes for CoreConfig { compute_rewards, administrators: administrative_accounts, refund_handling, + pricing_handling, fee_handling, + allow_reservations, balance_hold_interval, }; Ok((config, remainder)) diff --git a/types/src/chainspec/pricing_handling.rs b/types/src/chainspec/pricing_handling.rs new file mode 100644 index 0000000000..4e42b60ae5 --- /dev/null +++ b/types/src/chainspec/pricing_handling.rs @@ -0,0 +1,81 @@ +use crate::{ + bytesrepr, + bytesrepr::{FromBytes, ToBytes}, +}; +#[cfg(feature = "datasize")] +use datasize::DataSize; +use serde::{Deserialize, Serialize}; + +const PRICING_HANDLING_CLASSIC_TAG: u8 = 0; +const PRICING_HANDLING_FIXED_TAG: u8 = 1; + +const PRICING_HANDLING_TAG_LENGTH: u8 = 1; + +/// Defines what pricing mode a network allows. Correlates to the PricingMode of a [`Transaction`]. +/// Nodes will not accept transactions whose pricing mode does not match. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(tag = "type", rename_all = "snake_case")] +#[cfg_attr(feature = "datasize", derive(DataSize))] +pub enum PricingHandling { + /// The transaction sender self-specifies how much token they pay, which becomes their gas + /// limit. + Classic, + /// The costs are fixed, per the cost tables. + Fixed, +} + +impl ToBytes for PricingHandling { + fn to_bytes(&self) -> Result, bytesrepr::Error> { + let mut buffer = bytesrepr::allocate_buffer(self)?; + + match self { + PricingHandling::Classic => { + buffer.push(PRICING_HANDLING_CLASSIC_TAG); + } + PricingHandling::Fixed => { + buffer.push(PRICING_HANDLING_FIXED_TAG); + } + } + + Ok(buffer) + } + + fn serialized_length(&self) -> usize { + PRICING_HANDLING_TAG_LENGTH as usize + } +} + +impl FromBytes for PricingHandling { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (tag, rem) = u8::from_bytes(bytes)?; + match tag { + PRICING_HANDLING_CLASSIC_TAG => Ok((PricingHandling::Classic, rem)), + PRICING_HANDLING_FIXED_TAG => Ok((PricingHandling::Fixed, rem)), + _ => Err(bytesrepr::Error::Formatting), + } + } +} + +impl Default for PricingHandling { + fn default() -> Self { + // in 2.0 the default pricing handling is Fixed + PricingHandling::Fixed + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn bytesrepr_roundtrip_for_classic() { + let handling = PricingHandling::Classic; + bytesrepr::test_serialization_roundtrip(&handling); + } + + #[test] + fn bytesrepr_roundtrip_for_fixed() { + let handling = PricingHandling::Fixed; + bytesrepr::test_serialization_roundtrip(&handling); + } +} From dcdbebd96fd99df4a2d916118f56ba63fefb5719 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Thu, 21 Mar 2024 16:29:39 -0700 Subject: [PATCH 28/70] fixed node tests...ee tests still need attn --- execution_engine/src/engine_state/mod.rs | 2 - node/src/components/contract_runtime.rs | 4 +- .../components/contract_runtime/operations.rs | 165 ++++---- node/src/components/contract_runtime/types.rs | 370 +++++++----------- node/src/reactor/main_reactor/tests.rs | 3 +- storage/src/global_state.rs | 2 +- types/src/gas.rs | 5 + 7 files changed, 223 insertions(+), 328 deletions(-) diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index 72b05b6d0d..7a78e3a33a 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -132,7 +132,6 @@ impl ExecutionEngineV1 { Ok(execution_kind) => execution_kind, Err(ese) => return WasmV1Result::precondition_failure(gas_limit, ese), }; - let access_rights = entity.extract_access_rights(entity_hash, &named_keys); let execution_result = Executor::new(self.config().clone()).exec( execution_kind, @@ -154,7 +153,6 @@ impl ExecutionEngineV1 { self.config.max_runtime_call_stack_height() as usize, ), ); - WasmV1Result::from_execution_result(gas_limit, execution_result) } } diff --git a/node/src/components/contract_runtime.rs b/node/src/components/contract_runtime.rs index 0ac3862761..7bb1a642f7 100644 --- a/node/src/components/contract_runtime.rs +++ b/node/src/components/contract_runtime.rs @@ -69,8 +69,8 @@ pub(crate) use operations::compute_execution_results_checksum; pub use operations::execute_finalized_block; use operations::speculatively_execute; pub(crate) use types::{ - BlockAndExecutionArtifacts, ExecutionArtifact, ExecutionArtifacts, ExecutionPreState, - SpeculativeExecutionResult, StepOutcome, + BlockAndExecutionArtifacts, ExecutionArtifact, ExecutionPreState, SpeculativeExecutionResult, + StepOutcome, }; use utils::{exec_or_requeue, run_intensive_task}; diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 7270bd77eb..f2d0111344 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -29,11 +29,12 @@ use casper_types::{ }; use super::{ - types::{ExecutionArtifactOutcome, SpeculativeExecutionResult, StepOutcome}, + types::{SpeculativeExecutionResult, StepOutcome}, utils::{self, calculate_prune_eras}, - BlockAndExecutionArtifacts, BlockExecutionError, ExecutionArtifacts, ExecutionPreState, - Metrics, APPROVALS_CHECKSUM_NAME, EXECUTION_RESULTS_CHECKSUM_NAME, + BlockAndExecutionArtifacts, BlockExecutionError, ExecutionPreState, Metrics, + APPROVALS_CHECKSUM_NAME, EXECUTION_RESULTS_CHECKSUM_NAME, }; +use crate::contract_runtime::types::ExecutionArtifactBuilder; use crate::{ components::fetcher::FetchItem, types::{self, Chunkable, ExecutableBlock, InternalEraReport}, @@ -67,7 +68,7 @@ pub fn execute_finalized_block( let parent_seed = execution_pre_state.parent_seed(); let mut state_root_hash = pre_state_root_hash; - let mut artifacts = ExecutionArtifacts::with_capacity(executable_block.transactions.len()); + let mut artifacts = Vec::with_capacity(executable_block.transactions.len()); let block_time = BlockTime::new(executable_block.timestamp.millis()); let balance_handling = BalanceHandling::Available { block_time: executable_block.timestamp.millis(), @@ -88,37 +89,41 @@ pub fn execute_finalized_block( let insufficient_balance_handling = InsufficientBalanceHandling::HoldRemaining; let gas_price = Some(1); // < --TODO: this is where Karan's calculated gas price needs to be used - for txn in executable_block.transactions { - let mut effects = Effects::new(); - let initiator_addr = txn.initiator_addr(); - let txn_hash = txn.hash(); - let txn_header = txn.header(); - let runtime_args = txn.session_args().clone(); - let entry_point = txn.entry_point(); - let authorization_keys = txn.authorization_keys(); + for transaction in executable_block.transactions { + let mut artifact_builder = ExecutionArtifactBuilder::new(&transaction); + + let initiator_addr = transaction.initiator_addr(); + let transaction_hash = transaction.hash(); + let runtime_args = transaction.session_args().clone(); + let entry_point = transaction.entry_point(); + let authorization_keys = transaction.authorization_keys(); // NOTE: this is the allowed computation limit (gas limit) - let gas_limit = match txn.gas_limit(&system_costs, None) { + let gas_limit = match transaction.gas_limit(&system_costs, None) { Ok(gas) => gas, Err(ite) => { debug!(%ite, "invalid transaction (gas limit)"); - artifacts.push_invalid_transaction(txn_hash, txn_header, ite); + artifact_builder.with_invalid_transaction(&ite); + artifacts.push(artifact_builder.build()); continue; } }; // NOTE: this is the actual adjusted cost (gas limit * gas price) - let cost = match txn.gas_limit(&system_costs, gas_price) { + let cost = match transaction.gas_limit(&system_costs, gas_price) { Ok(gas) => gas, Err(ite) => { debug!(%ite, "invalid transaction (cost)"); - artifacts.push_invalid_transaction(txn_hash, txn_header, ite); + artifact_builder.with_invalid_transaction(&ite); + artifacts.push(artifact_builder.build()); continue; } }; + artifact_builder.with_added_gas(cost); + let balance_identifier = { - if !txn.is_standard_payment() { + if !transaction.is_standard_payment() { // execute custom payment logic, which is expected to // interact with the handle payment contract to deposit // sufficient token to cover the cost @@ -135,22 +140,18 @@ pub fn execute_finalized_block( state_root_hash, block_time, custom_payment_gas_limit, - &txn, + &transaction, ) { Ok(pay_request) => execution_engine_v1.execute(&scratch_state, pay_request), Err(error) => { WasmV1Result::invalid_executable_item(custom_payment_gas_limit, error) } }; - match artifacts.push_wasm_v1_result(txn_hash, txn_header.clone(), pay_result) { - ExecutionArtifactOutcome::RootNotFound => { - return Err(BlockExecutionError::RootNotFound(state_root_hash)) - } - ExecutionArtifactOutcome::Effects(custom_pay_effects) => { - effects.append(custom_pay_effects); - } + artifact_builder.with_wasm_v1_result(pay_result); + if artifact_builder.root_not_found() { + artifacts.push(artifact_builder.build()); + return Err(BlockExecutionError::RootNotFound(state_root_hash)); } - // balance request should check the handle payment purse, not initiator's purse BalanceIdentifier::Payment } else { initiator_addr.clone().into() @@ -165,7 +166,8 @@ pub fn execute_finalized_block( let sufficient_balance = initial_balance_result.is_sufficient(cost.value()); if sufficient_balance { - match txn.category() { + let category = transaction.category(); + match category { TransactionCategory::Mint => { let transfer_result = scratch_state.transfer(TransferRequest::with_runtime_args( @@ -173,24 +175,16 @@ pub fn execute_finalized_block( state_root_hash, holds_epoch, protocol_version, - txn_hash, + transaction_hash, initiator_addr, authorization_keys, runtime_args, cost, )); - match artifacts.push_transfer_result( - txn_hash, - txn_header.clone(), - transfer_result, - cost, - ) { - ExecutionArtifactOutcome::RootNotFound => { - return Err(BlockExecutionError::RootNotFound(state_root_hash)) - } - ExecutionArtifactOutcome::Effects(transfer_effects) => { - effects.append(transfer_effects.clone()); - } + artifact_builder.with_transfer_result(transfer_result); + if artifact_builder.root_not_found() { + artifacts.push(artifact_builder.build()); + return Err(BlockExecutionError::RootNotFound(state_root_hash)); } } TransactionCategory::Auction => { @@ -206,77 +200,58 @@ pub fn execute_finalized_block( state_root_hash, block_time, protocol_version, - txn_hash, + transaction_hash, initiator_addr, authorization_keys, auction_method, )); - match artifacts.push_bidding_result( - txn_hash, - txn_header.clone(), - bidding_result, - cost, - ) { - ExecutionArtifactOutcome::RootNotFound => { - return Err(BlockExecutionError::RootNotFound(state_root_hash)) - } - ExecutionArtifactOutcome::Effects(bidding_effects) => { - effects.append(bidding_effects.clone()); - } + artifact_builder.with_bidding_result(bidding_result); + if artifact_builder.root_not_found() { + artifacts.push(artifact_builder.build()); + return Err(BlockExecutionError::RootNotFound(state_root_hash)); } } Err(ame) => { error!( - %txn_hash, + %transaction_hash, ?ame, "failed to determine auction method" ); - artifacts.push_auction_method_failure( - txn_hash, - txn_header.clone(), - cost, - ); + artifact_builder.with_auction_method_error(&ame); } }; } TransactionCategory::Standard | TransactionCategory::InstallUpgrade => { - let wasm_v1_result = match WasmV1Request::new_session( + match WasmV1Request::new_session( state_root_hash, block_time, gas_limit, - &txn, + &transaction, ) { Ok(wasm_v1_request) => { - execution_engine_v1.execute(&scratch_state, wasm_v1_request) - } - Err(error) => WasmV1Result::invalid_executable_item(gas_limit, error), - }; - trace!( - %txn_hash, - ?wasm_v1_result, - "transaction execution result" - ); - match artifacts.push_wasm_v1_result( - txn_hash, - txn_header.clone(), - wasm_v1_result, - ) { - ExecutionArtifactOutcome::RootNotFound => { - return Err(BlockExecutionError::RootNotFound(state_root_hash)) + trace!(%transaction_hash, ?category, ?wasm_v1_request, "able to get wasm v1 request"); + let wasm_v1_result = + execution_engine_v1.execute(&scratch_state, wasm_v1_request); + trace!(%transaction_hash, ?category, ?wasm_v1_result, "able to get wasm v1 result"); + artifact_builder.with_wasm_v1_result(wasm_v1_result); + if artifact_builder.root_not_found() { + artifacts.push(artifact_builder.build()); + return Err(BlockExecutionError::RootNotFound(state_root_hash)); + } } - ExecutionArtifactOutcome::Effects(wasm_effects) => { - effects.append(wasm_effects.clone()); + Err(ire) => { + debug!(%transaction_hash, ?category, ?ire, "unable to get wasm v1 request"); + artifact_builder.with_invalid_wasm_v1_request(&ire); } - } + }; } } } else { - debug!(%txn_hash, "skipping execution due to insufficient balance"); + debug!(%transaction_hash, "skipping execution due to insufficient balance"); } let fee_handling = chainspec.core_config.fee_handling; - debug!(%txn_hash, ?fee_handling, ?sufficient_balance, "fee handling"); - + trace!(%transaction_hash, ?fee_handling, ?sufficient_balance, "fee handling"); // handle payment per the chainspec determined fee setting match fee_handling { FeeHandling::NoFee => { @@ -292,13 +267,10 @@ pub fn execute_finalized_block( chainspec.core_config.balance_hold_interval, insufficient_balance_handling, )); - match artifacts.push_hold_result(txn_hash, txn_header.clone(), hold_result) { - ExecutionArtifactOutcome::RootNotFound => { - return Err(BlockExecutionError::RootNotFound(state_root_hash)) - } - ExecutionArtifactOutcome::Effects(hold_effects) => { - effects.append(hold_effects.clone()) - } + artifact_builder.with_balance_hold_result(&hold_result); + if artifact_builder.root_not_found() { + artifacts.push(artifact_builder.build()); + return Err(BlockExecutionError::RootNotFound(state_root_hash)); } } FeeHandling::PayToProposer => { @@ -324,13 +296,13 @@ pub fn execute_finalized_block( } } - // commit effects - scratch_state.commit(state_root_hash, effects)?; + scratch_state.commit(state_root_hash, artifact_builder.effects())?; if let Some(metrics) = metrics.as_ref() { metrics .commit_effects .observe(start.elapsed().as_secs_f64()); } + artifacts.push(artifact_builder.build()); } // calculate and store checksums for approvals and execution effects across the transactions in @@ -340,8 +312,9 @@ pub fn execute_finalized_block( let txns_approvals_hashes = { let approvals_checksum = types::compute_approvals_checksum(txn_ids.clone()) .map_err(BlockExecutionError::FailedToComputeApprovalsChecksum)?; - let execution_results_checksum = - compute_execution_results_checksum(artifacts.execution_results())?; + let execution_results_checksum = compute_execution_results_checksum( + artifacts.iter().map(|artifact| &artifact.execution_result), + )?; let mut checksum_registry = ChecksumRegistry::new(); checksum_registry.insert(APPROVALS_CHECKSUM_NAME, approvals_checksum); checksum_registry.insert(EXECUTION_RESULTS_CHECKSUM_NAME, execution_results_checksum); @@ -632,12 +605,10 @@ pub fn execute_finalized_block( proof_of_checksum_registry, )); - let execution_artifacts = artifacts.take(); - Ok(BlockAndExecutionArtifacts { block, approvals_hashes, - execution_artifacts, + execution_artifacts: artifacts, step_outcome, }) } diff --git a/node/src/components/contract_runtime/types.rs b/node/src/components/contract_runtime/types.rs index fe4bc1bdc8..ea43c05436 100644 --- a/node/src/components/contract_runtime/types.rs +++ b/node/src/components/contract_runtime/types.rs @@ -2,9 +2,11 @@ use std::{collections::BTreeMap, sync::Arc}; use datasize::DataSize; use serde::Serialize; -use tracing::{debug, trace}; -use casper_execution_engine::engine_state::WasmV1Result; +use casper_execution_engine::engine_state::{ + Error, InvalidRequest as InvalidWasmV1Request, WasmV1Result, +}; +use casper_storage::data_access_layer::bidding::AuctionMethodError; use casper_storage::{ block_store::types::ApprovalsHashes, data_access_layer::{BalanceHoldResult, BiddingResult, EraValidatorsRequest, TransferResult}, @@ -14,7 +16,7 @@ use casper_types::{ execution::{Effects, ExecutionResult, ExecutionResultV2}, BlockHash, BlockHeaderV2, BlockV2, DeployHash, DeployHeader, Digest, EraId, Gas, InvalidDeploy, InvalidTransaction, InvalidTransactionV1, ProtocolVersion, PublicKey, Transaction, - TransactionHash, TransactionHeader, TransactionV1Hash, TransactionV1Header, U512, + TransactionHash, TransactionHeader, TransactionV1Hash, TransactionV1Header, TransferAddr, U512, }; /// Request for validator weights for a specific era. @@ -57,260 +59,178 @@ impl From for EraValidatorsRequest { } } -/// Effects from running step and the next era validators that are gathered when an era ends. -#[derive(Clone, Debug, DataSize)] -pub(crate) struct StepOutcome { - /// Validator sets for all upcoming eras that have already been determined. - pub(crate) upcoming_era_validators: BTreeMap>, - /// An [`Effects`] created by an era ending. - pub(crate) step_effects: Effects, +#[derive(Clone, Debug)] +pub(crate) struct ExecutionArtifactBuilder { + effects: Effects, + hash: TransactionHash, + header: TransactionHeader, + error_message: Option, + messages: Messages, + transfers: Vec, + gas: Gas, + root_not_found: bool, } -pub(crate) struct ExecutionArtifacts { - artifacts: Vec, -} +impl ExecutionArtifactBuilder { + pub fn new(transaction: &Transaction) -> Self { + let effects = Effects::new(); + let hash = transaction.hash(); + let header = transaction.header().clone(); + ExecutionArtifactBuilder { + effects, + hash, + header, + error_message: None, + transfers: vec![], + messages: Default::default(), + gas: Gas::zero(), + root_not_found: false, + } + } -pub(crate) enum ExecutionArtifactOutcome { - RootNotFound, - Effects(Effects), -} + pub fn effects(&self) -> Effects { + self.effects.clone() + } -impl ExecutionArtifacts { - pub fn with_capacity(capacity: usize) -> Self { - let artifacts = Vec::with_capacity(capacity); - ExecutionArtifacts { artifacts } + pub(crate) fn root_not_found(&self) -> bool { + self.root_not_found } - pub fn push_wasm_v1_result( - &mut self, - transaction_hash: TransactionHash, - transaction_header: TransactionHeader, - wasm_v1_result: WasmV1Result, - ) -> ExecutionArtifactOutcome { - trace!(?transaction_hash, ?wasm_v1_result, "native transfer result"); - let effects = wasm_v1_result.effects().clone(); - let result = { - if let Some(error) = wasm_v1_result.error() { - if let casper_execution_engine::engine_state::Error::RootNotFound(_) = error { - return ExecutionArtifactOutcome::RootNotFound; - } - ExecutionResultV2::Failure { - effects: effects.clone(), - transfers: wasm_v1_result.transfers().clone(), - gas: wasm_v1_result.consumed(), - error_message: format!("{:?}", error), - } - } else { - ExecutionResultV2::Success { - effects: effects.clone(), - transfers: wasm_v1_result.transfers().clone(), - gas: wasm_v1_result.consumed(), - } - } - }; - self.artifacts.push(ExecutionArtifact::new( - transaction_hash, - transaction_header, - ExecutionResult::V2(result), - wasm_v1_result.messages().clone(), - )); + pub fn with_appended_transfers(&mut self, transfers: &mut Vec) -> &mut Self { + self.transfers.append(transfers); + self + } - ExecutionArtifactOutcome::Effects(effects) + pub fn with_appended_effects(&mut self, effects: Effects) -> &mut Self { + self.effects.append(effects); + self } - pub fn push_transfer_result( - &mut self, - transaction_hash: TransactionHash, - transaction_header: TransactionHeader, - transfer_result: TransferResult, - gas: Gas, - ) -> ExecutionArtifactOutcome { - trace!( - ?transaction_hash, - ?transfer_result, - "native transfer result" - ); - match transfer_result { - TransferResult::RootNotFound => ExecutionArtifactOutcome::RootNotFound, - TransferResult::Failure(transfer_error) => { - self.push_failure( - transaction_hash, - transaction_header, - format!("{:?}", transfer_error), - ); - debug!(%transfer_error); - ExecutionArtifactOutcome::Effects(Effects::new()) - } - TransferResult::Success { - effects: transfer_effects, - transfers, - } => { - self.artifacts.push(ExecutionArtifact::new( - transaction_hash, - transaction_header, - ExecutionResult::V2(ExecutionResultV2::Success { - effects: transfer_effects.clone(), - gas, - transfers, - }), - Messages::default(), - )); - ExecutionArtifactOutcome::Effects(transfer_effects) - } - } + pub fn with_appended_messages(&mut self, messages: &mut Messages) -> &mut Self { + self.messages.append(messages); + self } - pub fn push_bidding_result( - &mut self, - transaction_hash: TransactionHash, - transaction_header: TransactionHeader, - bidding_result: BiddingResult, - gas: Gas, - ) -> ExecutionArtifactOutcome { - trace!(?transaction_hash, ?bidding_result, "bidding result"); - match bidding_result { - BiddingResult::RootNotFound => ExecutionArtifactOutcome::RootNotFound, - BiddingResult::Failure(tce) => { - self.artifacts.push(ExecutionArtifact::new( - transaction_hash, - transaction_header, - ExecutionResult::V2(ExecutionResultV2::Failure { - effects: Effects::new(), - gas, - transfers: vec![], - error_message: format!("{:?}", tce), - }), - Messages::default(), - )); - debug!(%tce); - ExecutionArtifactOutcome::Effects(Effects::new()) - } - BiddingResult::Success { - effects: bidding_effects, - .. - } => { - self.artifacts.push(ExecutionArtifact::new( - transaction_hash, - transaction_header, - ExecutionResult::V2(ExecutionResultV2::Success { - effects: bidding_effects.clone(), - gas, - transfers: vec![], - }), - Messages::default(), - )); - ExecutionArtifactOutcome::Effects(bidding_effects) - } + pub fn with_wasm_v1_result(&mut self, wasm_v1_result: WasmV1Result) -> &mut Self { + if let Some(Error::RootNotFound(_)) = wasm_v1_result.error() { + self.root_not_found = true; } + if let (None, Some(err)) = (&self.error_message, wasm_v1_result.error()) { + self.error_message = Some(format!("{}", err)); + } + self.with_appended_messages(&mut wasm_v1_result.messages().clone()) + .with_appended_transfers(&mut wasm_v1_result.transfers().clone()) + .with_appended_effects(wasm_v1_result.effects().clone()) } - pub fn push_hold_result( - &mut self, - transaction_hash: TransactionHash, - transaction_header: TransactionHeader, - hold_result: BalanceHoldResult, - ) -> ExecutionArtifactOutcome { - trace!(?transaction_hash, ?hold_result, "balance hold result"); - if hold_result.is_root_not_found() { - return ExecutionArtifactOutcome::RootNotFound; + pub fn with_balance_hold_result(&mut self, hold_result: &BalanceHoldResult) -> &mut Self { + if let BalanceHoldResult::RootNotFound = hold_result { + self.root_not_found = true; } - let hold_cost = Gas::zero(); // we don't charge for the hold itself. - let hold_effects = hold_result.effects(); - if !hold_result.is_fully_covered() { - let error_message = hold_result.error_message(); - self.artifacts.push(ExecutionArtifact::new( - transaction_hash, - transaction_header, - ExecutionResult::V2(ExecutionResultV2::Failure { - effects: hold_effects.clone(), - transfers: vec![], - gas: hold_cost, - error_message: error_message.clone(), - }), - Messages::default(), - )); - debug!(%error_message); - } else { - self.artifacts.push(ExecutionArtifact::new( - transaction_hash, - transaction_header, - ExecutionResult::V2(ExecutionResultV2::Success { - effects: hold_effects.clone(), - transfers: vec![], - gas: hold_cost, - }), - Messages::default(), - )); + if let (None, BalanceHoldResult::Failure(err)) = (&self.error_message, hold_result) { + self.error_message = Some(format!("{}", err)); } - ExecutionArtifactOutcome::Effects(hold_effects) + self.with_appended_effects(hold_result.effects().clone()) } - pub fn push_invalid_transaction( + pub fn with_added_gas(&mut self, gas: Gas) -> &mut Self { + self.gas = self.gas.saturating_add(gas); + self + } + + pub fn with_invalid_transaction( &mut self, - transaction_hash: TransactionHash, - transaction_header: TransactionHeader, - invalid_transaction: InvalidTransaction, - ) { - self.push_failure( - transaction_hash, - transaction_header, - invalid_transaction.to_string(), - ); + invalid_transaction: &InvalidTransaction, + ) -> &mut Self { + if self.error_message.is_none() { + self.error_message = Some(format!("{}", invalid_transaction)); + } + self } - pub fn push_auction_method_failure( + pub fn with_invalid_wasm_v1_request( &mut self, - transaction_hash: TransactionHash, - transaction_header: TransactionHeader, - gas: Gas, - ) { - let msg = "failed to resolve auction method".to_string(); - let artifact = ExecutionArtifact::new( - transaction_hash, - transaction_header, - ExecutionResult::V2(ExecutionResultV2::Failure { - effects: Effects::new(), - transfers: vec![], - error_message: msg.clone(), - gas, - }), - Messages::default(), - ); - debug!(%transaction_hash, "{:?}", msg); - self.artifacts.push(artifact); + invalid_request: &InvalidWasmV1Request, + ) -> &mut Self { + if self.error_message.is_none() { + self.error_message = Some(format!("{}", invalid_request)); + } + self } - fn push_failure( + pub fn with_auction_method_error( &mut self, - transaction_hash: TransactionHash, - transaction_header: TransactionHeader, - error_message: String, - ) { - let execution_artifact = ExecutionArtifact::new( - transaction_hash, - transaction_header, - ExecutionResult::V2(ExecutionResultV2::Failure { - effects: Effects::new(), - gas: Gas::zero(), - transfers: vec![], - error_message, - }), - Messages::default(), - ); - self.artifacts.push(execution_artifact); + auction_method_error: &AuctionMethodError, + ) -> &mut Self { + if self.error_message.is_none() { + self.error_message = Some(format!("{}", auction_method_error)); + } + self } - pub fn execution_results(&self) -> impl Iterator + Clone { - self.artifacts - .iter() - .map(|artifact| &artifact.execution_result) + pub fn with_transfer_result(&mut self, transfer_result: TransferResult) -> &mut Self { + if let TransferResult::RootNotFound = transfer_result { + self.root_not_found = true; + return self; + } + if let (None, TransferResult::Failure(err)) = (&self.error_message, &transfer_result) { + self.error_message = Some(format!("{}", err)); + return self; + } + if let TransferResult::Success { transfers, effects } = transfer_result { + return self + .with_appended_transfers(&mut transfers.clone()) + .with_appended_effects(effects.clone()); + } + self } - pub fn take(self) -> Vec { - self.artifacts + pub fn with_bidding_result(&mut self, bidding_result: BiddingResult) -> &mut Self { + if let BiddingResult::RootNotFound = bidding_result { + self.root_not_found = true; + return self; + } + if let (None, BiddingResult::Failure(err)) = (&self.error_message, &bidding_result) { + self.error_message = Some(format!("{}", err)); + return self; + } + if let BiddingResult::Success { effects, .. } = bidding_result { + return self.with_appended_effects(effects.clone()); + } + self + } + + pub(crate) fn build(self) -> ExecutionArtifact { + let effects = self.effects; + let transfers = self.transfers; + let gas = self.gas; + let result = match self.error_message { + Some(error_message) => ExecutionResultV2::Failure { + effects, + transfers, + gas, + error_message, + }, + None => ExecutionResultV2::Success { + effects, + transfers, + gas, + }, + }; + let execution_result = ExecutionResult::V2(result); + ExecutionArtifact::new(self.hash, self.header, execution_result, self.messages) } } +/// Effects from running step and the next era validators that are gathered when an era ends. +#[derive(Clone, Debug, DataSize)] +pub(crate) struct StepOutcome { + /// Validator sets for all upcoming eras that have already been determined. + pub(crate) upcoming_era_validators: BTreeMap>, + /// An [`Effects`] created by an era ending. + pub(crate) step_effects: Effects, +} + #[derive(Clone, Debug, DataSize, PartialEq, Eq, Serialize)] pub(crate) struct ExecutionArtifact { pub(crate) transaction_hash: TransactionHash, diff --git a/node/src/reactor/main_reactor/tests.rs b/node/src/reactor/main_reactor/tests.rs index c1bafe8988..cd7b29ba10 100644 --- a/node/src/reactor/main_reactor/tests.rs +++ b/node/src/reactor/main_reactor/tests.rs @@ -1677,7 +1677,7 @@ async fn run_redelegate_bid_network() { // Inject the transaction and run the network until executed. fixture.inject_transaction(txn).await; fixture - .run_until_executed_transaction(&txn_hash, TEN_SECS) + .run_until_executed_transaction(&txn_hash, ONE_MIN) .await; // Ensure execution succeeded and that there is a Write transform for the bid's key. @@ -1685,6 +1685,7 @@ async fn run_redelegate_bid_network() { &bob_public_key, Some(&alice_public_key), )); + fixture .successful_execution_transforms(&txn_hash) .iter() diff --git a/storage/src/global_state.rs b/storage/src/global_state.rs index 0443072bab..7e1bd84c7a 100644 --- a/storage/src/global_state.rs +++ b/storage/src/global_state.rs @@ -17,4 +17,4 @@ pub(crate) const DEFAULT_MAX_DB_SIZE: usize = 52_428_800; // 50 MiB pub(crate) const DEFAULT_MAX_READERS: u32 = 512; -pub(crate) const DEFAULT_MAX_QUERY_DEPTH: u64 = 6; +pub(crate) const DEFAULT_MAX_QUERY_DEPTH: u64 = 5; diff --git a/types/src/gas.rs b/types/src/gas.rs index 16e386f800..10717aa0ee 100644 --- a/types/src/gas.rs +++ b/types/src/gas.rs @@ -58,6 +58,11 @@ impl Gas { self.0.checked_add(rhs.value()).map(Self::new) } + /// Saturating integer addition. Computes `self + rhs`, returning max if overflow occurred. + pub fn saturating_add(self, rhs: Self) -> Self { + Gas(self.0.saturating_add(rhs.value())) + } + /// Checked integer subtraction. Computes `self - rhs`, returning `None` if overflow occurred. pub fn checked_sub(&self, rhs: Self) -> Option { self.0.checked_sub(rhs.value()).map(Self::new) From 38d059ed39a92cc5a0905031c730345e7457ea8c Mon Sep 17 00:00:00 2001 From: Alexandru Sardan Date: Thu, 21 Mar 2024 20:06:04 +0000 Subject: [PATCH 29/70] Remove transfer records and transaction info records from GS Transfer records and the transaction information that used to be stored in global state is now stored in the execution results in block storage. Signed-off-by: Alexandru Sardan --- .../src/speculative_execution_result.rs | 11 +- .../src/engine_state/execution_result.rs | 58 +-- execution_engine/src/engine_state/wasm_v1.rs | 6 +- execution_engine/src/runtime/mint_internal.rs | 20 +- execution_engine/src/runtime/mod.rs | 49 +- execution_engine/src/runtime_context/mod.rs | 34 +- .../test_support/src/wasm_test_builder.rs | 29 +- .../tests/src/test/deploy/receipts.rs | 125 ++---- .../tests/src/test/explorer/faucet.rs | 8 +- .../components/contract_runtime/operations.rs | 2 +- node/src/components/contract_runtime/types.rs | 75 ++-- .../event_stream_server/sse_server.rs | 5 +- node/src/components/storage.rs | 31 +- node/src/components/storage/tests.rs | 27 +- node/src/reactor/main_reactor/tests.rs | 22 +- .../block/block_execution_results_or_chunk.rs | 4 +- resources/test/sse_data_schema.json | 424 ++++++------------ .../src/block_store/lmdb/lmdb_block_store.rs | 31 +- storage/src/data_access_layer/fee.rs | 4 +- storage/src/data_access_layer/transfer.rs | 4 +- storage/src/system/mint/mint_native.rs | 57 ++- storage/src/system/mint/system_provider.rs | 10 - storage/src/system/runtime_native.rs | 12 +- storage/src/tracking_copy/byte_size.rs | 2 - storage/src/tracking_copy/mod.rs | 6 - types/src/deploy_info.rs | 5 +- types/src/execution.rs | 2 +- types/src/execution/execution_result_v2.rs | 241 ++++------ types/src/execution/transform_kind.rs | 10 - types/src/gens.rs | 8 +- types/src/key.rs | 180 +------- types/src/lib.rs | 5 +- types/src/stored_value.rs | 87 +--- types/src/transaction.rs | 15 + types/src/transaction/transaction_header.rs | 15 +- types/src/transaction_info.rs | 195 -------- types/src/transfer.rs | 106 ++--- types/src/transfer/transfer_addr.rs | 254 ----------- types/src/transfer/transfer_v1.rs | 1 - .../transfer/transfer_v1/transfer_v1_addr.rs | 3 +- types/src/transfer/transfer_v2.rs | 4 - .../transfer/transfer_v2/transfer_v2_addr.rs | 225 ---------- utils/validation/src/generators.rs | 21 +- 43 files changed, 580 insertions(+), 1853 deletions(-) delete mode 100644 types/src/transaction_info.rs delete mode 100644 types/src/transfer/transfer_addr.rs delete mode 100644 types/src/transfer/transfer_v2/transfer_v2_addr.rs diff --git a/binary_port/src/speculative_execution_result.rs b/binary_port/src/speculative_execution_result.rs index 9d179f98e6..c665d78358 100644 --- a/binary_port/src/speculative_execution_result.rs +++ b/binary_port/src/speculative_execution_result.rs @@ -1,15 +1,14 @@ use casper_types::{ - bytesrepr, - bytesrepr::{FromBytes, ToBytes}, + bytesrepr::{self, FromBytes, ToBytes}, contract_messages::Messages, execution::Effects, - Gas, InvalidTransaction, TransferAddr, + Gas, InvalidTransaction, Transfer, }; #[derive(Debug)] pub struct SpeculativeExecutionResult { /// List of transfers that happened during execution. - transfers: Vec, + transfers: Vec, /// Gas limit. limit: Gas, /// Gas consumed. @@ -24,7 +23,7 @@ pub struct SpeculativeExecutionResult { impl SpeculativeExecutionResult { pub fn new( - transfers: Vec, + transfers: Vec, limit: Gas, consumed: Gas, effects: Effects, @@ -83,7 +82,7 @@ impl ToBytes for SpeculativeExecutionResult { impl FromBytes for SpeculativeExecutionResult { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (transfers, bytes) = Vec::::from_bytes(bytes)?; + let (transfers, bytes) = Vec::::from_bytes(bytes)?; let (limit, bytes) = Gas::from_bytes(bytes)?; let (consumed, bytes) = Gas::from_bytes(bytes)?; let (effects, bytes) = Effects::from_bytes(bytes)?; diff --git a/execution_engine/src/engine_state/execution_result.rs b/execution_engine/src/engine_state/execution_result.rs index 27281073cc..cf78c3e2c7 100644 --- a/execution_engine/src/engine_state/execution_result.rs +++ b/execution_engine/src/engine_state/execution_result.rs @@ -7,8 +7,8 @@ use tracing::{debug, trace}; use casper_storage::data_access_layer::BiddingResult; use casper_types::{ contract_messages::Messages, - execution::{Effects, ExecutionResultV2 as TypesExecutionResult, TransformKindV2, TransformV2}, - CLValue, Gas, Key, Motes, StoredValue, TransferAddr, + execution::{Effects, TransformKindV2, TransformV2}, + CLValue, Gas, Key, Motes, StoredValue, Transfer, }; use super::Error; @@ -22,7 +22,7 @@ pub enum ExecutionResult { /// Error causing this `Failure` variant. error: Error, /// List of transfers that happened during execution up to the point of the failure. - transfers: Vec, + transfers: Vec, /// Gas consumed up to the point of the failure. gas: Gas, /// Execution effects. @@ -33,7 +33,7 @@ pub enum ExecutionResult { /// Execution was finished successfully Success { /// List of transfers. - transfers: Vec, + transfers: Vec, /// Gas consumed. gas: Gas, /// Execution effects. @@ -94,7 +94,7 @@ impl ExecutionResult { } /// Returns list of transfers regardless of variant. - pub fn transfers(&self) -> &Vec { + pub fn transfers(&self) -> &Vec { match self { ExecutionResult::Failure { transfers, .. } => transfers, ExecutionResult::Success { transfers, .. } => transfers, @@ -146,7 +146,7 @@ impl ExecutionResult { /// /// This method preserves the [`ExecutionResult`] variant and updates the /// `transfers` field only. - pub fn with_transfers(self, transfers: Vec) -> Self { + pub fn with_transfers(self, transfers: Vec) -> Self { match self { ExecutionResult::Failure { error, @@ -380,50 +380,6 @@ pub enum ForcedTransferResult { PaymentFailure, } -/// A versioned execution result and the messages produced by that execution. -#[derive(Debug)] -pub struct ExecutionResultAndMessages { - /// Execution result - pub execution_result: TypesExecutionResult, - /// Messages emitted during execution - pub messages: Messages, -} - -impl From for ExecutionResultAndMessages { - fn from(execution_result: ExecutionResult) -> Self { - match execution_result { - ExecutionResult::Success { - transfers, - gas, - effects, - messages, - } => ExecutionResultAndMessages { - execution_result: TypesExecutionResult::Success { - effects, - transfers, - gas, - }, - messages, - }, - ExecutionResult::Failure { - error, - transfers, - gas, - effects, - messages, - } => ExecutionResultAndMessages { - execution_result: TypesExecutionResult::Failure { - effects, - transfers, - gas, - error_message: error.to_string(), - }, - messages, - }, - } - } -} - /// Represents error conditions of an execution result builder. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum ExecutionResultBuilderError { @@ -499,7 +455,7 @@ impl ExecutionResultBuilder { /// Returns transfers from a session's execution result. /// /// If the session's execution result is not supplied then an empty [`Vec`] is returned. - pub fn transfers(&self) -> Vec { + pub fn transfers(&self) -> Vec { self.session_execution_result .as_ref() .map(ExecutionResult::transfers) diff --git a/execution_engine/src/engine_state/wasm_v1.rs b/execution_engine/src/engine_state/wasm_v1.rs index 9d59fe554b..7ae9ba19cc 100644 --- a/execution_engine/src/engine_state/wasm_v1.rs +++ b/execution_engine/src/engine_state/wasm_v1.rs @@ -9,7 +9,7 @@ use casper_types::{ runtime_args, system::mint::ARG_AMOUNT, BlockTime, DeployHash, Digest, ExecutableDeployItem, Gas, InitiatorAddr, Phase, PricingMode, RuntimeArgs, Transaction, TransactionEntryPoint, TransactionHash, TransactionInvocationTarget, TransactionSessionKind, TransactionTarget, - TransactionV1, TransactionV1Hash, TransferAddr, U512, + TransactionV1, TransactionV1Hash, Transfer, U512, }; use crate::engine_state::{DeployItem, Error as EngineError, ExecutionResult}; @@ -220,7 +220,7 @@ impl<'a> WasmV1Request<'a> { #[derive(Clone, Debug)] pub struct WasmV1Result { /// List of transfers that happened during execution. - transfers: Vec, + transfers: Vec, /// Gas limit. limit: Gas, /// Gas consumed. @@ -240,7 +240,7 @@ impl WasmV1Result { } /// List of transfers that happened during execution. - pub fn transfers(&self) -> &Vec { + pub fn transfers(&self) -> &Vec { &self.transfers } diff --git a/execution_engine/src/runtime/mint_internal.rs b/execution_engine/src/runtime/mint_internal.rs index 3145301fb8..db7a5937f8 100644 --- a/execution_engine/src/runtime/mint_internal.rs +++ b/execution_engine/src/runtime/mint_internal.rs @@ -170,18 +170,16 @@ where { fn record_transfer( &mut self, - _maybe_to: Option, - _source: URef, - _target: URef, - _amount: U512, - _id: Option, + maybe_to: Option, + source: URef, + target: URef, + amount: U512, + id: Option, ) -> Result<(), Error> { - Ok(()) - - // let result = Runtime::record_transfer(self, maybe_to, source, target, amount, id); - // result.map_err(|exec_error| { - // >::from(exec_error).unwrap_or(Error::RecordTransferFailure) - // }) + let result = Runtime::record_transfer(self, maybe_to, source, target, amount, id); + result.map_err(|exec_error| { + >::from(exec_error).unwrap_or(Error::RecordTransferFailure) + }) } } diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index b25799f825..10c0fac97a 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -51,9 +51,9 @@ use casper_types::{ AccessRights, ApiError, BlockTime, ByteCode, ByteCodeAddr, ByteCodeHash, ByteCodeKind, CLTyped, CLValue, ContextAccessRights, ContractWasm, EntityAddr, EntityKind, EntityVersion, EntityVersionKey, EntityVersions, Gas, GrantedAccess, Group, Groups, HostFunction, - HostFunctionCost, Key, NamedArg, Package, PackageHash, PackageStatus, Phase, PublicKey, - RuntimeArgs, StoredValue, Tagged, TransferResult, TransferredTo, URef, - DICTIONARY_ITEM_KEY_MAX_LENGTH, U512, + HostFunctionCost, InitiatorAddr, Key, NamedArg, Package, PackageHash, PackageStatus, Phase, + PublicKey, RuntimeArgs, StoredValue, Tagged, Transfer, TransferResult, TransferV2, + TransferredTo, URef, DICTIONARY_ITEM_KEY_MAX_LENGTH, U512, }; use crate::{ @@ -2100,30 +2100,27 @@ where /// Records a transfer. fn record_transfer( &mut self, - _maybe_to: Option, - _source: URef, - _target: URef, - _amount: U512, - _id: Option, + maybe_to: Option, + source: URef, + target: URef, + amount: U512, + id: Option, ) -> Result<(), ExecError> { - // if self.context.get_entity_key() != self.context.get_system_entity_key(MINT)? { - // return Err(ExecError::InvalidContext); - // } - // - // if self.context.phase() != Phase::Session { - // return Ok(()); - // } - // - // let transfer_addr = self.context.new_transfer_addr()?; - // let txn_hash = self.context.get_transaction_hash(); - // let from = InitiatorAddr::AccountHash(self.context.get_caller()); - // let fee = Gas::zero(); // TODO - // let transfer = Transfer::V2(TransferV2::new( - // txn_hash, from, maybe_to, source, target, amount, fee, id, - // )); - // self.context.transfers_mut().push(transfer_addr); - // self.context - // .write_transfer(Key::Transfer(transfer_addr), transfer); + if self.context.get_entity_key() != self.context.get_system_entity_key(MINT)? { + return Err(ExecError::InvalidContext); + } + + if self.context.phase() != Phase::Session { + return Ok(()); + } + + let txn_hash = self.context.get_transaction_hash(); + let from = InitiatorAddr::AccountHash(self.context.get_caller()); + let fee = Gas::zero(); // TODO + let transfer = Transfer::V2(TransferV2::new( + txn_hash, from, maybe_to, source, target, amount, fee, id, + )); + self.context.transfers_mut().push(transfer); Ok(()) } diff --git a/execution_engine/src/runtime_context/mod.rs b/execution_engine/src/runtime_context/mod.rs index 6ccc5fae3a..f018af633c 100644 --- a/execution_engine/src/runtime_context/mod.rs +++ b/execution_engine/src/runtime_context/mod.rs @@ -33,9 +33,8 @@ use casper_types::{ AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, CLType, CLValue, CLValueDictionary, ContextAccessRights, EntityAddr, EntryPointType, Gas, GrantedAccess, Key, KeyTag, Motes, Package, PackageHash, Phase, ProtocolVersion, PublicKey, RuntimeArgs, - StoredValue, StoredValueTypeMismatch, SystemEntityRegistry, TransactionHash, Transfer, - TransferAddr, TransferV2Addr, URef, URefAddr, DICTIONARY_ITEM_KEY_MAX_LENGTH, KEY_HASH_LENGTH, - U512, + StoredValue, StoredValueTypeMismatch, SystemEntityRegistry, TransactionHash, Transfer, URef, + URefAddr, DICTIONARY_ITEM_KEY_MAX_LENGTH, KEY_HASH_LENGTH, U512, }; use crate::{engine_state::EngineConfig, execution::ExecError}; @@ -71,7 +70,7 @@ pub struct RuntimeContext<'a, R> { engine_config: EngineConfig, //TODO: Will be removed along with stored session in later PR. entry_point_type: EntryPointType, - transfers: Vec, + transfers: Vec, remaining_spending_limit: U512, // Original account/contract for read only tasks taken before execution @@ -108,7 +107,7 @@ where args: RuntimeArgs, gas_limit: Gas, gas_counter: Gas, - transfers: Vec, + transfers: Vec, remaining_spending_limit: U512, entry_point_type: EntryPointType, calling_add_contract_version: CallingAddContractVersion, @@ -372,12 +371,6 @@ where self.new_uref(StoredValue::CLValue(CLValue::unit())) } - /// Creates a new transfer address using a transfer address generator. - pub fn new_transfer_addr(&mut self) -> Result { - let transfer_addr = self.address_generator.borrow_mut().create_address(); - Ok(TransferAddr::V2(TransferV2Addr::new(transfer_addr))) - } - /// Puts `key` to the map of named keys of current context. pub fn put_key(&mut self, name: String, key: Key) -> Result<(), ExecError> { // No need to perform actual validation on the base key because an account or contract (i.e. @@ -520,17 +513,6 @@ where .map_err(Into::into) } - /// Write a transfer instance to the global state. - pub fn write_transfer(&mut self, key: Key, value: Transfer) { - if let Key::Transfer(_) = key { - self.tracking_copy - .borrow_mut() - .write(key, StoredValue::Transfer(value)); - } else { - panic!("Do not use this function for writing non-transfer keys") - } - } - /// Write an era info instance to the global state. pub fn write_era_info(&mut self, key: Key, value: EraInfo) { if let Key::EraSummary = key { @@ -624,12 +606,12 @@ where } /// Returns list of transfers. - pub fn transfers(&self) -> &Vec { + pub fn transfers(&self) -> &Vec { &self.transfers } /// Returns mutable list of transfers. - pub fn transfers_mut(&mut self) -> &mut Vec { + pub fn transfers_mut(&mut self) -> &mut Vec { &mut self.transfers } @@ -694,9 +676,7 @@ where | StoredValue::ContractPackage(_) | StoredValue::ContractWasm(_) | StoredValue::MessageTopic(_) - | StoredValue::Message(_) - | StoredValue::TransactionInfo(_) - | StoredValue::Transfer(_) => Ok(()), + | StoredValue::Message(_) => Ok(()), } } diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index 8a8aebd269..9480b14c08 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -63,8 +63,7 @@ use casper_types::{ ByteCodeHash, CLTyped, CLValue, Contract, Digest, EntityAddr, EraId, Gas, HandlePaymentCosts, InitiatorAddr, Key, KeyTag, MintCosts, Motes, Package, PackageHash, ProtocolUpgradeConfig, ProtocolVersion, PublicKey, RefundHandling, StoredValue, SystemEntityRegistry, Timestamp, - TransactionHash, TransactionInfo, TransactionV1Hash, Transfer, TransferAddr, URef, - OS_PAGE_SIZE, U512, + TransactionHash, TransactionV1Hash, URef, OS_PAGE_SIZE, U512, }; use crate::{ @@ -1392,32 +1391,6 @@ where } } - /// Queries for a transfer by `TransferAddr`. - pub fn get_transfer(&self, transfer_addr: TransferAddr) -> Option { - let transfer_value: StoredValue = self - .query(None, Key::Transfer(transfer_addr), &[]) - .expect("should have transfer value"); - - if let StoredValue::Transfer(transfer) = transfer_value { - Some(transfer) - } else { - None - } - } - - /// Queries for transaction info by `TransactionHash`. - pub fn get_transaction_info(&self, txn_hash: TransactionHash) -> Option { - let txn_info_value: StoredValue = self - .query(None, Key::TransactionInfo(txn_hash), &[]) - .expect("should have transaction info value"); - - if let StoredValue::TransactionInfo(txn_info) = txn_info_value { - Some(txn_info) - } else { - None - } - } - /// Returns execution cost. pub fn exec_cost(&self, index: usize) -> Gas { self.exec_results diff --git a/execution_engine_testing/tests/src/test/deploy/receipts.rs b/execution_engine_testing/tests/src/test/deploy/receipts.rs index 4573726ace..1496e4215e 100644 --- a/execution_engine_testing/tests/src/test/deploy/receipts.rs +++ b/execution_engine_testing/tests/src/test/deploy/receipts.rs @@ -4,11 +4,11 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_ACCOUNT_PUBLIC_KEY, LOCAL_GENESIS_REQUEST, + LOCAL_GENESIS_REQUEST, }; use casper_types::{ account::AccountHash, runtime_args, system::mint, AccessRights, Gas, InitiatorAddr, PublicKey, - SecretKey, Transfer, TransferAddr, TransferV2, U512, + SecretKey, Transfer, TransferV2, U512, }; const CONTRACT_TRANSFER_PURSE_TO_ACCOUNT: &str = "transfer_purse_to_account.wasm"; @@ -77,26 +77,14 @@ fn should_record_wasmless_transfer() { .main_purse() .with_access_rights(AccessRights::ADD); - let txn_info = builder - .get_transaction_info(txn_hash) - .expect("should have txn info"); + let execution_result = builder + .get_last_exec_result() + .expect("Expected execution results."); - assert_eq!(txn_info.transaction_hash, txn_hash); - assert_eq!( - txn_info.from, - InitiatorAddr::PublicKey(DEFAULT_ACCOUNT_PUBLIC_KEY.clone()) - ); - assert_eq!(txn_info.source, default_account.main_purse()); - - // TODO: reenable after new payment logic is added - // assert_eq!(txn_info.gas, U512::from(DEFAULT_WASMLESS_TRANSFER_COST)); - - let transfers = txn_info.transfers; + let transfers = execution_result.transfers(); assert_eq!(transfers.len(), 1); - let Transfer::V2(transfer) = builder - .get_transfer(transfers[0]) - .expect("should have transfer") else { + let Transfer::V2(transfer) = transfers[0].clone() else { panic!("wrong transfer variant"); }; @@ -145,24 +133,15 @@ fn should_record_wasm_transfer() { .main_purse() .with_access_rights(AccessRights::ADD); - let txn_info = builder - .get_transaction_info(txn_hash) - .expect("should have txn info"); - - assert_eq!(txn_info.transaction_hash, txn_hash); - assert_eq!( - txn_info.from, - InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR) - ); - assert_eq!(txn_info.source, default_account.main_purse()); - assert_ne!(txn_info.gas, Gas::zero()); + let execution_result = builder + .get_last_exec_result() + .expect("Expected execution results."); - let transfers = txn_info.transfers; + assert_ne!(execution_result.consumed(), Gas::zero()); + let transfers = execution_result.transfers(); assert_eq!(transfers.len(), 1); - let Transfer::V2(transfer) = builder - .get_transfer(transfers[0]) - .expect("should have transfer") else { + let Transfer::V2(transfer) = transfers[0].clone() else { panic!("wrong transfer variant"); }; @@ -212,24 +191,15 @@ fn should_record_wasm_transfer_with_id() { .main_purse() .with_access_rights(AccessRights::ADD); - let txn_info = builder - .get_transaction_info(txn_hash) - .expect("should have txn info"); + let execution_result = builder + .get_last_exec_result() + .expect("Expected execution results."); - assert_eq!(txn_info.transaction_hash, txn_hash); - assert_eq!( - txn_info.from, - InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR) - ); - assert_eq!(txn_info.source, default_account.main_purse()); - assert_ne!(txn_info.gas, Gas::zero()); - - let transfers = txn_info.transfers; + assert_ne!(execution_result.consumed(), Gas::zero()); + let transfers = execution_result.transfers(); assert_eq!(transfers.len(), 1); - let Transfer::V2(transfer) = builder - .get_transfer(transfers[0]) - .expect("should have transfer") else { + let Transfer::V2(transfer) = transfers[0].clone() else { panic!("wrong transfer variant"); }; @@ -305,37 +275,27 @@ fn should_record_wasm_transfers() { .main_purse() .with_access_rights(AccessRights::ADD); - let txn_info = builder - .get_transaction_info(txn_hash) - .expect("should have txn info"); - - assert_eq!(txn_info.transaction_hash, txn_hash); - assert_eq!( - txn_info.from, - InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR) - ); - assert_eq!(txn_info.source, default_account.main_purse()); - assert_ne!(txn_info.gas, Gas::zero()); + let execution_result = builder + .get_last_exec_result() + .expect("Expected execution results."); + assert_ne!(execution_result.consumed(), Gas::zero()); const EXPECTED_LENGTH: usize = 3; - let transfer_addrs = txn_info.transfers; - assert_eq!(transfer_addrs.len(), EXPECTED_LENGTH); + assert_eq!(execution_result.transfers().len(), EXPECTED_LENGTH); assert_eq!( - transfer_addrs + execution_result + .transfers() .iter() .cloned() - .collect::>() + .collect::>() .len(), EXPECTED_LENGTH ); let transfers: BTreeSet = { let mut tmp = BTreeSet::new(); - for transfer_addr in transfer_addrs { - let transfer = builder - .get_transfer(transfer_addr) - .expect("should have transfer"); - tmp.insert(transfer); + for transfer in execution_result.transfers() { + tmp.insert(transfer.clone()); } tmp }; @@ -466,37 +426,38 @@ fn should_record_wasm_transfers_with_subcall() { .main_purse() .with_access_rights(AccessRights::ADD); - let txn_info = builder - .get_transaction_info(transfer_txn_hash) - .expect("should have txn info"); + let execution_result = builder + .get_last_exec_result() + .expect("Expected execution results."); + /* assert_eq!(txn_info.transaction_hash, transfer_txn_hash); assert_eq!( txn_info.from, InitiatorAddr::AccountHash(*DEFAULT_ACCOUNT_ADDR) ); assert_eq!(txn_info.source, default_account.main_purse()); - assert_ne!(txn_info.gas, Gas::zero()); + */ + assert_ne!(execution_result.consumed(), Gas::zero()); const EXPECTED_LENGTH: usize = 6; - let transfer_addrs = txn_info.transfers; - assert_eq!(transfer_addrs.len(), EXPECTED_LENGTH); + assert_eq!(execution_result.transfers().len(), EXPECTED_LENGTH); assert_eq!( - transfer_addrs + execution_result + .transfers() .iter() .cloned() - .collect::>() + .collect::>() .len(), EXPECTED_LENGTH ); let transfer_counts: BTreeMap = { let mut tmp = BTreeMap::new(); - for transfer_addr in transfer_addrs { - let transfer = builder - .get_transfer(transfer_addr) - .expect("should have transfer"); - tmp.entry(transfer).and_modify(|i| *i += 1).or_insert(1); + for transfer in execution_result.transfers() { + tmp.entry(transfer.clone()) + .and_modify(|i| *i += 1) + .or_insert(1); } tmp }; diff --git a/execution_engine_testing/tests/src/test/explorer/faucet.rs b/execution_engine_testing/tests/src/test/explorer/faucet.rs index ba2ba14fa0..66e1580c86 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet.rs @@ -923,10 +923,10 @@ fn faucet_costs() { // This test will fail if execution costs vary. The expected costs should not be updated // without understanding why the cost has changed. If the costs do change, it should be // reflected in the "Costs by Entry Point" section of the faucet crate's README.md. - const EXPECTED_FAUCET_INSTALL_COST: u64 = 92_506_829_880; - const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_742_240; - const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_318_380; - const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_830_980; + const EXPECTED_FAUCET_INSTALL_COST: u64 = 92_268_834_930; + const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_740_460; + const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_322_580; + const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_828_500; let installer_account = AccountHash::new([1u8; 32]); let user_account: AccountHash = AccountHash::new([2u8; 32]); diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index f2d0111344..f42fd32ff2 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -34,9 +34,9 @@ use super::{ BlockAndExecutionArtifacts, BlockExecutionError, ExecutionPreState, Metrics, APPROVALS_CHECKSUM_NAME, EXECUTION_RESULTS_CHECKSUM_NAME, }; -use crate::contract_runtime::types::ExecutionArtifactBuilder; use crate::{ components::fetcher::FetchItem, + contract_runtime::types::ExecutionArtifactBuilder, types::{self, Chunkable, ExecutableBlock, InternalEraReport}, }; diff --git a/node/src/components/contract_runtime/types.rs b/node/src/components/contract_runtime/types.rs index ea43c05436..c600084aa6 100644 --- a/node/src/components/contract_runtime/types.rs +++ b/node/src/components/contract_runtime/types.rs @@ -1,22 +1,25 @@ use std::{collections::BTreeMap, sync::Arc}; +use casper_types::{execution::PaymentInfo, InitiatorAddr, Transfer}; use datasize::DataSize; use serde::Serialize; use casper_execution_engine::engine_state::{ Error, InvalidRequest as InvalidWasmV1Request, WasmV1Result, }; -use casper_storage::data_access_layer::bidding::AuctionMethodError; use casper_storage::{ block_store::types::ApprovalsHashes, - data_access_layer::{BalanceHoldResult, BiddingResult, EraValidatorsRequest, TransferResult}, + data_access_layer::{ + bidding::AuctionMethodError, BalanceHoldResult, BiddingResult, EraValidatorsRequest, + TransferResult, + }, }; use casper_types::{ contract_messages::Messages, execution::{Effects, ExecutionResult, ExecutionResultV2}, BlockHash, BlockHeaderV2, BlockV2, DeployHash, DeployHeader, Digest, EraId, Gas, InvalidDeploy, InvalidTransaction, InvalidTransactionV1, ProtocolVersion, PublicKey, Transaction, - TransactionHash, TransactionHeader, TransactionV1Hash, TransactionV1Header, TransferAddr, U512, + TransactionHash, TransactionHeader, TransactionV1Hash, TransactionV1Header, U512, }; /// Request for validator weights for a specific era. @@ -66,23 +69,24 @@ pub(crate) struct ExecutionArtifactBuilder { header: TransactionHeader, error_message: Option, messages: Messages, - transfers: Vec, + transfers: Vec, + initiator: InitiatorAddr, + payment: Vec, gas: Gas, root_not_found: bool, } impl ExecutionArtifactBuilder { pub fn new(transaction: &Transaction) -> Self { - let effects = Effects::new(); - let hash = transaction.hash(); - let header = transaction.header().clone(); ExecutionArtifactBuilder { - effects, - hash, - header, + effects: Effects::new(), + hash: transaction.hash(), + header: transaction.header(), error_message: None, transfers: vec![], messages: Default::default(), + initiator: transaction.initiator_addr(), + payment: vec![], gas: Gas::zero(), root_not_found: false, } @@ -96,7 +100,7 @@ impl ExecutionArtifactBuilder { self.root_not_found } - pub fn with_appended_transfers(&mut self, transfers: &mut Vec) -> &mut Self { + pub fn with_appended_transfers(&mut self, transfers: &mut Vec) -> &mut Self { self.transfers.append(transfers); self } @@ -130,7 +134,7 @@ impl ExecutionArtifactBuilder { if let (None, BalanceHoldResult::Failure(err)) = (&self.error_message, hold_result) { self.error_message = Some(format!("{}", err)); } - self.with_appended_effects(hold_result.effects().clone()) + self.with_appended_effects(hold_result.effects()) } pub fn with_added_gas(&mut self, gas: Gas) -> &mut Self { @@ -177,10 +181,14 @@ impl ExecutionArtifactBuilder { self.error_message = Some(format!("{}", err)); return self; } - if let TransferResult::Success { transfers, effects } = transfer_result { + if let TransferResult::Success { + mut transfers, + effects, + } = transfer_result + { return self - .with_appended_transfers(&mut transfers.clone()) - .with_appended_effects(effects.clone()); + .with_appended_transfers(&mut transfers) + .with_appended_effects(effects); } self } @@ -195,27 +203,32 @@ impl ExecutionArtifactBuilder { return self; } if let BiddingResult::Success { effects, .. } = bidding_result { - return self.with_appended_effects(effects.clone()); + return self.with_appended_effects(effects); } self } + #[allow(unused)] + pub fn with_initiator_addr(&mut self, initiator_addr: InitiatorAddr) -> &mut Self { + self.initiator = initiator_addr; + self + } + + //TODO: use this when payment breakdown is implemented. + #[allow(unused)] + pub fn with_appended_payment_info(&mut self, payment: &mut Vec) -> &mut Self { + self.payment.append(payment); + self + } + pub(crate) fn build(self) -> ExecutionArtifact { - let effects = self.effects; - let transfers = self.transfers; - let gas = self.gas; - let result = match self.error_message { - Some(error_message) => ExecutionResultV2::Failure { - effects, - transfers, - gas, - error_message, - }, - None => ExecutionResultV2::Success { - effects, - transfers, - gas, - }, + let result = ExecutionResultV2 { + effects: self.effects, + transfers: self.transfers, + initiator: self.initiator, + payment: self.payment, + gas: self.gas, + error_message: self.error_message, }; let execution_result = ExecutionResult::V2(result); ExecutionArtifact::new(self.hash, self.header, execution_result, self.messages) diff --git a/node/src/components/event_stream_server/sse_server.rs b/node/src/components/event_stream_server/sse_server.rs index 614f099f21..02351b99bb 100644 --- a/node/src/components/event_stream_server/sse_server.rs +++ b/node/src/components/event_stream_server/sse_server.rs @@ -177,10 +177,7 @@ impl SseData { /// Returns a random `SseData::Step`. pub(super) fn random_step(rng: &mut TestRng) -> Self { - let execution_effects = match ExecutionResultV2::random(rng) { - ExecutionResultV2::Success { effects, .. } - | ExecutionResultV2::Failure { effects, .. } => effects, - }; + let execution_effects = ExecutionResultV2::random(rng).effects; SseData::Step { era_id: EraId::new(rng.gen()), execution_effects, diff --git a/node/src/components/storage.rs b/node/src/components/storage.rs index bf8211ee72..10aea2369d 100644 --- a/node/src/components/storage.rs +++ b/node/src/components/storage.rs @@ -65,13 +65,11 @@ use casper_storage::DbRawBytesSpec; use casper_types::SignedBlock; use casper_types::{ bytesrepr::{FromBytes, ToBytes}, - execution::{ - execution_result_v1, ExecutionResult, ExecutionResultV1, ExecutionResultV2, TransformKindV2, - }, + execution::{execution_result_v1, ExecutionResult, ExecutionResultV1, ExecutionResultV2}, Approval, ApprovalsHash, AvailableBlockRange, Block, BlockBody, BlockHash, BlockHeader, BlockSignatures, BlockSignaturesV1, BlockSignaturesV2, BlockV2, ChainNameDigest, DeployHash, - EraId, ExecutionInfo, FinalitySignature, ProtocolVersion, SignedBlockHeader, StoredValue, - Timestamp, Transaction, TransactionHash, TransactionHeader, TransactionId, Transfer, + EraId, ExecutionInfo, FinalitySignature, ProtocolVersion, SignedBlockHeader, Timestamp, + Transaction, TransactionHash, TransactionHeader, TransactionId, Transfer, }; use datasize::DataSize; use prometheus::Registry; @@ -2003,31 +2001,34 @@ fn move_storage_files_to_network_subdir( /// Returns all `Transform::WriteTransfer`s from the execution effects if this is an /// `ExecutionResult::Success`, or an empty `Vec` if `ExecutionResult::Failure`. fn successful_transfers(execution_result: &ExecutionResult) -> Vec { - let mut transfers: Vec = vec![]; + let mut all_transfers: Vec = vec![]; match execution_result { ExecutionResult::V1(ExecutionResultV1::Success { effect, .. }) => { for transform_v1 in &effect.transforms { if let execution_result_v1::TransformKindV1::WriteTransfer(transfer_v1) = &transform_v1.transform { - transfers.push(Transfer::V1(transfer_v1.clone())); + all_transfers.push(Transfer::V1(transfer_v1.clone())); } } } - ExecutionResult::V2(ExecutionResultV2::Success { effects, .. }) => { - for transform_v2 in effects.transforms() { - if let TransformKindV2::Write(StoredValue::Transfer(transfer)) = transform_v2.kind() - { - transfers.push(transfer.clone()); + ExecutionResult::V2(ExecutionResultV2 { + transfers, + error_message, + .. + }) => { + if error_message.is_none() { + for transfer in transfers { + all_transfers.push(transfer.clone()); } } + // else no-op: we only record transfers from successful executions. } - ExecutionResult::V1(ExecutionResultV1::Failure { .. }) - | ExecutionResult::V2(ExecutionResultV2::Failure { .. }) => { + ExecutionResult::V1(ExecutionResultV1::Failure { .. }) => { // No-op: we only record transfers from successful executions. } } - transfers + all_transfers } // Testing code. The functions below allow direct inspection of the storage component and should diff --git a/node/src/components/storage/tests.rs b/node/src/components/storage/tests.rs index c3bfb77809..1333aa30b4 100644 --- a/node/src/components/storage/tests.rs +++ b/node/src/components/storage/tests.rs @@ -20,15 +20,14 @@ use casper_storage::block_store::{ BlockStoreProvider, BlockStoreTransaction, DataReader, DataWriter, }; use casper_types::{ - execution::{Effects, ExecutionResult, ExecutionResultV2, TransformKindV2, TransformV2}, + execution::{Effects, ExecutionResult, ExecutionResultV2}, generate_ed25519_keypair, testing::TestRng, ApprovalsHash, AvailableBlockRange, Block, BlockHash, BlockHeader, BlockSignatures, BlockSignaturesV2, BlockV2, ChainNameDigest, Chainspec, ChainspecRawBytes, Deploy, DeployHash, - Digest, EraId, ExecutionInfo, FinalitySignature, FinalitySignatureV2, Gas, InitiatorAddr, Key, - ProtocolVersion, PublicKey, SecretKey, SignedBlockHeader, StoredValue, TestBlockBuilder, - TestBlockV1Builder, TimeDiff, Transaction, TransactionHash, TransactionV1Hash, Transfer, - TransferV2, U512, + Digest, EraId, ExecutionInfo, FinalitySignature, FinalitySignatureV2, Gas, InitiatorAddr, + ProtocolVersion, PublicKey, SecretKey, SignedBlockHeader, TestBlockBuilder, TestBlockV1Builder, + TimeDiff, Transaction, TransactionHash, TransactionV1Hash, Transfer, TransferV2, U512, }; use tempfile::tempdir; @@ -1353,9 +1352,10 @@ fn prepare_exec_result_with_transfer( rng: &mut TestRng, txn_hash: &TransactionHash, ) -> (ExecutionResult, Transfer) { + let initiator_addr = InitiatorAddr::random(rng); let transfer = Transfer::V2(TransferV2::new( *txn_hash, - InitiatorAddr::random(rng), + initiator_addr.clone(), Some(rng.gen()), rng.gen(), rng.gen(), @@ -1363,16 +1363,13 @@ fn prepare_exec_result_with_transfer( Gas::from(rng.gen::()), Some(rng.gen()), )); - let transform = TransformV2::new( - Key::TransactionInfo(*txn_hash), - TransformKindV2::Write(StoredValue::Transfer(transfer.clone())), - ); - let mut effects = Effects::new(); - effects.push(transform); - let exec_result = ExecutionResult::V2(ExecutionResultV2::Success { - effects, - transfers: vec![], + let exec_result = ExecutionResult::V2(ExecutionResultV2 { + effects: Effects::new(), + transfers: vec![transfer.clone()], + initiator: initiator_addr, gas: Gas::new(rng.gen::()), + payment: vec![], + error_message: None, }); (exec_result, transfer) } diff --git a/node/src/reactor/main_reactor/tests.rs b/node/src/reactor/main_reactor/tests.rs index cd7b29ba10..245ee733e7 100644 --- a/node/src/reactor/main_reactor/tests.rs +++ b/node/src/reactor/main_reactor/tests.rs @@ -692,16 +692,20 @@ impl TestFixture { .expect("node 0 should have given execution result") { ExecutionResult::V1(_) => unreachable!(), - ExecutionResult::V2(ExecutionResultV2::Success { effects, .. }) => { - effects.transforms().to_vec() - } - ExecutionResult::V2(ExecutionResultV2::Failure { - gas, error_message, .. + ExecutionResult::V2(ExecutionResultV2 { + effects, + gas, + error_message, + .. }) => { - panic!( - "transaction execution failed: {} gas: {}", - error_message, gas - ); + if error_message.is_none() { + effects.transforms().to_vec() + } else { + panic!( + "transaction execution failed: {:?} gas: {}", + error_message, gas + ); + } } } } diff --git a/node/src/types/block/block_execution_results_or_chunk.rs b/node/src/types/block/block_execution_results_or_chunk.rs index 7e2d502688..de95bb9037 100644 --- a/node/src/types/block/block_execution_results_or_chunk.rs +++ b/node/src/types/block/block_execution_results_or_chunk.rs @@ -2,8 +2,6 @@ use std::fmt::{self, Debug, Display, Formatter}; use datasize::DataSize; use once_cell::sync::OnceCell; -#[cfg(test)] -use rand::Rng; use serde::{Deserialize, Serialize}; use tracing::{debug, error}; @@ -181,7 +179,7 @@ impl BlockExecutionResultsOrChunk { ) -> Self { let execution_results: Vec = (0..num_results) .into_iter() - .map(|_| rng.gen::().into()) + .map(|_| ExecutionResultV2::random(rng).into()) .collect(); Self { diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index 79f2624a82..286af6d375 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -3290,101 +3290,62 @@ }, "ExecutionResultV2": { "description": "The result of executing a single transaction.", - "oneOf": [ - { - "description": "The result of a failed execution.", - "type": "object", - "required": [ - "Failure" - ], - "properties": { - "Failure": { - "type": "object", - "required": [ - "effects", - "error_message", - "gas", - "transfers" - ], - "properties": { - "effects": { - "description": "The effects of executing the transaction.", - "allOf": [ - { - "$ref": "#/definitions/Effects" - } - ] - }, - "transfers": { - "description": "A record of transfers performed while executing the transaction.", - "type": "array", - "items": { - "$ref": "#/definitions/TransferAddr" - } - }, - "gas": { - "description": "The gas consumed executing the transaction.", - "allOf": [ - { - "$ref": "#/definitions/Gas" - } - ] - }, - "error_message": { - "description": "The error message associated with executing the transaction.", - "type": "string" - } - }, - "additionalProperties": false + "type": "object", + "required": [ + "effects", + "gas", + "initiator", + "payment", + "transfers" + ], + "properties": { + "effects": { + "description": "The effects of executing the transaction.", + "allOf": [ + { + "$ref": "#/definitions/Effects" } - }, - "additionalProperties": false + ] }, - { - "description": "The result of a successful execution.", - "type": "object", - "required": [ - "Success" - ], - "properties": { - "Success": { - "type": "object", - "required": [ - "effects", - "gas", - "transfers" - ], - "properties": { - "effects": { - "description": "The effects of executing the transaction.", - "allOf": [ - { - "$ref": "#/definitions/Effects" - } - ] - }, - "transfers": { - "description": "A record of transfers performed while executing the transaction.", - "type": "array", - "items": { - "$ref": "#/definitions/TransferAddr" - } - }, - "gas": { - "description": "The gas consumed executing the transaction.", - "allOf": [ - { - "$ref": "#/definitions/Gas" - } - ] - } - }, - "additionalProperties": false + "transfers": { + "description": "A record of transfers performed while executing the transaction.", + "type": "array", + "items": { + "$ref": "#/definitions/Transfer" + } + }, + "initiator": { + "description": "Identifier of the initiator of the transaction.", + "allOf": [ + { + "$ref": "#/definitions/InitiatorAddr" } - }, - "additionalProperties": false + ] + }, + "payment": { + "description": "Breakdown of payments made to cover the cost.", + "type": "array", + "items": { + "$ref": "#/definitions/PaymentInfo" + } + }, + "gas": { + "description": "The gas consumed executing the transaction.", + "allOf": [ + { + "$ref": "#/definitions/Gas" + } + ] + }, + "error_message": { + "description": "The error message associated with executing the transaction if the transaction failed.", + "type": [ + "string", + "null" + ] } - ] + }, + "additionalProperties": false }, "Effects": { "description": "A log of all transforms produced during execution.", @@ -3784,32 +3745,6 @@ } }, "additionalProperties": false - }, - { - "description": "Info about a transaction.", - "type": "object", - "required": [ - "TransactionInfo" - ], - "properties": { - "TransactionInfo": { - "$ref": "#/definitions/TransactionInfo" - } - }, - "additionalProperties": false - }, - { - "description": "A versioned transfer.", - "type": "object", - "required": [ - "Transfer" - ], - "properties": { - "Transfer": { - "$ref": "#/definitions/Transfer" - } - }, - "additionalProperties": false } ] }, @@ -4643,102 +4578,109 @@ } } }, - "TransactionInfo": { - "description": "Information relating to the given Transaction, stored in global state under .", - "type": "object", - "required": [ - "from", - "gas", - "source", - "transaction_hash", - "transfers" - ], - "properties": { - "transaction_hash": { - "description": "The transaction hash.", - "allOf": [ - { - "$ref": "#/definitions/TransactionHash" - } - ] - }, - "transfers": { - "description": "Transfers done during execution of the transaction.", - "type": "array", - "items": { - "$ref": "#/definitions/TransferAddr" - } - }, - "from": { - "description": "Identifier of the initiator of the transaction.", - "allOf": [ - { - "$ref": "#/definitions/InitiatorAddr" - } - ] - }, - "source": { - "description": "Source purse used for payment of the transaction.", - "allOf": [ - { - "$ref": "#/definitions/URef" - } - ] - }, - "gas": { - "description": "Gas used in executing the transaction.", - "allOf": [ - { - "$ref": "#/definitions/Gas" - } - ] - } - }, - "additionalProperties": false - }, - "TransferAddr": { - "description": "A versioned wrapper for a transfer address.", + "TransformError": { + "description": "Error type for applying and combining transforms.\n\nA `TypeMismatch` occurs when a transform cannot be applied because the types are not compatible (e.g. trying to add a number to a string).", "oneOf": [ { - "description": "A version 1 transfer address.", + "description": "Error while (de)serializing data.", "type": "object", "required": [ - "Version1" + "Serialization" ], "properties": { - "Version1": { - "$ref": "#/definitions/TransferV1Addr" + "Serialization": { + "$ref": "#/definitions/BytesreprError" } }, "additionalProperties": false }, { - "description": "A version 2 transfer address.", + "description": "Type mismatch error.", "type": "object", "required": [ - "Version2" + "TypeMismatch" ], "properties": { - "Version2": { - "$ref": "#/definitions/TransferV2Addr" + "TypeMismatch": { + "$ref": "#/definitions/TypeMismatch" } }, "additionalProperties": false + }, + { + "description": "Type no longer supported.", + "type": "string", + "enum": [ + "Deprecated" + ] } ] }, - "TransferV2Addr": { - "description": "Hex-encoded version 2 transfer address.", - "type": "string" - }, - "Gas": { - "description": "The `Gas` struct represents a `U512` amount of gas.", - "allOf": [ + "BytesreprError": { + "description": "Serialization and deserialization errors.", + "oneOf": [ { - "$ref": "#/definitions/U512" + "description": "Early end of stream while deserializing.", + "type": "string", + "enum": [ + "EarlyEndOfStream" + ] + }, + { + "description": "Formatting error while deserializing.", + "type": "string", + "enum": [ + "Formatting" + ] + }, + { + "description": "Not all input bytes were consumed in [`deserialize`].", + "type": "string", + "enum": [ + "LeftOverBytes" + ] + }, + { + "description": "Out of memory error.", + "type": "string", + "enum": [ + "OutOfMemory" + ] + }, + { + "description": "No serialized representation is available for a value.", + "type": "string", + "enum": [ + "NotRepresentable" + ] + }, + { + "description": "Exceeded a recursion depth limit.", + "type": "string", + "enum": [ + "ExceededRecursionDepth" + ] } ] }, + "TypeMismatch": { + "description": "An error struct representing a type mismatch in [`StoredValue`](crate::StoredValue) operations.", + "type": "object", + "required": [ + "expected", + "found" + ], + "properties": { + "expected": { + "description": "The name of the expected type.", + "type": "string" + }, + "found": { + "description": "The actual type found.", + "type": "string" + } + } + }, "Transfer": { "description": "A versioned wrapper for a transfer.", "oneOf": [ @@ -4853,106 +4795,28 @@ }, "additionalProperties": false }, - "TransformError": { - "description": "Error type for applying and combining transforms.\n\nA `TypeMismatch` occurs when a transform cannot be applied because the types are not compatible (e.g. trying to add a number to a string).", - "oneOf": [ - { - "description": "Error while (de)serializing data.", - "type": "object", - "required": [ - "Serialization" - ], - "properties": { - "Serialization": { - "$ref": "#/definitions/BytesreprError" - } - }, - "additionalProperties": false - }, - { - "description": "Type mismatch error.", - "type": "object", - "required": [ - "TypeMismatch" - ], - "properties": { - "TypeMismatch": { - "$ref": "#/definitions/TypeMismatch" - } - }, - "additionalProperties": false - }, - { - "description": "Type no longer supported.", - "type": "string", - "enum": [ - "Deprecated" - ] - } - ] - }, - "BytesreprError": { - "description": "Serialization and deserialization errors.", - "oneOf": [ - { - "description": "Early end of stream while deserializing.", - "type": "string", - "enum": [ - "EarlyEndOfStream" - ] - }, - { - "description": "Formatting error while deserializing.", - "type": "string", - "enum": [ - "Formatting" - ] - }, - { - "description": "Not all input bytes were consumed in [`deserialize`].", - "type": "string", - "enum": [ - "LeftOverBytes" - ] - }, - { - "description": "Out of memory error.", - "type": "string", - "enum": [ - "OutOfMemory" - ] - }, - { - "description": "No serialized representation is available for a value.", - "type": "string", - "enum": [ - "NotRepresentable" - ] - }, + "Gas": { + "description": "The `Gas` struct represents a `U512` amount of gas.", + "allOf": [ { - "description": "Exceeded a recursion depth limit.", - "type": "string", - "enum": [ - "ExceededRecursionDepth" - ] + "$ref": "#/definitions/U512" } ] }, - "TypeMismatch": { - "description": "An error struct representing a type mismatch in [`StoredValue`](crate::StoredValue) operations.", + "PaymentInfo": { + "description": "Breakdown of payments made to cover the cost.", "type": "object", "required": [ - "expected", - "found" + "source" ], "properties": { - "expected": { - "description": "The name of the expected type.", - "type": "string" - }, - "found": { - "description": "The actual type found.", - "type": "string" + "source": { + "description": "Source purse used for payment of the transaction.", + "allOf": [ + { + "$ref": "#/definitions/URef" + } + ] } } }, diff --git a/storage/src/block_store/lmdb/lmdb_block_store.rs b/storage/src/block_store/lmdb/lmdb_block_store.rs index 27b32b61bc..e6fa881865 100644 --- a/storage/src/block_store/lmdb/lmdb_block_store.rs +++ b/storage/src/block_store/lmdb/lmdb_block_store.rs @@ -9,11 +9,9 @@ use datasize::DataSize; use tracing::{debug, error}; use casper_types::{ - execution::{ - execution_result_v1, ExecutionResult, ExecutionResultV1, ExecutionResultV2, TransformKindV2, - }, - Approval, Block, BlockBody, BlockHash, BlockHeader, BlockSignatures, Digest, StoredValue, - Transaction, TransactionHash, Transfer, + execution::{execution_result_v1, ExecutionResult, ExecutionResultV1, ExecutionResultV2}, + Approval, Block, BlockBody, BlockHash, BlockHeader, BlockSignatures, Digest, Transaction, + TransactionHash, Transfer, }; use super::{ @@ -543,30 +541,35 @@ pub(crate) fn new_environment( /// Returns all `Transform::WriteTransfer`s from the execution effects if this is an /// `ExecutionResult::Success`, or an empty `Vec` if `ExecutionResult::Failure`. fn successful_transfers(execution_result: &ExecutionResult) -> Vec { - let mut transfers: Vec = vec![]; + let mut all_transfers: Vec = vec![]; match execution_result { ExecutionResult::V1(ExecutionResultV1::Success { effect, .. }) => { for transform_entry in &effect.transforms { if let execution_result_v1::TransformKindV1::WriteTransfer(transfer_v1) = &transform_entry.transform { - transfers.push(Transfer::V1(transfer_v1.clone())); + all_transfers.push(Transfer::V1(transfer_v1.clone())); } } } - ExecutionResult::V2(ExecutionResultV2::Success { effects, .. }) => { - for transform in effects.transforms() { - if let TransformKindV2::Write(StoredValue::Transfer(transfer)) = transform.kind() { - transfers.push(transfer.clone()); + ExecutionResult::V2(ExecutionResultV2 { + transfers, + error_message, + .. + }) => { + if error_message.is_none() { + for transfer in transfers { + all_transfers.push(transfer.clone()); } } + // else no-op: we only record transfers from successful executions. } - ExecutionResult::V1(ExecutionResultV1::Failure { .. }) - | ExecutionResult::V2(ExecutionResultV2::Failure { .. }) => { + ExecutionResult::V1(ExecutionResultV1::Failure { .. }) => { // No-op: we only record transfers from successful executions. } } - transfers + + all_transfers } impl<'s> BlockStoreProvider for LmdbBlockStore<'s> { diff --git a/storage/src/data_access_layer/fee.rs b/storage/src/data_access_layer/fee.rs index 723cb4cafb..f6491789d4 100644 --- a/storage/src/data_access_layer/fee.rs +++ b/storage/src/data_access_layer/fee.rs @@ -6,7 +6,7 @@ use crate::system::{ transfer::TransferError, }; use casper_types::{ - account::AccountHash, execution::Effects, Digest, FeeHandling, ProtocolVersion, TransferAddr, + account::AccountHash, execution::Effects, Digest, FeeHandling, ProtocolVersion, Transfer, }; use crate::tracking_copy::TrackingCopyError; @@ -108,7 +108,7 @@ pub enum FeeResult { Failure(FeeError), Success { /// List of transfers that happened during execution. - transfers: Vec, + transfers: Vec, /// State hash after fee distribution outcome is committed to the global state. post_state_hash: Digest, /// Effects of the fee distribution process. diff --git a/storage/src/data_access_layer/transfer.rs b/storage/src/data_access_layer/transfer.rs index 8574b73576..3bee0152d6 100644 --- a/storage/src/data_access_layer/transfer.rs +++ b/storage/src/data_access_layer/transfer.rs @@ -3,7 +3,7 @@ use std::collections::BTreeSet; use crate::system::runtime_native::{Config as NativeRuntimeConfig, TransferConfig}; use casper_types::{ account::AccountHash, execution::Effects, Digest, Gas, InitiatorAddr, ProtocolVersion, - RuntimeArgs, TransactionHash, TransferAddr, + RuntimeArgs, TransactionHash, Transfer, }; use crate::system::transfer::{TransferArgs, TransferError}; @@ -162,7 +162,7 @@ pub enum TransferResult { /// Transfer succeeded Success { /// List of transfers that happened during execution. - transfers: Vec, + transfers: Vec, /// Effects of transfer. effects: Effects, }, diff --git a/storage/src/system/mint/mint_native.rs b/storage/src/system/mint/mint_native.rs index 47074f88cf..9b476f8fc1 100644 --- a/storage/src/system/mint/mint_native.rs +++ b/storage/src/system/mint/mint_native.rs @@ -8,7 +8,7 @@ use crate::{ runtime_provider::RuntimeProvider, storage_provider::StorageProvider, system_provider::SystemProvider, Mint, }, - runtime_native::RuntimeNative, + runtime_native::{Id, RuntimeNative}, }, tracking_copy::{TrackingCopyEntityExt, TrackingCopyExt}, }; @@ -16,8 +16,8 @@ use casper_types::{ account::AccountHash, bytesrepr::{FromBytes, ToBytes}, system::{mint::Error, Caller}, - AccessRights, AddressableEntity, CLTyped, CLValue, Key, Phase, PublicKey, StoredValue, - SystemEntityRegistry, URef, U512, + AccessRights, AddressableEntity, CLTyped, CLValue, Gas, InitiatorAddr, Key, Phase, PublicKey, + StoredValue, SystemEntityRegistry, Transfer, TransferV2, URef, U512, }; impl RuntimeProvider for RuntimeNative @@ -208,36 +208,29 @@ where { fn record_transfer( &mut self, - _maybe_to: Option, - _source: URef, - _target: URef, - _amount: U512, - _id: Option, + maybe_to: Option, + source: URef, + target: URef, + amount: U512, + id: Option, ) -> Result<(), Error> { - // if self.phase() != Phase::Session { - // return Ok(()); - // } - // let txn_hash = match self.id() { - // Id::Transaction(txn_hash) => *txn_hash, - // // we don't write transfer records for systemic transfers (step, fees, rewards, etc) - // // so return Ok and move on. - // Id::Seed(_) => return Ok(()), - // }; - // let from = InitiatorAddr::AccountHash(self.get_caller()); - // let fee = Gas::zero(); // TODO - // let transfer = Transfer::V2(TransferV2::new( - // txn_hash, from, maybe_to, source, target, amount, fee, id, - // )); - // - // let transfer_addr = TransferAddr::from(TransferV2Addr::new( - // self.address_generator().create_address(), - // )); - // self.push_transfer(transfer_addr); - // - // self.tracking_copy().borrow_mut().write( - // Key::Transfer(transfer_addr), - // StoredValue::Transfer(transfer), - // ); + if self.phase() != Phase::Session { + return Ok(()); + } + let txn_hash = match self.id() { + Id::Transaction(txn_hash) => *txn_hash, + // we don't write transfer records for systemic transfers (step, fees, rewards, etc) + // so return Ok and move on. + Id::Seed(_) => return Ok(()), + }; + let from = InitiatorAddr::AccountHash(self.get_caller()); + let fee = Gas::zero(); // TODO + let transfer = Transfer::V2(TransferV2::new( + txn_hash, from, maybe_to, source, target, amount, fee, id, + )); + + self.push_transfer(transfer); + Ok(()) } } diff --git a/storage/src/system/mint/system_provider.rs b/storage/src/system/mint/system_provider.rs index 627d77ec6b..64922f7247 100644 --- a/storage/src/system/mint/system_provider.rs +++ b/storage/src/system/mint/system_provider.rs @@ -2,16 +2,6 @@ use casper_types::{account::AccountHash, system::mint::Error, URef, U512}; /// Provides functionality of a system module. pub trait SystemProvider { - /* TODO: record_transfer:: writing Deploy / TransactionInfo and Transfer records to global state - is not sustainable as such records are never pruned away, causing the width of a - slice of global state at tip to unnecessarily grow as they accrete over time. - Instead, this salient details can be recored in the transaction meta data that we - already store ... currently a vec of TransferAddr is stored. Going forward we would - just store the record itself in the metadata. That metadata is already wired up - to be synchronized, chunked, etc. - In the meantime, until that can be wired up, disabling the storing of these records. - */ - /// Records a transfer. fn record_transfer( &mut self, diff --git a/storage/src/system/runtime_native.rs b/storage/src/system/runtime_native.rs index b24736b839..ddeacc6be6 100644 --- a/storage/src/system/runtime_native.rs +++ b/storage/src/system/runtime_native.rs @@ -6,7 +6,7 @@ use crate::{ use casper_types::{ account::AccountHash, addressable_entity::NamedKeys, AddressableEntity, Chainspec, ContextAccessRights, FeeHandling, Key, Phase, ProtocolVersion, PublicKey, RefundHandling, - StoredValue, TransactionHash, TransferAddr, URef, U512, + StoredValue, TransactionHash, Transfer, URef, U512, }; use std::{cell::RefCell, collections::BTreeSet, rc::Rc}; @@ -239,7 +239,7 @@ pub struct RuntimeNative { named_keys: NamedKeys, access_rights: ContextAccessRights, remaining_spending_limit: U512, - transfers: Vec, + transfers: Vec, phase: Phase, } @@ -361,12 +361,12 @@ where self.remaining_spending_limit = remaining; } - pub fn transfers(&self) -> &Vec { + pub fn transfers(&self) -> &Vec { &self.transfers } - pub fn push_transfer(&mut self, transfer_addr: TransferAddr) { - self.transfers.push(transfer_addr); + pub fn push_transfer(&mut self, transfer: Transfer) { + self.transfers.push(transfer); } pub fn id(&self) -> &Id { @@ -389,7 +389,7 @@ where self.config.compute_rewards } - pub fn into_transfers(self) -> Vec { + pub fn into_transfers(self) -> Vec { self.transfers } } diff --git a/storage/src/tracking_copy/byte_size.rs b/storage/src/tracking_copy/byte_size.rs index 12f8fa91ba..417defdd05 100644 --- a/storage/src/tracking_copy/byte_size.rs +++ b/storage/src/tracking_copy/byte_size.rs @@ -47,8 +47,6 @@ impl ByteSize for StoredValue { } StoredValue::Message(message_summary) => message_summary.serialized_length(), StoredValue::NamedKey(named_key) => named_key.serialized_length(), - StoredValue::TransactionInfo(info) => info.serialized_length(), - StoredValue::Transfer(transfer) => transfer.serialized_length(), } } } diff --git a/storage/src/tracking_copy/mod.rs b/storage/src/tracking_copy/mod.rs index 84f27adba4..0ac1c5b76a 100644 --- a/storage/src/tracking_copy/mod.rs +++ b/storage/src/tracking_copy/mod.rs @@ -695,12 +695,6 @@ where StoredValue::Message(_) => { return Ok(query.into_not_found_result("Message value found.")); } - StoredValue::TransactionInfo(_) => { - return Ok(query.into_not_found_result("TransactionInfo value found.")); - } - StoredValue::Transfer(_) => { - return Ok(query.into_not_found_result("Transfer value found.")); - } } } } diff --git a/types/src/deploy_info.rs b/types/src/deploy_info.rs index c0bad8e239..d98c3b14b9 100644 --- a/types/src/deploy_info.rs +++ b/types/src/deploy_info.rs @@ -110,8 +110,9 @@ pub(crate) mod gens { use proptest::{collection, prelude::Strategy}; use crate::{ - gens::{u512_arb, uref_arb}, - transaction_info::gens::{account_hash_arb, deploy_hash_arb, transfer_v1_addr_arb}, + gens::{account_hash_arb, u512_arb, uref_arb}, + transaction::gens::deploy_hash_arb, + transfer::gens::transfer_v1_addr_arb, DeployInfo, }; diff --git a/types/src/execution.rs b/types/src/execution.rs index f1f190ad44..2c57b26d9d 100644 --- a/types/src/execution.rs +++ b/types/src/execution.rs @@ -11,7 +11,7 @@ mod transform_kind; pub use effects::Effects; pub use execution_result::ExecutionResult; pub use execution_result_v1::ExecutionResultV1; -pub use execution_result_v2::ExecutionResultV2; +pub use execution_result_v2::{ExecutionResultV2, PaymentInfo}; pub use transform::TransformV2; pub use transform_error::TransformError; pub use transform_kind::{TransformInstruction, TransformKindV2}; diff --git a/types/src/execution/execution_result_v2.rs b/types/src/execution/execution_result_v2.rs index 42675ec660..7337b40608 100644 --- a/types/src/execution/execution_result_v2.rs +++ b/types/src/execution/execution_result_v2.rs @@ -13,7 +13,7 @@ use datasize::DataSize; #[cfg(feature = "json-schema")] use once_cell::sync::Lazy; #[cfg(any(feature = "testing", test))] -use rand::{distributions::Standard, prelude::Distribution, Rng}; +use rand::Rng; #[cfg(feature = "json-schema")] use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -23,14 +23,12 @@ use super::Effects; use super::{TransformKindV2, TransformV2}; #[cfg(any(feature = "testing", test))] use crate::testing::TestRng; -#[cfg(any(feature = "json-schema", feature = "testing", test))] -use crate::TransferV2Addr; +#[cfg(feature = "json-schema")] +use crate::Key; use crate::{ - bytesrepr::{self, FromBytes, ToBytes, RESULT_ERR_TAG, RESULT_OK_TAG, U8_SERIALIZED_LENGTH}, - Gas, TransferAddr, + bytesrepr::{self, FromBytes, ToBytes}, + Gas, InitiatorAddr, Transfer, URef, }; -#[cfg(feature = "json-schema")] -use crate::{Key, KEY_HASH_LENGTH}; #[cfg(feature = "json-schema")] static EXECUTION_RESULT: Lazy = Lazy::new(|| { @@ -46,74 +44,72 @@ static EXECUTION_RESULT: Lazy = Lazy::new(|| { effects.push(TransformV2::new(key1, TransformKindV2::AddUInt64(8u64))); effects.push(TransformV2::new(key2, TransformKindV2::Identity)); - let transfers = vec![ - TransferAddr::V2(TransferV2Addr::new([89; KEY_HASH_LENGTH])), - TransferAddr::V2(TransferV2Addr::new([130; KEY_HASH_LENGTH])), - ]; + let transfers = vec![Transfer::example().clone()]; - ExecutionResultV2::Success { + ExecutionResultV2 { effects, transfers, gas: Gas::new(123_456), + payment: vec![PaymentInfo { + source: URef::new([1; crate::UREF_ADDR_LENGTH], crate::AccessRights::READ), + }], + initiator: InitiatorAddr::from(crate::PublicKey::example().clone()), + error_message: None, } }); -/// The result of executing a single transaction. +/// Breakdown of payments made to cover the cost. #[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Debug)] #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] -#[serde(deny_unknown_fields)] -pub enum ExecutionResultV2 { - /// The result of a failed execution. - Failure { - /// The effects of executing the transaction. - effects: Effects, - /// A record of transfers performed while executing the transaction. - transfers: Vec, - /// The gas consumed executing the transaction. - gas: Gas, - /// The error message associated with executing the transaction. - error_message: String, - }, - /// The result of a successful execution. - Success { - /// The effects of executing the transaction. - effects: Effects, - /// A record of transfers performed while executing the transaction. - transfers: Vec, - /// The gas consumed executing the transaction. - gas: Gas, - }, +pub struct PaymentInfo { + /// Source purse used for payment of the transaction. + pub source: URef, } -#[cfg(any(feature = "testing", test))] -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> ExecutionResultV2 { - let transfer_count = rng.gen_range(0..6); - let mut transfers = Vec::new(); - for _ in 0..transfer_count { - transfers.push(TransferAddr::V2(TransferV2Addr::new(rng.gen()))) - } +impl ToBytes for PaymentInfo { + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + self.source.write_bytes(writer) + } - let effects = Effects::random(rng); + fn to_bytes(&self) -> Result, bytesrepr::Error> { + let mut buffer = bytesrepr::allocate_buffer(self)?; + self.write_bytes(&mut buffer)?; + Ok(buffer) + } - if rng.gen() { - ExecutionResultV2::Failure { - effects, - transfers, - gas: Gas::new(rng.gen::()), - error_message: format!("Error message {}", rng.gen::()), - } - } else { - ExecutionResultV2::Success { - effects, - transfers, - gas: Gas::new(rng.gen::()), - } - } + fn serialized_length(&self) -> usize { + self.source.serialized_length() + } +} + +impl FromBytes for PaymentInfo { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (source, remainder) = URef::from_bytes(bytes)?; + Ok((PaymentInfo { source }, remainder)) } } +/// The result of executing a single transaction. +#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Debug)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +#[serde(deny_unknown_fields)] +pub struct ExecutionResultV2 { + /// The effects of executing the transaction. + pub effects: Effects, + /// A record of transfers performed while executing the transaction. + pub transfers: Vec, + /// Identifier of the initiator of the transaction. + pub initiator: InitiatorAddr, + /// Breakdown of payments made to cover the cost. + pub payment: Vec, + /// The gas consumed executing the transaction. + pub gas: Gas, + /// The error message associated with executing the transaction if the transaction failed. + pub error_message: Option, +} + impl ExecutionResultV2 { // This method is not intended to be used by third party crates. #[doc(hidden)] @@ -130,54 +126,35 @@ impl ExecutionResultV2 { let transfer_count = rng.gen_range(0..6); let mut transfers = vec![]; for _ in 0..transfer_count { - transfers.push(TransferAddr::V2(TransferV2Addr::new(rng.gen()))) + transfers.push(Transfer::random(rng)) } let gas = Gas::new(rng.gen::()); - if rng.gen() { - ExecutionResultV2::Failure { - effects, - transfers, - gas, - error_message: format!("Error message {}", rng.gen::()), - } - } else { - ExecutionResultV2::Success { - effects, - transfers, - gas, - } + let payment = vec![PaymentInfo { source: rng.gen() }]; + ExecutionResultV2 { + effects, + transfers, + gas, + payment, + initiator: InitiatorAddr::random(rng), + error_message: if rng.gen() { + Some(format!("Error message {}", rng.gen::())) + } else { + None + }, } } } impl ToBytes for ExecutionResultV2 { fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - match self { - ExecutionResultV2::Failure { - effects, - transfers, - gas, - error_message, - } => { - RESULT_ERR_TAG.write_bytes(writer)?; - effects.write_bytes(writer)?; - transfers.write_bytes(writer)?; - gas.write_bytes(writer)?; - error_message.write_bytes(writer) - } - ExecutionResultV2::Success { - effects, - transfers, - gas, - } => { - RESULT_OK_TAG.write_bytes(writer)?; - effects.write_bytes(writer)?; - transfers.write_bytes(writer)?; - gas.write_bytes(writer) - } - } + self.effects.write_bytes(writer)?; + self.transfers.write_bytes(writer)?; + self.initiator.write_bytes(writer)?; + self.payment.write_bytes(writer)?; + self.gas.write_bytes(writer)?; + self.error_message.write_bytes(writer) } fn to_bytes(&self) -> Result, bytesrepr::Error> { @@ -187,62 +164,32 @@ impl ToBytes for ExecutionResultV2 { } fn serialized_length(&self) -> usize { - U8_SERIALIZED_LENGTH - + match self { - ExecutionResultV2::Failure { - effects, - transfers, - gas, - error_message, - } => { - effects.serialized_length() - + transfers.serialized_length() - + gas.serialized_length() - + error_message.serialized_length() - } - ExecutionResultV2::Success { - effects, - transfers, - gas, - } => { - effects.serialized_length() - + transfers.serialized_length() - + gas.serialized_length() - } - } + self.effects.serialized_length() + + self.transfers.serialized_length() + + self.initiator.serialized_length() + + self.payment.serialized_length() + + self.gas.serialized_length() + + self.error_message.serialized_length() } } impl FromBytes for ExecutionResultV2 { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (tag, remainder) = u8::from_bytes(bytes)?; - match tag { - RESULT_ERR_TAG => { - let (effects, remainder) = Effects::from_bytes(remainder)?; - let (transfers, remainder) = Vec::::from_bytes(remainder)?; - let (gas, remainder) = Gas::from_bytes(remainder)?; - let (error_message, remainder) = String::from_bytes(remainder)?; - let execution_result = ExecutionResultV2::Failure { - effects, - transfers, - gas, - error_message, - }; - Ok((execution_result, remainder)) - } - RESULT_OK_TAG => { - let (effects, remainder) = Effects::from_bytes(remainder)?; - let (transfers, remainder) = Vec::::from_bytes(remainder)?; - let (gas, remainder) = Gas::from_bytes(remainder)?; - let execution_result = ExecutionResultV2::Success { - effects, - transfers, - gas, - }; - Ok((execution_result, remainder)) - } - _ => Err(bytesrepr::Error::Formatting), - } + let (effects, remainder) = Effects::from_bytes(bytes)?; + let (transfers, remainder) = Vec::::from_bytes(remainder)?; + let (initiator, remainder) = InitiatorAddr::from_bytes(remainder)?; + let (payment, remainder) = Vec::::from_bytes(remainder)?; + let (gas, remainder) = Gas::from_bytes(remainder)?; + let (error_message, remainder) = Option::::from_bytes(remainder)?; + let execution_result = ExecutionResultV2 { + effects, + transfers, + initiator, + payment, + gas, + error_message, + }; + Ok((execution_result, remainder)) } } diff --git a/types/src/execution/transform_kind.rs b/types/src/execution/transform_kind.rs index 574e449a7c..8fd52a042e 100644 --- a/types/src/execution/transform_kind.rs +++ b/types/src/execution/transform_kind.rs @@ -183,16 +183,6 @@ impl TransformKindV2 { let found = "Message".to_string(); Err(StoredValueTypeMismatch::new(expected, found).into()) } - StoredValue::TransactionInfo(_) => { - let expected = "Contract or Account".to_string(); - let found = "TransactionInfo".to_string(); - Err(StoredValueTypeMismatch::new(expected, found).into()) - } - StoredValue::Transfer(_) => { - let expected = "Contract or Account".to_string(); - let found = "Transfer".to_string(); - Err(StoredValueTypeMismatch::new(expected, found).into()) - } }, TransformKindV2::Failure(error) => Err(error), } diff --git a/types/src/gens.rs b/types/src/gens.rs index fd2f004e57..6d67bdcc6a 100644 --- a/types/src/gens.rs +++ b/types/src/gens.rs @@ -43,9 +43,9 @@ use crate::{ }, mint::BalanceHoldAddr, }, - transaction_info::gens::{deploy_hash_arb, transfer_v1_addr_arb, txn_info_arb}, + transaction::gens::deploy_hash_arb, transfer::{ - gens::{transfer_arb, transfer_v1_arb}, + gens::{transfer_v1_addr_arb, transfer_v1_arb}, TransferV1Addr, }, AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, ByteCode, CLType, CLValue, @@ -730,8 +730,6 @@ pub fn stored_value_arb() -> impl Strategy { message_topic_summary_arb().prop_map(StoredValue::MessageTopic), message_summary_arb().prop_map(StoredValue::Message), named_key_value_arb().prop_map(StoredValue::NamedKey), - txn_info_arb().prop_map(StoredValue::TransactionInfo), - transfer_arb().prop_map(StoredValue::Transfer), ] .prop_map(|stored_value| // The following match statement is here only to make sure @@ -755,8 +753,6 @@ pub fn stored_value_arb() -> impl Strategy { StoredValue::MessageTopic(_) => stored_value, StoredValue::Message(_) => stored_value, StoredValue::NamedKey(_) => stored_value, - StoredValue::TransactionInfo(_) => stored_value, - StoredValue::Transfer(_) => stored_value, }) } diff --git a/types/src/key.rs b/types/src/key.rs index a389d4397e..2c9a7e0211 100644 --- a/types/src/key.rs +++ b/types/src/key.rs @@ -33,8 +33,6 @@ use schemars::JsonSchema; use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer}; use tracing::warn; -#[cfg(any(feature = "testing", test))] -use crate::TransferV2Addr; use crate::{ account::{AccountHash, ACCOUNT_HASH_LENGTH}, addressable_entity, @@ -54,8 +52,8 @@ use crate::{ mint::BalanceHoldAddr, }, uref::{self, URef, URefAddr, UREF_SERIALIZED_LENGTH}, - ByteCodeAddr, DeployHash, Digest, EraId, Tagged, TransactionHash, TransactionV1Hash, - TransferAddr, TransferFromStrError, TransferV1Addr, TRANSFER_V1_ADDR_LENGTH, UREF_ADDR_LENGTH, + ByteCodeAddr, DeployHash, Digest, EraId, Tagged, TransferFromStrError, TransferV1Addr, + TRANSFER_V1_ADDR_LENGTH, UREF_ADDR_LENGTH, }; const HASH_PREFIX: &str = "hash-"; @@ -75,9 +73,6 @@ const CHECKSUM_REGISTRY_PREFIX: &str = "checksum-registry-"; const BID_ADDR_PREFIX: &str = "bid-addr-"; const PACKAGE_PREFIX: &str = "package-"; const BLOCK_MESSAGE_COUNT_PREFIX: &str = "block-message-count-"; -const TXN_INFO_PREFIX: &str = "txn-"; -const TXN_INFO_DEPLOY_PREFIX: &str = "d-"; -const TXN_INFO_V1_PREFIX: &str = "v1-"; /// The number of bytes in a Blake2b hash pub const BLAKE2B_DIGEST_LENGTH: usize = 32; @@ -161,15 +156,13 @@ pub enum KeyTag { NamedKey = 20, BlockMessageCount = 21, BalanceHold = 22, - TransactionInfo = 23, - Transfer = 24, } impl KeyTag { /// Returns a random `KeyTag`. #[cfg(any(feature = "testing", test))] pub fn random(rng: &mut TestRng) -> Self { - match rng.gen_range(0..=24) { + match rng.gen_range(0..=22) { 0 => KeyTag::Account, 1 => KeyTag::Hash, 2 => KeyTag::URef, @@ -193,8 +186,6 @@ impl KeyTag { 20 => KeyTag::NamedKey, 21 => KeyTag::BlockMessageCount, 22 => KeyTag::BalanceHold, - 23 => KeyTag::TransactionInfo, - 24 => KeyTag::Transfer, _ => panic!(), } } @@ -226,8 +217,6 @@ impl Display for KeyTag { KeyTag::NamedKey => write!(f, "NamedKey"), KeyTag::BlockMessageCount => write!(f, "BlockMessageCount"), KeyTag::BalanceHold => write!(f, "BalanceHold"), - KeyTag::TransactionInfo => write!(f, "TransactionInfo"), - KeyTag::Transfer => write!(f, "Transfer"), } } } @@ -276,8 +265,6 @@ impl FromBytes for KeyTag { tag if tag == KeyTag::NamedKey as u8 => KeyTag::NamedKey, tag if tag == KeyTag::BlockMessageCount as u8 => KeyTag::BlockMessageCount, tag if tag == KeyTag::BalanceHold as u8 => KeyTag::BalanceHold, - tag if tag == KeyTag::TransactionInfo as u8 => KeyTag::TransactionInfo, - tag if tag == KeyTag::Transfer as u8 => KeyTag::Transfer, _ => return Err(Error::Formatting), }; Ok((tag, rem)) @@ -338,10 +325,6 @@ pub enum Key { BlockMessageCount, /// A `Key` under which a hold on a purse balance is stored. BalanceHold(BalanceHoldAddr), - /// A `Key` under which info about a transaction is stored. - TransactionInfo(TransactionHash), - /// A `Key` under which a versioned transfer is stored. - Transfer(TransferAddr), } #[cfg(feature = "json-schema")] @@ -412,10 +395,6 @@ pub enum FromStrError { BlockMessageCount(String), /// Balance hold parse error. BalanceHold(String), - /// TransactionInfo parse error. - TransactionInfo(String), - /// Transfer parse error. - Transfer(TransferFromStrError), /// Unknown prefix. UnknownPrefix, } @@ -496,12 +475,6 @@ impl Display for FromStrError { FromStrError::BalanceHold(error) => { write!(f, "balance-hold from string error: {}", error) } - FromStrError::TransactionInfo(error) => { - write!(f, "transaction-info-key from string error: {}", error) - } - FromStrError::Transfer(error) => { - write!(f, "transfer-key from string error: {}", error) - } FromStrError::UnknownPrefix => write!(f, "unknown prefix for key"), } } @@ -535,8 +508,6 @@ impl Key { Key::NamedKey(_) => String::from("Key::NamedKey"), Key::BlockMessageCount => String::from("Key::BlockMessageCount"), Key::BalanceHold(_) => String::from("Key::BalanceHold"), - Key::TransactionInfo(_) => String::from("Key::TransactionInfo"), - Key::Transfer(_) => String::from("Key::Transfer"), } } @@ -653,25 +624,6 @@ impl Key { let tail = BalanceHoldAddr::to_formatted_string(&balance_hold_addr); format!("{}{}", BALANCE_HOLD_PREFIX, tail) } - Key::TransactionInfo(txn_hash) => match txn_hash { - TransactionHash::Deploy(deploy_hash) => { - format!( - "{}{}{}", - TXN_INFO_PREFIX, - TXN_INFO_DEPLOY_PREFIX, - base16::encode_lower(deploy_hash.as_ref()) - ) - } - TransactionHash::V1(txn_v1_hash) => { - format!( - "{}{}{}", - TXN_INFO_PREFIX, - TXN_INFO_V1_PREFIX, - base16::encode_lower(txn_v1_hash.as_ref()) - ) - } - }, - Key::Transfer(transfer_addr) => transfer_addr.to_formatted_string(), } } @@ -699,12 +651,6 @@ impl Key { return Ok(Key::DeployInfo(DeployHash::new(Digest::from(hash_array)))); } - match TransferAddr::from_formatted_str(input) { - Ok(transfer_addr) => return Ok(Key::Transfer(transfer_addr)), - Err(TransferFromStrError::InvalidPrefix) => {} - Err(error) => return Err(FromStrError::Transfer(error)), - } - if let Some(hex) = input.strip_prefix(LEGACY_TRANSFER_PREFIX) { let v1_addr = checksummed_hex::decode(hex) .map_err(|error| FromStrError::LegacyTransfer(TransferFromStrError::from(error)))?; @@ -892,28 +838,6 @@ impl Key { return Ok(Key::BlockMessageCount); } - if let Some(txn_hash) = input.strip_prefix(TXN_INFO_PREFIX) { - let txn_hash = if let Some(deploy_hash) = txn_hash.strip_prefix(TXN_INFO_DEPLOY_PREFIX) - { - let hash_bytes = checksummed_hex::decode(deploy_hash) - .map_err(|error| FromStrError::TransactionInfo(error.to_string()))?; - let hash = Digest::try_from(hash_bytes.as_slice()) - .map_err(|error| FromStrError::TransactionInfo(error.to_string()))?; - TransactionHash::from(DeployHash::new(hash)) - } else if let Some(txn_v1_hash) = txn_hash.strip_prefix(TXN_INFO_V1_PREFIX) { - let hash_bytes = checksummed_hex::decode(txn_v1_hash) - .map_err(|error| FromStrError::TransactionInfo(error.to_string()))?; - let hash = Digest::try_from(hash_bytes.as_slice()) - .map_err(|error| FromStrError::TransactionInfo(error.to_string()))?; - TransactionHash::from(TransactionV1Hash::new(hash)) - } else { - return Err(FromStrError::TransactionInfo( - "invalid transaction info prefix".to_string(), - )); - }; - return Ok(Key::TransactionInfo(txn_hash)); - } - Err(FromStrError::UnknownPrefix) } @@ -1368,22 +1292,6 @@ impl Display for Key { Key::BalanceHold(balance_hold_addr) => { write!(f, "Key::BalanceHold({})", balance_hold_addr) } - Key::TransactionInfo(TransactionHash::Deploy(deploy_hash)) => write!( - f, - "Key::TransactionInfo(deploy-{})", - base16::encode_lower(deploy_hash.as_ref()) - ), - Key::TransactionInfo(TransactionHash::V1(txn_v1_hash)) => write!( - f, - "Key::TransactionInfo(txn-v1-{})", - base16::encode_lower(txn_v1_hash.as_ref()) - ), - Key::Transfer(TransferAddr::V1(transfer_v1_addr)) => { - write!(f, "Key::Transfer(transfer-v1-{})", transfer_v1_addr) - } - Key::Transfer(TransferAddr::V2(transfer_v2_addr)) => { - write!(f, "Key::Transfer(transfer-v2-{})", transfer_v2_addr) - } } } } @@ -1420,8 +1328,6 @@ impl Tagged for Key { Key::NamedKey(_) => KeyTag::NamedKey, Key::BlockMessageCount => KeyTag::BlockMessageCount, Key::BalanceHold(_) => KeyTag::BalanceHold, - Key::TransactionInfo(_) => KeyTag::TransactionInfo, - Key::Transfer(_) => KeyTag::Transfer, } } } @@ -1445,12 +1351,6 @@ impl From for Key { } } -impl From for Key { - fn from(transfer_addr: TransferAddr) -> Key { - Key::Transfer(transfer_addr) - } -} - impl From for Key { fn from(package_hash: PackageHash) -> Key { Key::Package(package_hash.value()) @@ -1542,10 +1442,6 @@ impl ToBytes for Key { Key::BalanceHold(balance_hold_addr) => { U8_SERIALIZED_LENGTH + balance_hold_addr.serialized_length() } - Key::TransactionInfo(txn_hash) => { - KEY_ID_SERIALIZED_LENGTH + txn_hash.serialized_length() - } - Key::Transfer(transfer) => KEY_ID_SERIALIZED_LENGTH + transfer.serialized_length(), } } @@ -1582,8 +1478,6 @@ impl ToBytes for Key { Key::Message(message_addr) => message_addr.write_bytes(writer), Key::NamedKey(named_key_addr) => named_key_addr.write_bytes(writer), Key::BalanceHold(balance_hold_addr) => balance_hold_addr.write_bytes(writer), - Key::TransactionInfo(txn_hash) => txn_hash.write_bytes(writer), - Key::Transfer(addr) => addr.write_bytes(writer), } } } @@ -1684,14 +1578,6 @@ impl FromBytes for Key { let (balance_hold_addr, rem) = BalanceHoldAddr::from_bytes(remainder)?; Ok((Key::BalanceHold(balance_hold_addr), rem)) } - KeyTag::TransactionInfo => { - let (txn_hash, rem) = TransactionHash::from_bytes(remainder)?; - Ok((Key::TransactionInfo(txn_hash), rem)) - } - KeyTag::Transfer => { - let (transfer_addr, rem) = TransferAddr::from_bytes(remainder)?; - Ok((Key::Transfer(transfer_addr), rem)) - } } } } @@ -1724,15 +1610,13 @@ fn please_add_to_distribution_impl(key: Key) { Key::NamedKey(_) => unimplemented!(), Key::BlockMessageCount => unimplemented!(), Key::BalanceHold(_) => unimplemented!(), - Key::TransactionInfo(_) => unimplemented!(), - Key::Transfer(_) => unimplemented!(), } } #[cfg(any(feature = "testing", test))] impl Distribution for Standard { fn sample(&self, rng: &mut R) -> Key { - match rng.gen_range(0..=23) { + match rng.gen_range(0..=22) { 0 => Key::Account(rng.gen()), 1 => Key::Hash(rng.gen()), 2 => Key::URef(rng.gen()), @@ -1756,16 +1640,6 @@ impl Distribution for Standard { 20 => Key::NamedKey(NamedKeyAddr::new_named_key_entry(rng.gen(), rng.gen())), 21 => Key::BlockMessageCount, 22 => Key::BalanceHold(rng.gen()), - 23 => Key::TransactionInfo(if rng.gen() { - TransactionHash::Deploy(DeployHash::from_raw(rng.gen())) - } else { - TransactionHash::V1(TransactionV1Hash::from_raw(rng.gen())) - }), - 24 => Key::Transfer(if rng.gen() { - TransferAddr::V1(TransferV1Addr::new(rng.gen())) - } else { - TransferAddr::V2(TransferV2Addr::new(rng.gen())) - }), _ => unreachable!(), } } @@ -1800,8 +1674,6 @@ mod serde_helpers { NamedKey(&'a NamedKeyAddr), BlockMessageCount, BalanceHold(&'a BalanceHoldAddr), - TransactionInfo(&'a TransactionHash), - Transfer(&'a TransferAddr), } #[derive(Deserialize)] @@ -1830,8 +1702,6 @@ mod serde_helpers { NamedKey(NamedKeyAddr), BlockMessageCount, BalanceHold(BalanceHoldAddr), - TransactionInfo(TransactionHash), - Transfer(TransferAddr), } impl<'a> From<&'a Key> for BinarySerHelper<'a> { @@ -1866,8 +1736,6 @@ mod serde_helpers { Key::BalanceHold(balance_hold_addr) => { BinarySerHelper::BalanceHold(balance_hold_addr) } - Key::TransactionInfo(txn_hash) => BinarySerHelper::TransactionInfo(txn_hash), - Key::Transfer(transfer_addr) => BinarySerHelper::Transfer(transfer_addr), } } } @@ -1904,8 +1772,6 @@ mod serde_helpers { BinaryDeserHelper::BalanceHold(balance_hold_addr) => { Key::BalanceHold(balance_hold_addr) } - BinaryDeserHelper::TransactionInfo(txn_hash) => Key::TransactionInfo(txn_hash), - BinaryDeserHelper::Transfer(transfer_addr) => Key::Transfer(transfer_addr), } } } @@ -1995,12 +1861,6 @@ mod tests { const BLOCK_MESSAGE_COUNT: Key = Key::BlockMessageCount; const BALANCE_HOLD: Key = Key::BalanceHold(BalanceHoldAddr::new_gas([42; 32], BlockTime::new(100))); - const TRANSACTION_INFO_DEPLOY_KEY: Key = - Key::TransactionInfo(TransactionHash::Deploy(DeployHash::from_raw([42; 32]))); - const TRANSACTION_INFO_V1_KEY: Key = - Key::TransactionInfo(TransactionHash::V1(TransactionV1Hash::from_raw([42; 32]))); - const TRANSFER_V1_KEY: Key = Key::Transfer(TransferAddr::V1(TransferV1Addr::new([42; 32]))); - const TRANSFER_V2_KEY: Key = Key::Transfer(TransferAddr::V2(TransferV2Addr::new([42; 32]))); const KEYS: &[Key] = &[ ACCOUNT_KEY, HASH_KEY, @@ -2031,9 +1891,6 @@ mod tests { NAMED_KEY, BLOCK_MESSAGE_COUNT, BALANCE_HOLD, - TRANSACTION_INFO_V1_KEY, - TRANSFER_V1_KEY, - TRANSFER_V2_KEY, ]; const HEX_STRING: &str = "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"; const TOPIC_NAME_HEX_STRING: &str = @@ -2216,22 +2073,6 @@ mod tests { base16::encode_lower(&PADDING_BYTES) ) ); - assert_eq!( - format!("{}", TRANSACTION_INFO_DEPLOY_KEY), - format!("Key::TransactionInfo(deploy-{})", HEX_STRING) - ); - assert_eq!( - format!("{}", TRANSACTION_INFO_V1_KEY), - format!("Key::TransactionInfo(txn-v1-{})", HEX_STRING) - ); - assert_eq!( - format!("{}", TRANSFER_V1_KEY), - format!("Key::Transfer(transfer-v1-{})", HEX_STRING) - ); - assert_eq!( - format!("{}", TRANSFER_V2_KEY), - format!("Key::Transfer(transfer-v2-{})", HEX_STRING) - ); } #[test] @@ -2491,11 +2332,6 @@ mod tests { .to_string() .starts_with("byte-code-key from string error: ") ); - println!("{}", Key::from_formatted_str(TXN_INFO_PREFIX).unwrap_err()); - assert!(Key::from_formatted_str(TXN_INFO_PREFIX) - .unwrap_err() - .to_string() - .starts_with("transaction-info-key from string error: ")); let invalid_prefix = "a-0000000000000000000000000000000000000000000000000000000000000000"; assert_eq!( Key::from_formatted_str(invalid_prefix) @@ -2606,13 +2442,5 @@ mod tests { round_trip(&Key::NamedKey(NamedKeyAddr::default())); round_trip(&Key::BlockMessageCount); round_trip(&Key::BalanceHold(BalanceHoldAddr::default())); - round_trip(&Key::TransactionInfo(TransactionHash::Deploy( - DeployHash::from_raw(zeros), - ))); - round_trip(&Key::TransactionInfo(TransactionHash::V1( - TransactionV1Hash::from_raw(zeros), - ))); - round_trip(&Key::Transfer(TransferAddr::V1(TransferV1Addr::new(zeros)))); - round_trip(&Key::Transfer(TransferAddr::V2(TransferV2Addr::new(zeros)))); } } diff --git a/types/src/lib.rs b/types/src/lib.rs index fdf4c9603d..af75e50641 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -68,7 +68,6 @@ mod tagged; pub mod testing; mod timestamp; mod transaction; -mod transaction_info; mod transfer; mod transfer_result; mod uint; @@ -199,10 +198,8 @@ pub use transaction::{ pub use transaction::{ DeployBuilder, DeployBuilderError, TransactionV1Builder, TransactionV1BuilderError, }; -pub use transaction_info::TransactionInfo; pub use transfer::{ - Transfer, TransferAddr, TransferFromStrError, TransferV1, TransferV1Addr, TransferV2, - TransferV2Addr, TRANSFER_V1_ADDR_LENGTH, TRANSFER_V2_ADDR_LENGTH, + Transfer, TransferFromStrError, TransferV1, TransferV1Addr, TransferV2, TRANSFER_V1_ADDR_LENGTH, }; pub use transfer_result::{TransferResult, TransferredTo}; pub use uref::{ diff --git a/types/src/stored_value.rs b/types/src/stored_value.rs index 8187035b7d..a9af67b6d6 100644 --- a/types/src/stored_value.rs +++ b/types/src/stored_value.rs @@ -24,7 +24,7 @@ use crate::{ contracts::{Contract, ContractPackage}, package::Package, system::auction::{Bid, BidKind, EraInfo, UnbondingPurse, WithdrawPurse}, - AddressableEntity, ByteCode, CLValue, DeployInfo, TransactionInfo, Transfer, TransferV1, + AddressableEntity, ByteCode, CLValue, DeployInfo, TransferV1, }; pub use global_state_identifier::GlobalStateIdentifier; pub use type_mismatch::TypeMismatch; @@ -50,8 +50,6 @@ enum Tag { MessageTopic = 15, Message = 16, NamedKey = 17, - TransactionInfo = 18, - Transfer = 19, } /// A value stored in Global State. @@ -100,10 +98,6 @@ pub enum StoredValue { Message(MessageChecksum), /// A NamedKey record. NamedKey(NamedKeyValue), - /// Info about a transaction. - TransactionInfo(TransactionInfo), - /// A versioned transfer. - Transfer(Transfer), } impl StoredValue { @@ -231,22 +225,6 @@ impl StoredValue { } } - /// Returns a reference to the wrapped `TransactionInfo` if this is a `TransactionInfo` variant. - pub fn as_transaction_info(&self) -> Option<&TransactionInfo> { - match self { - StoredValue::TransactionInfo(txn_info) => Some(txn_info), - _ => None, - } - } - - /// Returns a reference to the wrapped `Transfer` if this is a `Transfer` variant. - pub fn as_transfer(&self) -> Option<&Transfer> { - match self { - StoredValue::Transfer(transfer) => Some(transfer), - _ => None, - } - } - /// Returns the `CLValue` if this is a `CLValue` variant. pub fn into_cl_value(self) -> Option { match self { @@ -359,22 +337,6 @@ impl StoredValue { } } - /// Returns the `TransactionInfo` if this is a `TransactionInfo` variant. - pub fn into_transaction_info(self) -> Option { - match self { - StoredValue::TransactionInfo(txn_info) => Some(txn_info), - _ => None, - } - } - - /// Returns the `Transfer` if this is a `Transfer` variant. - pub fn into_transfer(self) -> Option { - match self { - StoredValue::Transfer(transfer) => Some(transfer), - _ => None, - } - } - /// Returns the type name of the [`StoredValue`] enum variant. /// /// For [`CLValue`] variants it will return the name of the [`CLType`](crate::cl_type::CLType) @@ -398,8 +360,6 @@ impl StoredValue { StoredValue::MessageTopic(_) => "MessageTopic".to_string(), StoredValue::Message(_) => "Message".to_string(), StoredValue::NamedKey(_) => "NamedKey".to_string(), - StoredValue::TransactionInfo(_) => "TransactionInfo".to_string(), - StoredValue::Transfer(_) => "Transfer".to_string(), } } @@ -423,8 +383,6 @@ impl StoredValue { StoredValue::MessageTopic(_) => Tag::MessageTopic, StoredValue::Message(_) => Tag::Message, StoredValue::NamedKey(_) => Tag::NamedKey, - StoredValue::TransactionInfo(_) => Tag::TransactionInfo, - StoredValue::Transfer(_) => Tag::Transfer, } } } @@ -674,31 +632,6 @@ impl TryFrom for NamedKeyValue { } } -impl TryFrom for TransactionInfo { - type Error = TypeMismatch; - - fn try_from(value: StoredValue) -> Result { - match value { - StoredValue::TransactionInfo(txn_info) => Ok(txn_info), - _ => Err(TypeMismatch::new( - "TransactionInfo".to_string(), - value.type_name(), - )), - } - } -} - -impl TryFrom for Transfer { - type Error = TypeMismatch; - - fn try_from(value: StoredValue) -> Result { - match value { - StoredValue::Transfer(transfer) => Ok(transfer), - _ => Err(TypeMismatch::new("Transfer".to_string(), value.type_name())), - } - } -} - impl ToBytes for StoredValue { fn to_bytes(&self) -> Result, Error> { let mut buffer = bytesrepr::allocate_buffer(self)?; @@ -731,8 +664,6 @@ impl ToBytes for StoredValue { } StoredValue::Message(message_digest) => message_digest.serialized_length(), StoredValue::NamedKey(named_key_value) => named_key_value.serialized_length(), - StoredValue::TransactionInfo(txn_info) => txn_info.serialized_length(), - StoredValue::Transfer(transfer) => transfer.serialized_length(), } } @@ -759,8 +690,6 @@ impl ToBytes for StoredValue { } StoredValue::Message(message_digest) => message_digest.write_bytes(writer), StoredValue::NamedKey(named_key_value) => named_key_value.write_bytes(writer), - StoredValue::TransactionInfo(txn_info) => txn_info.write_bytes(writer), - StoredValue::Transfer(transfer) => transfer.write_bytes(writer), } } } @@ -825,10 +754,6 @@ impl FromBytes for StoredValue { (StoredValue::NamedKey(named_key_value), remainder) }) } - tag if tag == Tag::TransactionInfo as u8 => TransactionInfo::from_bytes(remainder) - .map(|(txn_info, remainder)| (StoredValue::TransactionInfo(txn_info), remainder)), - tag if tag == Tag::Transfer as u8 => Transfer::from_bytes(remainder) - .map(|(transfer, remainder)| (StoredValue::Transfer(transfer), remainder)), _ => Err(Error::Formatting), } } @@ -857,8 +782,6 @@ mod serde_helpers { MessageTopic(&'a MessageTopicSummary), Message(&'a MessageChecksum), NamedKey(&'a NamedKeyValue), - TransactionInfo(&'a TransactionInfo), - Transfer(&'a Transfer), } #[derive(Deserialize)] @@ -881,8 +804,6 @@ mod serde_helpers { MessageTopic(MessageTopicSummary), Message(MessageChecksum), NamedKey(NamedKeyValue), - TransactionInfo(TransactionInfo), - Transfer(Transfer), } impl<'a> From<&'a StoredValue> for BinarySerHelper<'a> { @@ -910,8 +831,6 @@ mod serde_helpers { } StoredValue::Message(message_digest) => BinarySerHelper::Message(message_digest), StoredValue::NamedKey(payload) => BinarySerHelper::NamedKey(payload), - StoredValue::TransactionInfo(payload) => BinarySerHelper::TransactionInfo(payload), - StoredValue::Transfer(payload) => BinarySerHelper::Transfer(payload), } } } @@ -943,10 +862,6 @@ mod serde_helpers { } BinaryDeserHelper::Message(message_digest) => StoredValue::Message(message_digest), BinaryDeserHelper::NamedKey(payload) => StoredValue::NamedKey(payload), - BinaryDeserHelper::TransactionInfo(payload) => { - StoredValue::TransactionInfo(payload) - } - BinaryDeserHelper::Transfer(payload) => StoredValue::Transfer(payload), } } } diff --git a/types/src/transaction.rs b/types/src/transaction.rs index 766f3350fe..7d0f8ac777 100644 --- a/types/src/transaction.rs +++ b/types/src/transaction.rs @@ -502,6 +502,21 @@ impl Display for Transaction { } } +/// Proptest generators for [`Transaction`]. +#[cfg(any(feature = "testing", feature = "gens", test))] +pub mod gens { + use proptest::{ + array, + prelude::{Arbitrary, Strategy}, + }; + + use super::*; + + pub fn deploy_hash_arb() -> impl Strategy { + array::uniform32(::arbitrary()).prop_map(DeployHash::from_raw) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/types/src/transaction/transaction_header.rs b/types/src/transaction/transaction_header.rs index 588d84bd03..68b5d7f3bd 100644 --- a/types/src/transaction/transaction_header.rs +++ b/types/src/transaction/transaction_header.rs @@ -9,7 +9,10 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use super::{DeployHeader, TransactionV1Header}; -use crate::bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}; +use crate::{ + bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, + InitiatorAddr, +}; const DEPLOY_TAG: u8 = 0; const V1_TAG: u8 = 1; @@ -31,6 +34,16 @@ pub enum TransactionHeader { V1(TransactionV1Header), } +impl TransactionHeader { + /// Return the initiator addr of this transaction. + pub fn initiator_addr(&self) -> InitiatorAddr { + match self { + TransactionHeader::Deploy(header) => header.account().clone().into(), + TransactionHeader::V1(header) => header.initiator_addr().clone(), + } + } +} + impl From for TransactionHeader { fn from(header: DeployHeader) -> Self { Self::Deploy(header) diff --git a/types/src/transaction_info.rs b/types/src/transaction_info.rs deleted file mode 100644 index 732fb24c0d..0000000000 --- a/types/src/transaction_info.rs +++ /dev/null @@ -1,195 +0,0 @@ -use alloc::vec::Vec; - -#[cfg(feature = "datasize")] -use datasize::DataSize; -#[cfg(feature = "json-schema")] -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use crate::{ - bytesrepr::{self, FromBytes, ToBytes}, - Gas, InitiatorAddr, TransactionHash, TransferAddr, URef, -}; - -/// Information relating to the given Transaction, stored in global state under . -#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)] -#[cfg_attr(feature = "datasize", derive(DataSize))] -#[cfg_attr(feature = "json-schema", derive(JsonSchema))] -#[serde(deny_unknown_fields)] -pub struct TransactionInfo { - /// The transaction hash. - pub transaction_hash: TransactionHash, - /// Transfers done during execution of the transaction. - pub transfers: Vec, - /// Identifier of the initiator of the transaction. - pub from: InitiatorAddr, - /// Source purse used for payment of the transaction. - pub source: URef, - /// Gas used in executing the transaction. - pub gas: Gas, -} - -impl TransactionInfo { - /// Returns a new `TransactionInfo`. - pub fn new( - transaction_hash: TransactionHash, - transfers: Vec, - from: InitiatorAddr, - source: URef, - gas: Gas, - ) -> Self { - TransactionInfo { - transaction_hash, - transfers, - from, - source, - gas, - } - } -} - -impl ToBytes for TransactionInfo { - fn to_bytes(&self) -> Result, bytesrepr::Error> { - let mut buf = Vec::new(); - self.write_bytes(&mut buf)?; - Ok(buf) - } - - fn serialized_length(&self) -> usize { - self.transaction_hash.serialized_length() - + self.transfers.serialized_length() - + self.from.serialized_length() - + self.source.serialized_length() - + self.gas.serialized_length() - } - - fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - self.transaction_hash.write_bytes(writer)?; - self.transfers.write_bytes(writer)?; - self.from.write_bytes(writer)?; - self.source.write_bytes(writer)?; - self.gas.write_bytes(writer) - } -} - -impl FromBytes for TransactionInfo { - fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (transaction_hash, remainder) = TransactionHash::from_bytes(bytes)?; - let (transfers, remainder) = Vec::::from_bytes(remainder)?; - let (from, remainder) = InitiatorAddr::from_bytes(remainder)?; - let (source, remainder) = URef::from_bytes(remainder)?; - let (gas, remainder) = Gas::from_bytes(remainder)?; - Ok(( - TransactionInfo { - transaction_hash, - transfers, - from, - source, - gas, - }, - remainder, - )) - } -} - -/// Generators for a `TransactionInfo`. -#[cfg(any(feature = "testing", feature = "gens", test))] -pub(crate) mod gens { - use alloc::vec::Vec; - - use proptest::{ - array, - collection::{self, SizeRange}, - prelude::{Arbitrary, Strategy}, - prop_oneof, - }; - - use crate::{ - account::AccountHash, - crypto::gens::public_key_arb_no_system, - gens::{u512_arb, uref_arb}, - DeployHash, Gas, InitiatorAddr, TransactionHash, TransactionInfo, TransactionV1Hash, - TransferAddr, TransferV1Addr, TransferV2Addr, - }; - - pub fn deploy_hash_arb() -> impl Strategy { - array::uniform32(::arbitrary()).prop_map(DeployHash::from_raw) - } - - pub fn txn_v1_hash_arb() -> impl Strategy { - array::uniform32(::arbitrary()).prop_map(TransactionV1Hash::from_raw) - } - - pub fn txn_hash_arb() -> impl Strategy { - prop_oneof![ - deploy_hash_arb().prop_map(TransactionHash::from), - txn_v1_hash_arb().prop_map(TransactionHash::from) - ] - } - - pub fn transfer_v1_addr_arb() -> impl Strategy { - array::uniform32(::arbitrary()).prop_map(TransferV1Addr::new) - } - - fn transfer_v2_addr_arb() -> impl Strategy { - array::uniform32(::arbitrary()).prop_map(TransferV2Addr::new) - } - - fn transfer_addr_arb() -> impl Strategy { - transfer_v2_addr_arb().prop_map(TransferAddr::from) - } - - pub fn transfer_addrs_arb( - size: impl Into, - ) -> impl Strategy> { - collection::vec(transfer_addr_arb(), size) - } - - pub fn account_hash_arb() -> impl Strategy { - array::uniform32(::arbitrary()).prop_map(AccountHash::new) - } - - pub fn initiator_addr_arb() -> impl Strategy { - prop_oneof![ - public_key_arb_no_system().prop_map(InitiatorAddr::from), - account_hash_arb().prop_map(InitiatorAddr::from), - ] - } - - /// Arbitrary `TransactionInfo`. - pub fn txn_info_arb() -> impl Strategy { - let transfers_length_range = 0..5; - ( - txn_hash_arb(), - transfer_addrs_arb(transfers_length_range), - initiator_addr_arb(), - uref_arb(), - u512_arb(), - ) - .prop_map( - |(transaction_hash, transfers, from, source, gas)| TransactionInfo { - transaction_hash, - transfers, - from, - source, - gas: Gas::new(gas), - }, - ) - } -} - -#[cfg(test)] -mod tests { - use proptest::prelude::*; - - use crate::bytesrepr; - - use super::gens; - - proptest! { - #[test] - fn test_serialization_roundtrip(txn_info in gens::txn_info_arb()) { - bytesrepr::test_serialization_roundtrip(&txn_info) - } - } -} diff --git a/types/src/transfer.rs b/types/src/transfer.rs index 4f8bc628e1..27e3358697 100644 --- a/types/src/transfer.rs +++ b/types/src/transfer.rs @@ -1,27 +1,29 @@ mod error; -mod transfer_addr; mod transfer_v1; mod transfer_v2; use alloc::vec::Vec; +#[cfg(any(feature = "testing", test))] +use crate::testing::TestRng; #[cfg(feature = "datasize")] use datasize::DataSize; #[cfg(feature = "json-schema")] use once_cell::sync::Lazy; +#[cfg(any(feature = "testing", test))] +use rand::Rng; #[cfg(feature = "json-schema")] use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use crate::bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}; #[cfg(feature = "json-schema")] -use crate::{ - account::AccountHash, Gas, InitiatorAddr, TransactionHash, TransactionV1Hash, URef, U512, -}; +use crate::{account::AccountHash, TransactionV1Hash, URef, U512}; +#[cfg(any(feature = "testing", feature = "json-schema", test))] +use crate::{Gas, InitiatorAddr, TransactionHash}; pub use error::TransferFromStrError; -pub use transfer_addr::TransferAddr; pub use transfer_v1::{TransferV1, TransferV1Addr, TRANSFER_V1_ADDR_LENGTH}; -pub use transfer_v2::{TransferV2, TransferV2Addr, TRANSFER_V2_ADDR_LENGTH}; +pub use transfer_v2::TransferV2; const V1_TAG: u8 = 0; const V2_TAG: u8 = 1; @@ -74,6 +76,36 @@ impl Transfer { pub fn example() -> &'static Self { &TRANSFER } + + /// Returns a random `Transfer`. + #[cfg(any(feature = "testing", test))] + pub fn random(rng: &mut TestRng) -> Self { + use crate::DeployHash; + + if rng.gen() { + Transfer::V1(TransferV1::new( + DeployHash::random(rng), + rng.gen(), + rng.gen(), + rng.gen(), + rng.gen(), + rng.gen(), + rng.gen(), + rng.gen(), + )) + } else { + Transfer::V2(TransferV2::new( + TransactionHash::random(rng), + InitiatorAddr::random(rng), + rng.gen(), + rng.gen(), + rng.gen(), + rng.gen(), + Gas::new(rng.gen::()), + rng.gen(), + )) + } + } } impl From for Transfer { @@ -137,17 +169,21 @@ impl FromBytes for Transfer { /// Proptest generators for [`Transfer`]. #[cfg(any(feature = "testing", feature = "gens", test))] pub mod gens { - use proptest::prelude::{prop::option, prop_oneof, Arbitrary, Strategy}; + use proptest::{ + array, + prelude::{prop::option, Arbitrary, Strategy}, + }; use super::*; use crate::{ - gens::{u512_arb, uref_arb}, - transaction_info::gens::{ - account_hash_arb, deploy_hash_arb, initiator_addr_arb, txn_hash_arb, - }, - Gas, Transfer, + gens::{account_hash_arb, u512_arb, uref_arb}, + transaction::gens::deploy_hash_arb, }; + pub fn transfer_v1_addr_arb() -> impl Strategy { + array::uniform32(::arbitrary()).prop_map(TransferV1Addr::new) + } + pub fn transfer_v1_arb() -> impl Strategy { ( deploy_hash_arb(), @@ -172,53 +208,19 @@ pub mod gens { } }) } - - pub fn transfer_v2_arb() -> impl Strategy { - ( - txn_hash_arb(), - initiator_addr_arb(), - option::of(account_hash_arb()), - uref_arb(), - uref_arb(), - u512_arb(), - u512_arb(), - option::of(::arbitrary()), - ) - .prop_map( - |(transaction_hash, from, to, source, target, amount, gas, id)| TransferV2 { - transaction_hash, - from, - to, - source, - target, - amount, - gas: Gas::new(gas), - id, - }, - ) - } - - /// Creates an arbitrary [`Transfer`] - pub fn transfer_arb() -> impl Strategy { - prop_oneof![ - transfer_v1_arb().prop_map(Transfer::V1), - transfer_v2_arb().prop_map(Transfer::V2) - ] - } } #[cfg(test)] mod tests { - use proptest::prelude::*; - use crate::bytesrepr; use super::*; - proptest! { - #[test] - fn bytesrepr_roundtrip(transfer in gens::transfer_arb()) { - bytesrepr::test_serialization_roundtrip(&transfer) - } + #[test] + fn bytesrepr_roundtrip() { + let rng = &mut TestRng::new(); + + let transfer = Transfer::random(rng); + bytesrepr::test_serialization_roundtrip(&transfer); } } diff --git a/types/src/transfer/transfer_addr.rs b/types/src/transfer/transfer_addr.rs deleted file mode 100644 index 1a0c03a497..0000000000 --- a/types/src/transfer/transfer_addr.rs +++ /dev/null @@ -1,254 +0,0 @@ -use alloc::{string::String, vec::Vec}; -use core::{ - convert::TryFrom, - fmt::{self, Display, Formatter}, -}; - -#[cfg(feature = "datasize")] -use datasize::DataSize; -#[cfg(any(feature = "testing", test))] -use rand::{ - distributions::{Distribution, Standard}, - Rng, -}; -#[cfg(feature = "json-schema")] -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use super::{ - transfer_v1::V1_PREFIX, transfer_v2::V2_PREFIX, TransferFromStrError, TransferV1Addr, - TransferV2Addr, TRANSFER_V1_ADDR_LENGTH, TRANSFER_V2_ADDR_LENGTH, -}; -#[cfg(any(feature = "testing", test))] -use crate::testing::TestRng; -use crate::{ - bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, - checksummed_hex, -}; - -pub(super) const TRANSFER_ADDR_FORMATTED_STRING_PREFIX: &str = "transfer-"; -const V1_TAG: u8 = 0; -const V2_TAG: u8 = 1; - -/// A versioned wrapper for a transfer address. -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize, Debug)] -#[cfg_attr(feature = "datasize", derive(DataSize))] -#[cfg_attr(feature = "json-schema", derive(JsonSchema))] -#[serde(deny_unknown_fields)] -pub enum TransferAddr { - /// A version 1 transfer address. - #[serde(rename = "Version1")] - V1(TransferV1Addr), - /// A version 2 transfer address. - #[serde(rename = "Version2")] - V2(TransferV2Addr), -} - -impl TransferAddr { - /// Formats the `TransferAddr` as a prefixed, hex-encoded string. - pub fn to_formatted_string(self) -> String { - match self { - TransferAddr::V1(addr) => addr.to_formatted_string(), - TransferAddr::V2(addr) => addr.to_formatted_string(), - } - } - - /// Parses a string formatted as per `Self::to_formatted_string()` into a `TransferAddr`. - pub fn from_formatted_str(input: &str) -> Result { - let v_remainder = input - .strip_prefix(TRANSFER_ADDR_FORMATTED_STRING_PREFIX) - .ok_or(TransferFromStrError::InvalidPrefix)?; - if let Some(v1_addr_hex) = v_remainder.strip_prefix(V1_PREFIX) { - let addr = <[u8; TRANSFER_V1_ADDR_LENGTH]>::try_from( - checksummed_hex::decode(v1_addr_hex)?.as_ref(), - )?; - Ok(TransferAddr::V1(TransferV1Addr::new(addr))) - } else if let Some(v2_addr_hex) = v_remainder.strip_prefix(V2_PREFIX) { - let addr = <[u8; TRANSFER_V2_ADDR_LENGTH]>::try_from( - checksummed_hex::decode(v2_addr_hex)?.as_ref(), - )?; - Ok(TransferAddr::V2(TransferV2Addr::new(addr))) - } else { - Err(TransferFromStrError::InvalidPrefix) - } - } - - /// Returns a random `TransferAddr`. - #[cfg(any(feature = "testing", test))] - pub fn random(rng: &mut TestRng) -> Self { - if rng.gen() { - TransferAddr::V1(TransferV1Addr::random(rng)) - } else { - TransferAddr::V2(TransferV2Addr::random(rng)) - } - } -} - -impl From for TransferAddr { - fn from(addr: TransferV1Addr) -> Self { - Self::V1(addr) - } -} - -impl From<&TransferV1Addr> for TransferAddr { - fn from(addr: &TransferV1Addr) -> Self { - Self::from(*addr) - } -} - -impl From for TransferAddr { - fn from(addr: TransferV2Addr) -> Self { - Self::V2(addr) - } -} - -impl From<&TransferV2Addr> for TransferAddr { - fn from(addr: &TransferV2Addr) -> Self { - Self::from(*addr) - } -} - -impl Display for TransferAddr { - fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { - match self { - TransferAddr::V1(addr) => Display::fmt(addr, formatter), - TransferAddr::V2(addr) => Display::fmt(addr, formatter), - } - } -} - -impl ToBytes for TransferAddr { - fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - match self { - TransferAddr::V1(addr) => { - V1_TAG.write_bytes(writer)?; - addr.write_bytes(writer) - } - TransferAddr::V2(addr) => { - V2_TAG.write_bytes(writer)?; - addr.write_bytes(writer) - } - } - } - - fn to_bytes(&self) -> Result, bytesrepr::Error> { - let mut buffer = bytesrepr::allocate_buffer(self)?; - self.write_bytes(&mut buffer)?; - Ok(buffer) - } - - fn serialized_length(&self) -> usize { - U8_SERIALIZED_LENGTH - + match self { - TransferAddr::V1(addr) => addr.serialized_length(), - TransferAddr::V2(addr) => addr.serialized_length(), - } - } -} - -impl FromBytes for TransferAddr { - fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (tag, remainder) = u8::from_bytes(bytes)?; - match tag { - V1_TAG => { - let (addr, remainder) = TransferV1Addr::from_bytes(remainder)?; - Ok((TransferAddr::V1(addr), remainder)) - } - V2_TAG => { - let (addr, remainder) = TransferV2Addr::from_bytes(remainder)?; - Ok((TransferAddr::V2(addr), remainder)) - } - _ => Err(bytesrepr::Error::Formatting), - } - } -} - -#[cfg(any(feature = "testing", test))] -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> TransferAddr { - if rng.gen() { - TransferAddr::V1(TransferV1Addr::new(rng.gen())) - } else { - TransferAddr::V2(TransferV2Addr::new(rng.gen())) - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::testing::TestRng; - - #[test] - fn transfer_addr_from_str() { - let transfer_v1_addr = TransferV1Addr::new([4; 32]); - let encoded = transfer_v1_addr.to_formatted_string(); - let decoded = TransferV1Addr::from_formatted_str(&encoded).unwrap(); - assert_eq!(transfer_v1_addr, decoded); - - let transfer_v2_addr = TransferV2Addr::new([4; 32]); - let encoded = transfer_v2_addr.to_formatted_string(); - let decoded = TransferV2Addr::from_formatted_str(&encoded).unwrap(); - assert_eq!(transfer_v2_addr, decoded); - - let invalid_prefix = - "transfer-v-0000000000000000000000000000000000000000000000000000000000000000"; - assert!(matches!( - TransferV2Addr::from_formatted_str(invalid_prefix), - Err(TransferFromStrError::InvalidPrefix) - )); - - let invalid_prefix = - "transfer-v20000000000000000000000000000000000000000000000000000000000000000"; - assert!(matches!( - TransferV2Addr::from_formatted_str(invalid_prefix), - Err(TransferFromStrError::InvalidPrefix) - )); - - let short_addr = - "transfer-v2-00000000000000000000000000000000000000000000000000000000000000"; - assert!(matches!( - TransferV2Addr::from_formatted_str(short_addr), - Err(TransferFromStrError::Length(_)) - )); - - let long_addr = - "transfer-v2-000000000000000000000000000000000000000000000000000000000000000000"; - assert!(matches!( - TransferV2Addr::from_formatted_str(long_addr), - Err(TransferFromStrError::Length(_)) - )); - - let invalid_hex = - "transfer-v2-000000000000000000000000000000000000000000000000000000000000000g"; - assert!(matches!( - TransferV2Addr::from_formatted_str(invalid_hex), - Err(TransferFromStrError::Hex(_)) - )); - } - - #[test] - fn bytesrepr_roundtrip() { - let rng = &mut TestRng::new(); - let addr = TransferAddr::random(rng); - bytesrepr::test_serialization_roundtrip(&addr); - } - - #[test] - fn bincode_roundtrip() { - let rng = &mut TestRng::new(); - let addr = TransferAddr::random(rng); - let serialized = bincode::serialize(&addr).unwrap(); - let decoded = bincode::deserialize(&serialized).unwrap(); - assert_eq!(addr, decoded); - } - - #[test] - fn json_roundtrip() { - let rng = &mut TestRng::new(); - let addr = TransferAddr::random(rng); - let json_string = serde_json::to_string_pretty(&addr).unwrap(); - let decoded = serde_json::from_str(&json_string).unwrap(); - assert_eq!(addr, decoded); - } -} diff --git a/types/src/transfer/transfer_v1.rs b/types/src/transfer/transfer_v1.rs index e161e49f67..b1b00a9949 100644 --- a/types/src/transfer/transfer_v1.rs +++ b/types/src/transfer/transfer_v1.rs @@ -13,7 +13,6 @@ use crate::{ bytesrepr::{self, FromBytes, ToBytes}, serde_helpers, DeployHash, URef, U512, }; -pub(super) use transfer_v1_addr::V1_PREFIX; pub use transfer_v1_addr::{TransferV1Addr, TRANSFER_V1_ADDR_LENGTH}; /// Represents a version 1 transfer from one purse to another. diff --git a/types/src/transfer/transfer_v1/transfer_v1_addr.rs b/types/src/transfer/transfer_v1/transfer_v1_addr.rs index 018be413e2..981321c9ae 100644 --- a/types/src/transfer/transfer_v1/transfer_v1_addr.rs +++ b/types/src/transfer/transfer_v1/transfer_v1_addr.rs @@ -12,7 +12,8 @@ use rand::Rng; use schemars::JsonSchema; use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer}; -use super::super::{transfer_addr::TRANSFER_ADDR_FORMATTED_STRING_PREFIX, TransferFromStrError}; +use super::super::TransferFromStrError; +pub(super) const TRANSFER_ADDR_FORMATTED_STRING_PREFIX: &str = "transfer-"; #[cfg(any(feature = "testing", test))] use crate::testing::TestRng; use crate::{ diff --git a/types/src/transfer/transfer_v2.rs b/types/src/transfer/transfer_v2.rs index 9333871b65..c3ff440f8f 100644 --- a/types/src/transfer/transfer_v2.rs +++ b/types/src/transfer/transfer_v2.rs @@ -1,5 +1,3 @@ -mod transfer_v2_addr; - use alloc::vec::Vec; #[cfg(feature = "datasize")] @@ -13,8 +11,6 @@ use crate::{ bytesrepr::{self, FromBytes, ToBytes}, Gas, InitiatorAddr, TransactionHash, URef, U512, }; -pub(super) use transfer_v2_addr::V2_PREFIX; -pub use transfer_v2_addr::{TransferV2Addr, TRANSFER_V2_ADDR_LENGTH}; /// Represents a version 2 transfer from one purse to another. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Debug)] diff --git a/types/src/transfer/transfer_v2/transfer_v2_addr.rs b/types/src/transfer/transfer_v2/transfer_v2_addr.rs deleted file mode 100644 index a35aa27de0..0000000000 --- a/types/src/transfer/transfer_v2/transfer_v2_addr.rs +++ /dev/null @@ -1,225 +0,0 @@ -use alloc::{format, string::String, vec::Vec}; -use core::{ - convert::TryFrom, - fmt::{self, Debug, Display, Formatter}, -}; - -#[cfg(feature = "datasize")] -use datasize::DataSize; -#[cfg(any(feature = "testing", test))] -use rand::Rng; -#[cfg(feature = "json-schema")] -use schemars::JsonSchema; -use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer}; - -use super::super::{transfer_addr::TRANSFER_ADDR_FORMATTED_STRING_PREFIX, TransferFromStrError}; -#[cfg(any(feature = "testing", test))] -use crate::testing::TestRng; -use crate::{ - bytesrepr::{self, FromBytes, ToBytes}, - checksummed_hex, CLType, CLTyped, -}; - -/// The length of a version 2 transfer address. -pub const TRANSFER_V2_ADDR_LENGTH: usize = 32; -pub(in crate::transfer) const V2_PREFIX: &str = "v2-"; - -/// A newtype wrapping a [u8; [TRANSFER_V2_ADDR_LENGTH]] which is the raw bytes of the -/// transfer address. -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Default)] -#[cfg_attr(feature = "datasize", derive(DataSize))] -#[cfg_attr( - feature = "json-schema", - derive(JsonSchema), - schemars(description = "Hex-encoded version 2 transfer address.") -)] -pub struct TransferV2Addr( - #[cfg_attr(feature = "json-schema", schemars(skip, with = "String"))] - [u8; TRANSFER_V2_ADDR_LENGTH], -); - -impl TransferV2Addr { - /// Constructs a new `TransferV2Addr` instance from the raw bytes. - pub const fn new(value: [u8; TRANSFER_V2_ADDR_LENGTH]) -> TransferV2Addr { - TransferV2Addr(value) - } - - /// Returns the raw bytes of the transfer address as an array. - pub fn value(&self) -> [u8; TRANSFER_V2_ADDR_LENGTH] { - self.0 - } - - /// Returns the raw bytes of the transfer address as a `slice`. - pub fn as_bytes(&self) -> &[u8] { - &self.0 - } - - /// Formats the `TransferV2Addr` as a prefixed, hex-encoded string. - pub fn to_formatted_string(self) -> String { - format!( - "{}{}{}", - TRANSFER_ADDR_FORMATTED_STRING_PREFIX, - V2_PREFIX, - base16::encode_lower(&self.0), - ) - } - - /// Parses a string formatted as per `Self::to_formatted_string()` into a `TransferV2Addr`. - pub fn from_formatted_str(input: &str) -> Result { - let v2_remainder = input - .strip_prefix(TRANSFER_ADDR_FORMATTED_STRING_PREFIX) - .ok_or(TransferFromStrError::InvalidPrefix)?; - let remainder = v2_remainder - .strip_prefix(V2_PREFIX) - .ok_or(TransferFromStrError::InvalidPrefix)?; - let bytes = <[u8; TRANSFER_V2_ADDR_LENGTH]>::try_from( - checksummed_hex::decode(remainder)?.as_ref(), - )?; - Ok(TransferV2Addr(bytes)) - } - - /// Returns a random `TransferV2Addr`. - #[cfg(any(feature = "testing", test))] - pub fn random(rng: &mut TestRng) -> Self { - TransferV2Addr(rng.gen()) - } -} - -impl Serialize for TransferV2Addr { - fn serialize(&self, serializer: S) -> Result { - if serializer.is_human_readable() { - self.to_formatted_string().serialize(serializer) - } else { - self.0.serialize(serializer) - } - } -} - -impl<'de> Deserialize<'de> for TransferV2Addr { - fn deserialize>(deserializer: D) -> Result { - if deserializer.is_human_readable() { - let formatted_string = String::deserialize(deserializer)?; - TransferV2Addr::from_formatted_str(&formatted_string).map_err(SerdeError::custom) - } else { - let bytes = <[u8; TRANSFER_V2_ADDR_LENGTH]>::deserialize(deserializer)?; - Ok(TransferV2Addr(bytes)) - } - } -} - -impl Display for TransferV2Addr { - fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { - write!(formatter, "{}", base16::encode_lower(&self.0)) - } -} - -impl Debug for TransferV2Addr { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "TransferV2Addr({})", base16::encode_lower(&self.0)) - } -} - -impl CLTyped for TransferV2Addr { - fn cl_type() -> CLType { - CLType::ByteArray(TRANSFER_V2_ADDR_LENGTH as u32) - } -} - -impl ToBytes for TransferV2Addr { - #[inline(always)] - fn to_bytes(&self) -> Result, bytesrepr::Error> { - self.0.to_bytes() - } - - #[inline(always)] - fn serialized_length(&self) -> usize { - self.0.serialized_length() - } - - #[inline(always)] - fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - self.0.write_bytes(writer) - } -} - -impl FromBytes for TransferV2Addr { - fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (bytes, remainder) = <[u8; TRANSFER_V2_ADDR_LENGTH]>::from_bytes(bytes)?; - Ok((TransferV2Addr(bytes), remainder)) - } -} - -#[cfg(test)] -mod tests { - use crate::{bytesrepr, testing::TestRng}; - - use super::*; - - #[test] - fn transfer_addr_from_str() { - let transfer_address = TransferV2Addr([4; 32]); - let encoded = transfer_address.to_formatted_string(); - let decoded = TransferV2Addr::from_formatted_str(&encoded).unwrap(); - assert_eq!(transfer_address, decoded); - - let invalid_prefix = - "transfer-v-0000000000000000000000000000000000000000000000000000000000000000"; - assert!(matches!( - TransferV2Addr::from_formatted_str(invalid_prefix), - Err(TransferFromStrError::InvalidPrefix) - )); - - let invalid_prefix = - "transfer-v20000000000000000000000000000000000000000000000000000000000000000"; - assert!(matches!( - TransferV2Addr::from_formatted_str(invalid_prefix), - Err(TransferFromStrError::InvalidPrefix) - )); - - let short_addr = - "transfer-v2-00000000000000000000000000000000000000000000000000000000000000"; - assert!(matches!( - TransferV2Addr::from_formatted_str(short_addr), - Err(TransferFromStrError::Length(_)) - )); - - let long_addr = - "transfer-v2-000000000000000000000000000000000000000000000000000000000000000000"; - assert!(matches!( - TransferV2Addr::from_formatted_str(long_addr), - Err(TransferFromStrError::Length(_)) - )); - - let invalid_hex = - "transfer-v2-000000000000000000000000000000000000000000000000000000000000000g"; - assert!(matches!( - TransferV2Addr::from_formatted_str(invalid_hex), - Err(TransferFromStrError::Hex(_)) - )); - } - - #[test] - fn bytesrepr_roundtrip() { - let rng = &mut TestRng::new(); - let transfer_address = TransferV2Addr::random(rng); - bytesrepr::test_serialization_roundtrip(&transfer_address) - } - - #[test] - fn bincode_roundtrip() { - let rng = &mut TestRng::new(); - let transfer_address = TransferV2Addr::random(rng); - let serialized = bincode::serialize(&transfer_address).unwrap(); - let decoded = bincode::deserialize(&serialized).unwrap(); - assert_eq!(transfer_address, decoded); - } - - #[test] - fn json_roundtrip() { - let rng = &mut TestRng::new(); - let transfer_address = TransferV2Addr::random(rng); - let json_string = serde_json::to_string_pretty(&transfer_address).unwrap(); - let decoded = serde_json::from_str(&json_string).unwrap(); - assert_eq!(transfer_address, decoded); - } -} diff --git a/utils/validation/src/generators.rs b/utils/validation/src/generators.rs index 721f6b4b54..13a3f911ea 100644 --- a/utils/validation/src/generators.rs +++ b/utils/validation/src/generators.rs @@ -20,10 +20,9 @@ use casper_types::{ }, AccessRights, AddressableEntityHash, BlockTime, ByteCode, ByteCodeHash, ByteCodeKind, CLType, CLTyped, CLValue, DeployHash, DeployInfo, EntityVersionKey, EntityVersions, EntryPoint, - EntryPointAccess, EntryPointType, EntryPoints, EraId, Gas, Group, Groups, InitiatorAddr, Key, - Package, PackageHash, PackageStatus, Parameter, ProtocolVersion, PublicKey, SecretKey, - StoredValue, TransactionHash, TransactionV1Hash, Transfer, TransferV1, TransferV1Addr, - TransferV2, URef, U512, + EntryPointAccess, EntryPointType, EntryPoints, EraId, Group, Groups, Key, Package, PackageHash, + PackageStatus, Parameter, ProtocolVersion, PublicKey, SecretKey, StoredValue, TransferV1, + TransferV1Addr, URef, U512, }; use casper_validation::{ abi::{ABIFixture, ABITestCase}, @@ -80,16 +79,6 @@ pub fn make_abi_test_fixtures() -> Result { U512::from(2_500_000_000u64), Some(1), ); - let transfer = Transfer::V2(TransferV2::new( - TransactionHash::V1(TransactionV1Hash::from_raw([44; 32])), - InitiatorAddr::AccountHash(AccountHash::new([100; 32])), - Some(AccountHash::new([101; 32])), - URef::new([10; 32], AccessRights::WRITE), - URef::new([11; 32], AccessRights::WRITE), - U512::from(15_000_000_000u64), - Gas::new(2_500_000_000u64), - Some(1), - )); let deploy_info = DeployInfo::new( DeployHash::from_raw([55; 32]), &[TransferV1Addr::new([1; 32]), TransferV1Addr::new([2; 32])], @@ -473,10 +462,6 @@ pub fn make_abi_test_fixtures() -> Result { ]) .into()])?, ); - stored_value.insert( - "Transfer".to_string(), - ABITestCase::from_inputs(vec![StoredValue::Transfer(transfer).into()])?, - ); Fixture::ABI { name: "stored_value".to_string(), From ebf32d7a1a9210e139ca426bce5dafb310fcee52 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Fri, 22 Mar 2024 12:01:14 -0700 Subject: [PATCH 30/70] tweaking execution artifact builder --- .../components/contract_runtime/operations.rs | 40 +++----- node/src/components/contract_runtime/types.rs | 93 +++++++------------ 2 files changed, 47 insertions(+), 86 deletions(-) diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index f2d0111344..d861c8e1ba 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -147,11 +147,9 @@ pub fn execute_finalized_block( WasmV1Result::invalid_executable_item(custom_payment_gas_limit, error) } }; - artifact_builder.with_wasm_v1_result(pay_result); - if artifact_builder.root_not_found() { - artifacts.push(artifact_builder.build()); - return Err(BlockExecutionError::RootNotFound(state_root_hash)); - } + artifact_builder + .with_wasm_v1_result(pay_result) + .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; BalanceIdentifier::Payment } else { initiator_addr.clone().into() @@ -181,11 +179,9 @@ pub fn execute_finalized_block( runtime_args, cost, )); - artifact_builder.with_transfer_result(transfer_result); - if artifact_builder.root_not_found() { - artifacts.push(artifact_builder.build()); - return Err(BlockExecutionError::RootNotFound(state_root_hash)); - } + artifact_builder + .with_transfer_result(transfer_result) + .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; } TransactionCategory::Auction => { match AuctionMethod::from_parts( @@ -205,11 +201,9 @@ pub fn execute_finalized_block( authorization_keys, auction_method, )); - artifact_builder.with_bidding_result(bidding_result); - if artifact_builder.root_not_found() { - artifacts.push(artifact_builder.build()); - return Err(BlockExecutionError::RootNotFound(state_root_hash)); - } + artifact_builder + .with_bidding_result(bidding_result) + .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; } Err(ame) => { error!( @@ -233,11 +227,9 @@ pub fn execute_finalized_block( let wasm_v1_result = execution_engine_v1.execute(&scratch_state, wasm_v1_request); trace!(%transaction_hash, ?category, ?wasm_v1_result, "able to get wasm v1 result"); - artifact_builder.with_wasm_v1_result(wasm_v1_result); - if artifact_builder.root_not_found() { - artifacts.push(artifact_builder.build()); - return Err(BlockExecutionError::RootNotFound(state_root_hash)); - } + artifact_builder + .with_wasm_v1_result(wasm_v1_result) + .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; } Err(ire) => { debug!(%transaction_hash, ?category, ?ire, "unable to get wasm v1 request"); @@ -267,11 +259,9 @@ pub fn execute_finalized_block( chainspec.core_config.balance_hold_interval, insufficient_balance_handling, )); - artifact_builder.with_balance_hold_result(&hold_result); - if artifact_builder.root_not_found() { - artifacts.push(artifact_builder.build()); - return Err(BlockExecutionError::RootNotFound(state_root_hash)); - } + artifact_builder + .with_balance_hold_result(&hold_result) + .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; } FeeHandling::PayToProposer => { // this is the current mainnet mechanism...pay up front diff --git a/node/src/components/contract_runtime/types.rs b/node/src/components/contract_runtime/types.rs index ea43c05436..93fc7d74c8 100644 --- a/node/src/components/contract_runtime/types.rs +++ b/node/src/components/contract_runtime/types.rs @@ -14,9 +14,9 @@ use casper_storage::{ use casper_types::{ contract_messages::Messages, execution::{Effects, ExecutionResult, ExecutionResultV2}, - BlockHash, BlockHeaderV2, BlockV2, DeployHash, DeployHeader, Digest, EraId, Gas, InvalidDeploy, - InvalidTransaction, InvalidTransactionV1, ProtocolVersion, PublicKey, Transaction, - TransactionHash, TransactionHeader, TransactionV1Hash, TransactionV1Header, TransferAddr, U512, + BlockHash, BlockHeaderV2, BlockV2, Digest, EraId, Gas, InvalidDeploy, InvalidTransaction, + InvalidTransactionV1, ProtocolVersion, PublicKey, Transaction, TransactionHash, + TransactionHeader, TransferAddr, U512, }; /// Request for validator weights for a specific era. @@ -68,14 +68,13 @@ pub(crate) struct ExecutionArtifactBuilder { messages: Messages, transfers: Vec, gas: Gas, - root_not_found: bool, } impl ExecutionArtifactBuilder { pub fn new(transaction: &Transaction) -> Self { let effects = Effects::new(); let hash = transaction.hash(); - let header = transaction.header().clone(); + let header = transaction.header(); ExecutionArtifactBuilder { effects, hash, @@ -84,7 +83,6 @@ impl ExecutionArtifactBuilder { transfers: vec![], messages: Default::default(), gas: Gas::zero(), - root_not_found: false, } } @@ -92,10 +90,6 @@ impl ExecutionArtifactBuilder { self.effects.clone() } - pub(crate) fn root_not_found(&self) -> bool { - self.root_not_found - } - pub fn with_appended_transfers(&mut self, transfers: &mut Vec) -> &mut Self { self.transfers.append(transfers); self @@ -111,26 +105,31 @@ impl ExecutionArtifactBuilder { self } - pub fn with_wasm_v1_result(&mut self, wasm_v1_result: WasmV1Result) -> &mut Self { + pub fn with_wasm_v1_result(&mut self, wasm_v1_result: WasmV1Result) -> Result<&mut Self, ()> { if let Some(Error::RootNotFound(_)) = wasm_v1_result.error() { - self.root_not_found = true; + return Err(()); } if let (None, Some(err)) = (&self.error_message, wasm_v1_result.error()) { self.error_message = Some(format!("{}", err)); } self.with_appended_messages(&mut wasm_v1_result.messages().clone()) .with_appended_transfers(&mut wasm_v1_result.transfers().clone()) - .with_appended_effects(wasm_v1_result.effects().clone()) + .with_appended_effects(wasm_v1_result.effects().clone()); + Ok(self) } - pub fn with_balance_hold_result(&mut self, hold_result: &BalanceHoldResult) -> &mut Self { + pub fn with_balance_hold_result( + &mut self, + hold_result: &BalanceHoldResult, + ) -> Result<&mut Self, ()> { if let BalanceHoldResult::RootNotFound = hold_result { - self.root_not_found = true; + return Err(()); } if let (None, BalanceHoldResult::Failure(err)) = (&self.error_message, hold_result) { self.error_message = Some(format!("{}", err)); } - self.with_appended_effects(hold_result.effects().clone()) + self.with_appended_effects(hold_result.effects()); + Ok(self) } pub fn with_added_gas(&mut self, gas: Gas) -> &mut Self { @@ -168,36 +167,38 @@ impl ExecutionArtifactBuilder { self } - pub fn with_transfer_result(&mut self, transfer_result: TransferResult) -> &mut Self { + pub fn with_transfer_result( + &mut self, + transfer_result: TransferResult, + ) -> Result<&mut Self, ()> { if let TransferResult::RootNotFound = transfer_result { - self.root_not_found = true; - return self; + return Err(()); } if let (None, TransferResult::Failure(err)) = (&self.error_message, &transfer_result) { self.error_message = Some(format!("{}", err)); - return self; } - if let TransferResult::Success { transfers, effects } = transfer_result { - return self - .with_appended_transfers(&mut transfers.clone()) - .with_appended_effects(effects.clone()); + if let TransferResult::Success { + mut transfers, + effects, + } = transfer_result + { + self.with_appended_transfers(&mut transfers) + .with_appended_effects(effects); } - self + Ok(self) } - pub fn with_bidding_result(&mut self, bidding_result: BiddingResult) -> &mut Self { + pub fn with_bidding_result(&mut self, bidding_result: BiddingResult) -> Result<&mut Self, ()> { if let BiddingResult::RootNotFound = bidding_result { - self.root_not_found = true; - return self; + return Err(()); } if let (None, BiddingResult::Failure(err)) = (&self.error_message, &bidding_result) { self.error_message = Some(format!("{}", err)); - return self; } if let BiddingResult::Success { effects, .. } = bidding_result { - return self.with_appended_effects(effects.clone()); + self.with_appended_effects(effects); } - self + Ok(self) } pub(crate) fn build(self) -> ExecutionArtifact { @@ -253,36 +254,6 @@ impl ExecutionArtifact { messages, } } - - #[allow(unused)] - pub(crate) fn deploy( - deploy_hash: DeployHash, - header: DeployHeader, - execution_result: ExecutionResult, - messages: Messages, - ) -> Self { - Self { - transaction_hash: TransactionHash::Deploy(deploy_hash), - transaction_header: TransactionHeader::Deploy(header), - execution_result, - messages, - } - } - - #[allow(unused)] - pub(crate) fn v1( - transaction_hash: TransactionV1Hash, - header: TransactionV1Header, - execution_result: ExecutionResult, - messages: Messages, - ) -> Self { - Self { - transaction_hash: TransactionHash::V1(transaction_hash), - transaction_header: TransactionHeader::V1(header), - execution_result, - messages, - } - } } #[doc(hidden)] From 846b23ee602fafc378a55027c560746c1ededed5 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Fri, 22 Mar 2024 13:03:46 -0700 Subject: [PATCH 31/70] merging Sardan commit --- node/src/components/contract_runtime/types.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/node/src/components/contract_runtime/types.rs b/node/src/components/contract_runtime/types.rs index 8687f5957e..9620a32e13 100644 --- a/node/src/components/contract_runtime/types.rs +++ b/node/src/components/contract_runtime/types.rs @@ -17,9 +17,9 @@ use casper_storage::{ use casper_types::{ contract_messages::Messages, execution::{Effects, ExecutionResult, ExecutionResultV2}, - BlockHash, BlockHeaderV2, BlockV2, DeployHash, DeployHeader, Digest, EraId, Gas, InvalidDeploy, - InvalidTransaction, InvalidTransactionV1, ProtocolVersion, PublicKey, Transaction, - TransactionHash, TransactionHeader, TransactionV1Hash, TransactionV1Header, U512, + BlockHash, BlockHeaderV2, BlockV2, Digest, EraId, Gas, InvalidDeploy, InvalidTransaction, + InvalidTransactionV1, ProtocolVersion, PublicKey, Transaction, TransactionHash, + TransactionHeader, U512, }; /// Request for validator weights for a specific era. From 0bdfd4804e82494f743585634072c990cd5e9b4a Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Fri, 22 Mar 2024 14:03:51 -0700 Subject: [PATCH 32/70] restoring bidding permission enforcement (had temporarily disabled waiting on other changes) --- .../components/contract_runtime/operations.rs | 1 - storage/src/data_access_layer/bidding.rs | 8 ++--- storage/src/global_state/state/mod.rs | 34 ++++++++++++++----- storage/src/system/runtime_native.rs | 2 +- 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 645bc9b257..8fca35508c 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -194,7 +194,6 @@ pub fn execute_finalized_block( let bidding_result = scratch_state.bidding(BiddingRequest::new( native_runtime_config.clone(), state_root_hash, - block_time, protocol_version, transaction_hash, initiator_addr, diff --git a/storage/src/data_access_layer/bidding.rs b/storage/src/data_access_layer/bidding.rs index b9fc16e3b8..226c9321af 100644 --- a/storage/src/data_access_layer/bidding.rs +++ b/storage/src/data_access_layer/bidding.rs @@ -9,8 +9,8 @@ use casper_types::{ bytesrepr::FromBytes, execution::Effects, system::{auction, auction::DelegationRate}, - BlockTime, CLTyped, CLValue, CLValueError, Chainspec, Digest, InitiatorAddr, ProtocolVersion, - PublicKey, RuntimeArgs, TransactionEntryPoint, TransactionHash, U512, + CLTyped, CLValue, CLValueError, Chainspec, Digest, InitiatorAddr, ProtocolVersion, PublicKey, + RuntimeArgs, TransactionEntryPoint, TransactionHash, U512, }; use crate::{ @@ -197,8 +197,6 @@ pub struct BiddingRequest { pub(crate) config: NativeRuntimeConfig, /// State root hash. pub(crate) state_hash: Digest, - /// Block time represented as a unix timestamp. - pub(crate) block_time: BlockTime, /// The protocol version. pub(crate) protocol_version: ProtocolVersion, /// The auction method. @@ -217,7 +215,6 @@ impl BiddingRequest { pub fn new( config: NativeRuntimeConfig, state_hash: Digest, - block_time: BlockTime, protocol_version: ProtocolVersion, transaction_hash: TransactionHash, initiator: InitiatorAddr, @@ -227,7 +224,6 @@ impl BiddingRequest { Self { config, state_hash, - block_time, protocol_version, transaction_hash, initiator, diff --git a/storage/src/global_state/state/mod.rs b/storage/src/global_state/state/mod.rs index 6402442216..68a1a96fb5 100644 --- a/storage/src/global_state/state/mod.rs +++ b/storage/src/global_state/state/mod.rs @@ -902,7 +902,8 @@ pub trait StateProvider { protocol_version, auction_method, transaction_hash, - .. + initiator, + authorization_keys, }: BiddingRequest, ) -> BiddingResult { let tc = match self.tracking_copy(state_hash) { @@ -911,18 +912,33 @@ pub trait StateProvider { Err(err) => return BiddingResult::Failure(TrackingCopyError::Storage(err)), }; - let mut runtime = match RuntimeNative::new_system_runtime( + let source_account_hash = initiator.account_hash(); + let (entity, entity_named_keys, entity_access_rights) = + match tc.borrow_mut().resolved_entity( + protocol_version, + source_account_hash, + &authorization_keys, + &BTreeSet::default(), + ) { + Ok(ret) => ret, + Err(tce) => { + return BiddingResult::Failure(tce); + } + }; + + // IMPORTANT: this runtime _must_ use the payer's context. + let mut runtime = RuntimeNative::new( config, protocol_version, Id::Transaction(transaction_hash), Rc::clone(&tc), + source_account_hash, + entity, + entity_named_keys, + entity_access_rights, + U512::MAX, Phase::Session, - ) { - Ok(rt) => rt, - Err(tce) => { - return BiddingResult::Failure(tce); - } - }; + ); let result = match auction_method { AuctionMethod::ActivateBid { validator } => runtime @@ -1380,8 +1396,8 @@ pub trait StateProvider { let id = Id::Transaction(request.transaction_hash()); // IMPORTANT: this runtime _must_ use the payer's context. let mut runtime = RuntimeNative::new( - protocol_version, config.clone(), + protocol_version, id, Rc::clone(&tc), source_account_hash, diff --git a/storage/src/system/runtime_native.rs b/storage/src/system/runtime_native.rs index ddeacc6be6..b0fd3c1a66 100644 --- a/storage/src/system/runtime_native.rs +++ b/storage/src/system/runtime_native.rs @@ -249,8 +249,8 @@ where { #[allow(clippy::too_many_arguments)] pub fn new( - protocol_version: ProtocolVersion, config: Config, + protocol_version: ProtocolVersion, id: Id, tracking_copy: Rc>>, address: AccountHash, From 213693ba53eaea292f842887a10635159e87d0bf Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Sun, 24 Mar 2024 18:16:25 -0700 Subject: [PATCH 33/70] wip --- .../src/engine_state/engine_config.rs | 2 +- .../src/engine_state/execution_kind.rs | 3 + execution_engine/src/engine_state/wasm_v1.rs | 100 ++-- .../src/runtime/handle_payment_internal.rs | 16 +- execution_engine/src/runtime/mod.rs | 27 +- .../src/transfer_request_builder.rs | 1 - .../test_support/src/wasm_test_builder.rs | 12 +- .../system_contracts/auction/distribute.rs | 3 - .../tests/src/test/system_costs.rs | 10 +- .../components/contract_runtime/operations.rs | 243 +++++--- node/src/components/contract_runtime/types.rs | 57 +- .../components/event_stream_server/tests.rs | 6 +- node/src/components/storage/tests.rs | 11 +- .../components/transaction_acceptor/tests.rs | 13 +- node/src/reactor/main_reactor/tests.rs | 2 +- resources/local/chainspec.toml.in | 3 +- resources/production/chainspec.toml | 3 +- resources/test/sse_data_schema.json | 332 ++++++----- storage/src/data_access_layer.rs | 12 +- .../{bidding.rs => auction.rs} | 4 +- storage/src/data_access_layer/balance.rs | 82 ++- .../src/data_access_layer/handle_payment.rs | 139 +++++ .../{transfer.rs => mint.rs} | 15 +- storage/src/global_state/state/mod.rs | 102 +++- storage/src/system/handle_payment.rs | 37 +- .../handle_payment/handle_payment_native.rs | 224 ++++++++ storage/src/system/handle_payment/internal.rs | 539 +++++++++++------- .../system/handle_payment/mint_provider.rs | 6 + .../system/handle_payment/runtime_provider.rs | 8 +- storage/src/system/runtime_native.rs | 10 +- types/src/chainspec/core_config.rs | 15 +- types/src/chainspec/fee_handling.rs | 17 +- types/src/chainspec/refund_handling.rs | 36 +- types/src/execution/execution_result_v2.rs | 98 ++-- types/src/gas.rs | 5 + types/src/system/handle_payment/constants.rs | 4 - .../src/system/handle_payment/entry_points.rs | 26 +- types/src/system/handle_payment/error.rs | 12 + types/src/transaction.rs | 8 + types/src/transaction/deploy.rs | 6 + types/src/transaction/transaction_v1.rs | 6 + 41 files changed, 1564 insertions(+), 691 deletions(-) rename storage/src/data_access_layer/{bidding.rs => auction.rs} (99%) create mode 100644 storage/src/data_access_layer/handle_payment.rs rename storage/src/data_access_layer/{transfer.rs => mint.rs} (93%) create mode 100644 storage/src/system/handle_payment/handle_payment_native.rs diff --git a/execution_engine/src/engine_state/engine_config.rs b/execution_engine/src/engine_state/engine_config.rs index 7fec7ecb52..19c45588a3 100644 --- a/execution_engine/src/engine_state/engine_config.rs +++ b/execution_engine/src/engine_state/engine_config.rs @@ -330,7 +330,7 @@ impl EngineConfigBuilder { "refund ratio should be in the range of [0, 1]" ); } - RefundHandling::None => { + RefundHandling::NoRefund => { //noop } } diff --git a/execution_engine/src/engine_state/execution_kind.rs b/execution_engine/src/engine_state/execution_kind.rs index fe0af6dca5..5b9d21e818 100644 --- a/execution_engine/src/engine_state/execution_kind.rs +++ b/execution_engine/src/engine_state/execution_kind.rs @@ -76,6 +76,9 @@ impl<'a> ExecutionKind<'a> { ExecutableItem::DeploySessionModuleBytes(module_bytes) => { Ok(ExecutionKind::Deploy(module_bytes)) } + ExecutableItem::StandardPayment => Err(Error::Deprecated( + "standard payment is no longer handled by the execution engine".to_string(), + )), } } diff --git a/execution_engine/src/engine_state/wasm_v1.rs b/execution_engine/src/engine_state/wasm_v1.rs index 7ae9ba19cc..39a87d6e3c 100644 --- a/execution_engine/src/engine_state/wasm_v1.rs +++ b/execution_engine/src/engine_state/wasm_v1.rs @@ -9,7 +9,7 @@ use casper_types::{ runtime_args, system::mint::ARG_AMOUNT, BlockTime, DeployHash, Digest, ExecutableDeployItem, Gas, InitiatorAddr, Phase, PricingMode, RuntimeArgs, Transaction, TransactionEntryPoint, TransactionHash, TransactionInvocationTarget, TransactionSessionKind, TransactionTarget, - TransactionV1, TransactionV1Hash, Transfer, U512, + TransactionV1, Transfer, U512, }; use crate::engine_state::{DeployItem, Error as EngineError, ExecutionResult}; @@ -17,29 +17,23 @@ use crate::engine_state::{DeployItem, Error as EngineError, ExecutionResult}; const DEFAULT_ENTRY_POINT: &str = "call"; /// Error returned if constructing a new [`WasmV1Request`] fails. -#[derive(Copy, Clone, Eq, PartialEq, Error, Serialize, Debug)] +#[derive(Clone, Eq, PartialEq, Error, Serialize, Debug)] pub enum InvalidRequest { - /// The module bytes for custom payment must not be empty. - #[error("empty module bytes for custom payment in deploy {0}")] - EmptyCustomPaymentBytes(DeployHash), - /// The executable deploy item for custom payment must be the module bytes variant. - #[error("can only use module bytes for custom payment in deploy {0}")] - InvalidPaymentDeployItem(DeployHash), - /// The transaction v1 pricing mode must be the classic variant with `standard_payment` false. - #[error( - "can only use classic variant with `standard_payment` false for pricing mode in \ - transaction v1 {0}" - )] - InvalidPricingMode(TransactionV1Hash), - /// The executable deploy item for session cannot be the transfer variant. - #[error("cannot use transfer variant for session in deploy {0}")] - InvalidSessionDeployItem(DeployHash), - /// The transaction v1 target for session cannot be the native variant. - #[error("cannot use native variant for session target in transaction v1 {0}")] - InvalidSessionV1Target(TransactionV1Hash), - /// The transaction v1 entry point for session cannot be one of the native variants. - #[error("cannot use native variant for session entry point in transaction v1 {0}")] - InvalidSessionV1EntryPoint(TransactionV1Hash), + /// Missing custom payment. + #[error("custom payment not found for {0}")] + CustomPaymentNotFound(TransactionHash), + /// Unexpected variant. + #[error("unexpected variant for {0} attempting {1}")] + UnexpectedVariant(TransactionHash, String), + /// Unsupported mode. + #[error("unsupported mode for {0} attempting {1}")] + UnsupportedMode(TransactionHash, String), + /// Invalid entry point. + #[error("invalid entry point for {0} attempting {1}")] + InvalidEntryPoint(TransactionHash, String), + /// Invalid target. + #[error("invalid target for {0} attempting {1}")] + InvalidTarget(TransactionHash, String), } /// The item to be executed. @@ -58,6 +52,8 @@ pub enum ExecutableItem<'a> { DeploySessionModuleBytes(&'a Bytes), /// Module bytes to be used as custom payment. CustomPayment(&'a Bytes), + /// Standard payment. + StandardPayment, } impl<'a> ExecutableItem<'a> { @@ -66,7 +62,7 @@ impl<'a> ExecutableItem<'a> { ExecutableItem::Stored(_) | ExecutableItem::SessionModuleBytes { .. } | ExecutableItem::DeploySessionModuleBytes(_) => Phase::Session, - ExecutableItem::CustomPayment(_) => Phase::Payment, + ExecutableItem::CustomPayment(_) | ExecutableItem::StandardPayment => Phase::Payment, } } } @@ -384,6 +380,7 @@ impl<'a> TryFrom<(&'a ExecutableDeployItem, &'a DeployHash)> for SessionInfo<'a> fn try_from( (session_item, deploy_hash): (&'a ExecutableDeployItem, &'a DeployHash), ) -> Result { + let transaction_hash = TransactionHash::Deploy(*deploy_hash); let session: ExecutableItem<'a>; let session_entry_point: String; let session_args: RuntimeArgs; @@ -441,7 +438,10 @@ impl<'a> TryFrom<(&'a ExecutableDeployItem, &'a DeployHash)> for SessionInfo<'a> session_args = args.clone(); } ExecutableDeployItem::Transfer { .. } => { - return Err(InvalidRequest::InvalidSessionDeployItem(*deploy_hash)); + return Err(InvalidRequest::UnsupportedMode( + transaction_hash, + session_item.to_string(), + )); } } @@ -457,10 +457,14 @@ impl<'a> TryFrom<&'a TransactionV1> for SessionInfo<'a> { type Error = InvalidRequest; fn try_from(v1_txn: &'a TransactionV1) -> Result { + let transaction_hash = TransactionHash::V1(*v1_txn.hash()); let args = v1_txn.args().clone(); let session = match v1_txn.target() { TransactionTarget::Native => { - return Err(InvalidRequest::InvalidSessionV1Target(*v1_txn.hash())); + return Err(InvalidRequest::InvalidTarget( + transaction_hash, + v1_txn.target().to_string(), + )); } TransactionTarget::Stored { id, .. } => ExecutableItem::Stored(id.clone()), TransactionTarget::Session { @@ -472,7 +476,7 @@ impl<'a> TryFrom<&'a TransactionV1> for SessionInfo<'a> { }; let TransactionEntryPoint::Custom(entry_point) = v1_txn.entry_point() else { - return Err(InvalidRequest::InvalidSessionV1EntryPoint(*v1_txn.hash())); + return Err(InvalidRequest::InvalidEntryPoint(transaction_hash, v1_txn.entry_point().to_string())); }; Ok(SessionInfo { @@ -497,23 +501,29 @@ impl<'a> TryFrom<(&'a ExecutableDeployItem, &'a DeployHash)> for PaymentInfo<'a> fn try_from( (payment_item, deploy_hash): (&'a ExecutableDeployItem, &'a DeployHash), ) -> Result { + let transaction_hash = TransactionHash::Deploy(*deploy_hash); match payment_item { ExecutableDeployItem::ModuleBytes { module_bytes, args } => { if module_bytes.is_empty() { - return Err(InvalidRequest::EmptyCustomPaymentBytes(*deploy_hash)); + Ok(PaymentInfo { + payment: ExecutableItem::StandardPayment, + args: args.clone(), + }) + } else { + Ok(PaymentInfo { + payment: ExecutableItem::CustomPayment(module_bytes), + args: args.clone(), + }) } - Ok(PaymentInfo { - payment: ExecutableItem::CustomPayment(module_bytes), - args: args.clone(), - }) } ExecutableDeployItem::StoredContractByHash { .. } | ExecutableDeployItem::StoredContractByName { .. } | ExecutableDeployItem::StoredVersionedContractByHash { .. } | ExecutableDeployItem::StoredVersionedContractByName { .. } - | ExecutableDeployItem::Transfer { .. } => { - Err(InvalidRequest::InvalidPaymentDeployItem(*deploy_hash)) - } + | ExecutableDeployItem::Transfer { .. } => Err(InvalidRequest::UnexpectedVariant( + transaction_hash, + "payment item".to_string(), + )), } } } @@ -522,8 +532,8 @@ impl<'a> TryFrom<&'a TransactionV1> for PaymentInfo<'a> { type Error = InvalidRequest; fn try_from(v1_txn: &'a TransactionV1) -> Result { - // TODO - check this is using the correct value (i.e. we don't need to account for gas_price - // here). + let transaction_hash = TransactionHash::V1(*v1_txn.hash()); + let pricing_mode = v1_txn.pricing_mode(); let payment_amount = match v1_txn.pricing_mode() { PricingMode::Classic { payment_amount, @@ -531,22 +541,30 @@ impl<'a> TryFrom<&'a TransactionV1> for PaymentInfo<'a> { .. } => { if *standard_payment { - return Err(InvalidRequest::InvalidPricingMode(*v1_txn.hash())); + return Err(InvalidRequest::UnsupportedMode( + transaction_hash, + pricing_mode.to_string(), + )); } *payment_amount } PricingMode::Fixed { .. } | PricingMode::Reserved { .. } => { - return Err(InvalidRequest::InvalidPricingMode(*v1_txn.hash())); + return Err(InvalidRequest::UnsupportedMode( + transaction_hash, + pricing_mode.to_string(), + )); } }; let payment = match v1_txn.target() { - // TODO - should we also consider the session kind here? TransactionTarget::Session { module_bytes, .. } => { ExecutableItem::CustomPayment(module_bytes) } TransactionTarget::Native | TransactionTarget::Stored { .. } => { - return Err(InvalidRequest::InvalidSessionV1Target(*v1_txn.hash())); + return Err(InvalidRequest::InvalidTarget( + transaction_hash, + v1_txn.target().to_string(), + )); } }; let args = runtime_args! { ARG_AMOUNT => U512::from(payment_amount)}; diff --git a/execution_engine/src/runtime/handle_payment_internal.rs b/execution_engine/src/runtime/handle_payment_internal.rs index 2776ee9972..5020850272 100644 --- a/execution_engine/src/runtime/handle_payment_internal.rs +++ b/execution_engine/src/runtime/handle_payment_internal.rs @@ -2,9 +2,8 @@ use casper_storage::global_state::{error::Error as GlobalStateError, state::Stat use std::collections::BTreeSet; use casper_types::{ - account::AccountHash, addressable_entity::NamedKeyAddr, system::handle_payment::Error, - BlockTime, CLValue, FeeHandling, Key, Phase, RefundHandling, StoredValue, TransferredTo, URef, - U512, + account::AccountHash, addressable_entity::NamedKeyAddr, system::handle_payment::Error, CLValue, + FeeHandling, Key, Phase, RefundHandling, StoredValue, TransferredTo, URef, U512, }; use casper_storage::system::handle_payment::{ @@ -133,10 +132,6 @@ where self.context.phase() } - fn get_block_time(&self) -> BlockTime { - self.context.get_blocktime() - } - fn get_caller(&self) -> AccountHash { self.context.get_caller() } @@ -149,8 +144,11 @@ where self.context.engine_config().fee_handling() } - fn administrative_accounts(&self) -> &BTreeSet { - self.context.engine_config().administrative_accounts() + fn administrative_accounts(&self) -> BTreeSet { + self.context + .engine_config() + .administrative_accounts() + .clone() } } diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index 10c0fac97a..8be23a05f7 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -757,29 +757,6 @@ where let maybe_purse = runtime.get_refund_purse().map_err(Self::reverter)?; CLValue::from_t(maybe_purse).map_err(Self::reverter) })(), - handle_payment::METHOD_FINALIZE_PAYMENT => (|| { - runtime.charge_system_contract_call(handle_payment_costs.finalize_payment)?; - - let amount_spent: U512 = - Self::get_named_argument(runtime_args, handle_payment::ARG_AMOUNT)?; - let account: AccountHash = - Self::get_named_argument(runtime_args, handle_payment::ARG_ACCOUNT)?; - let target: URef = - Self::get_named_argument(runtime_args, handle_payment::ARG_TARGET)?; - runtime - .finalize_payment(amount_spent, account, target) - .map_err(Self::reverter)?; - - CLValue::from_t(()).map_err(Self::reverter) - })(), - handle_payment::METHOD_DISTRIBUTE_ACCUMULATED_FEES => (|| { - runtime.charge_system_contract_call(handle_payment_costs.finalize_payment)?; - runtime - .distribute_accumulated_fees() - .map_err(Self::reverter)?; - CLValue::from_t(()).map_err(Self::reverter) - })(), - _ => CLValue::from_t(()).map_err(Self::reverter), }; @@ -2653,9 +2630,9 @@ where self.transfer_to_new_account(source, target, amount, id) } - Some(StoredValue::CLValue(account)) => { + Some(StoredValue::CLValue(entity_key_value)) => { // Attenuate the target main purse - let entity_key = CLValue::into_t::(account)?; + let entity_key = CLValue::into_t::(entity_key_value)?; let target_uref = if let Some(StoredValue::AddressableEntity(entity)) = self.context.read_gs(&entity_key)? { diff --git a/execution_engine_testing/test_support/src/transfer_request_builder.rs b/execution_engine_testing/test_support/src/transfer_request_builder.rs index 222e1d738b..f156181189 100644 --- a/execution_engine_testing/test_support/src/transfer_request_builder.rs +++ b/execution_engine_testing/test_support/src/transfer_request_builder.rs @@ -220,7 +220,6 @@ impl TransferRequestBuilder { self.initiator, self.authorization_keys, RuntimeArgs::from(self.args), - self.gas, ) } diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index 9480b14c08..9fdff02611 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -62,8 +62,8 @@ use casper_types::{ AddressableEntity, AddressableEntityHash, AuctionCosts, BlockTime, ByteCode, ByteCodeAddr, ByteCodeHash, CLTyped, CLValue, Contract, Digest, EntityAddr, EraId, Gas, HandlePaymentCosts, InitiatorAddr, Key, KeyTag, MintCosts, Motes, Package, PackageHash, ProtocolUpgradeConfig, - ProtocolVersion, PublicKey, RefundHandling, StoredValue, SystemEntityRegistry, Timestamp, - TransactionHash, TransactionV1Hash, URef, OS_PAGE_SIZE, U512, + ProtocolVersion, PublicKey, RefundHandling, StoredValue, SystemEntityRegistry, TransactionHash, + TransactionV1Hash, URef, OS_PAGE_SIZE, U512, }; use crate::{ @@ -550,9 +550,8 @@ impl LmdbWasmTestBuilder { pub fn transfer_and_commit(&mut self, mut transfer_request: TransferRequest) -> &mut Self { let pre_state_hash = self.post_state_hash.expect("expected post_state_hash"); transfer_request.set_state_hash_and_config(pre_state_hash, self.native_runtime_config()); - let gas = transfer_request.gas(); let transfer_result = self.data_access_layer.transfer(transfer_request); - + let gas = Gas::new(self.chainspec.system_costs_config.mint_costs().transfer); let execution_result = WasmV1Result::from_transfer_result(transfer_result, gas).unwrap(); let effects = execution_result.effects().clone(); self.effects.push(effects.clone()); @@ -766,7 +765,6 @@ where pub fn bidding( &mut self, maybe_post_state: Option, - maybe_block_time: Option, protocol_version: ProtocolVersion, initiator: InitiatorAddr, auction_method: AuctionMethod, @@ -775,7 +773,6 @@ where .or(self.post_state_hash) .expect("builder must have a post-state hash"); - let block_time = BlockTime::new(maybe_block_time.unwrap_or(Timestamp::now()).millis()); let transaction_hash = TransactionHash::V1(TransactionV1Hash::default()); let authorization_keys = BTreeSet::from_iter(iter::once(initiator.account_hash())); @@ -804,7 +801,6 @@ where let bidding_req = BiddingRequest::new( native_runtime_config, post_state, - block_time, protocol_version, transaction_hash, initiator, @@ -1794,7 +1790,7 @@ where RefundHandling::Refund { refund_ratio } | RefundHandling::Burn { refund_ratio } => { refund_ratio } - RefundHandling::None => Ratio::zero(), + RefundHandling::NoRefund => Ratio::zero(), }; let (numer, denom) = refund_ratio.into(); diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs b/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs index 4dcb02259f..d050092b63 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs @@ -987,7 +987,6 @@ fn should_distribute_rewards_after_restaking_delegated_funds() { // lets churn the bids just to have some fun let undelegate_amount = delegator_1_expected_payout - 1; let undelegate_result = builder.bidding( - None, None, protocol_version, (*DELEGATOR_1_ADDR).into(), @@ -1004,7 +1003,6 @@ fn should_distribute_rewards_after_restaking_delegated_funds() { let updelegate_amount = U512::from(1_000_000); let updelegate_result = builder.bidding( - None, None, protocol_version, (*DELEGATOR_2_ADDR).into(), @@ -1039,7 +1037,6 @@ fn should_distribute_rewards_after_restaking_delegated_funds() { } }; let bid_flip_result = builder.bidding( - None, None, protocol_version, (*VALIDATOR_1_ADDR).into(), diff --git a/execution_engine_testing/tests/src/test/system_costs.rs b/execution_engine_testing/tests/src/test/system_costs.rs index 6a78776f56..cbe00c40a0 100644 --- a/execution_engine_testing/tests/src/test/system_costs.rs +++ b/execution_engine_testing/tests/src/test/system_costs.rs @@ -697,11 +697,11 @@ fn should_charge_for_erroneous_system_contract_calls() { handle_payment::METHOD_SET_REFUND_PURSE, system_config.handle_payment_costs().set_refund_purse, ), - ( - handle_payment_hash, - handle_payment::METHOD_FINALIZE_PAYMENT, - system_config.handle_payment_costs().finalize_payment, - ), + // ( + // handle_payment_hash, + // handle_payment::METHOD_FINALIZE_PAYMENT, + // system_config.handle_payment_costs().finalize_payment, + // ), ]; for (contract_hash, entrypoint, expected_cost) in entrypoint_calls { diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 8fca35508c..86eb178600 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -10,8 +10,8 @@ use casper_storage::{ balance::BalanceHandling, AuctionMethod, BalanceHoldRequest, BalanceIdentifier, BalanceRequest, BiddingRequest, BlockRewardsRequest, BlockRewardsResult, DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, EvictItem, FeeRequest, FeeResult, FlushRequest, - InsufficientBalanceHandling, PruneRequest, PruneResult, StepRequest, StepResult, - TransferRequest, + HandlePaymentMode, HandlePaymentRequest, InsufficientBalanceHandling, PruneRequest, + PruneResult, StepRequest, StepResult, TransferRequest, }, global_state::state::{ lmdb::LmdbGlobalState, scratch::ScratchGlobalState, CommitProvider, ScratchProvider, @@ -19,6 +19,7 @@ use casper_storage::{ }, system::runtime_native::Config as NativeRuntimeConfig, }; + use casper_types::{ bytesrepr::{self, ToBytes, U32_SERIALIZED_LENGTH}, execution::{Effects, ExecutionResult, TransformKindV2, TransformV2}, @@ -40,6 +41,11 @@ use crate::{ types::{self, Chunkable, ExecutableBlock, InternalEraReport}, }; +const ACCOUNT_SESSION: bool = true; +const DIRECT_CONTRACT: bool = !ACCOUNT_SESSION; +const STANDARD_PAYMENT: bool = true; +const CUSTOM_PAYMENT: bool = !STANDARD_PAYMENT; + /// Executes a finalized block. #[allow(clippy::too_many_arguments)] pub fn execute_finalized_block( @@ -75,12 +81,13 @@ pub fn execute_finalized_block( hold_interval: chainspec.core_config.balance_hold_interval.millis(), }; let holds_epoch = Some(chainspec.balance_holds_epoch(executable_block.timestamp)); + let proposer = executable_block.proposer.clone(); let start = Instant::now(); let scratch_state = data_access_layer.get_scratch_global_state(); - let txn_ids = executable_block + let transaction_ids = executable_block .transactions .iter() .map(Transaction::fetch_id) @@ -98,6 +105,25 @@ pub fn execute_finalized_block( let entry_point = transaction.entry_point(); let authorization_keys = transaction.authorization_keys(); + // there are three separate mote / gas / token values and it is important to not mix them up + // we solve for halting state using a `gas limit` which is the maximum amount of + // computation we will allow a given transaction to consume. the transaction itself + // provides a function to determine this if provided with the current cost tables + // + // next there is the actual cost, i.e. how much we charge for that computation + // this is calculated by multiplying the gas limit by the current `gas_price` + // gas price has a floor of 1, and the ceiling is configured in the chainspec + // NOTE: when the gas price is 1, the gas limit and the cost are coincidentally equal + // because x == x * 1; thus it is recommended to run tests with gas price >1 to + // avoid being confused by this + // + // the third important value is the amount of computation consumed by executing a + // transaction for native transactions there is no wasm and the consumed always + // equals the limit for bytecode / wasm based transactions the consumed is based on + // what opcodes were executed in such cases, consumed can range from >0 to + // <=gas_limit. consumed is determined after execution and is important for payment + // post processing + // NOTE: this is the allowed computation limit (gas limit) let gas_limit = match transaction.gas_limit(&system_costs, None) { Ok(gas) => gas, @@ -108,10 +134,11 @@ pub fn execute_finalized_block( continue; } }; + artifact_builder.with_gas_limit(gas_limit); - // NOTE: this is the actual adjusted cost (gas limit * gas price) + // NOTE: this is the actual adjusted cost that we charge for (gas limit * gas price) let cost = match transaction.gas_limit(&system_costs, gas_price) { - Ok(gas) => gas, + Ok(gas) => gas.value(), Err(ite) => { debug!(%ite, "invalid transaction (cost)"); artifact_builder.with_invalid_transaction(&ite); @@ -119,42 +146,76 @@ pub fn execute_finalized_block( continue; } }; - - artifact_builder.with_added_gas(cost); + artifact_builder.with_added_cost(cost); let balance_identifier = { - if !transaction.is_standard_payment() { - // execute custom payment logic, which is expected to - // interact with the handle payment contract to deposit - // sufficient token to cover the cost - - // this is the limit on how much gas we will allow custom payment code to consume - // this notion was originally referred to as the "leash" in the early design of the - // system. - let custom_payment_gas_limit = Gas::new( - // TODO: this should have it's own chainspec value; in the meantime - // using a multiple of a small value. - chainspec.transaction_config.native_transfer_minimum_motes * 5, - ); - let pay_result = match WasmV1Request::new_custom_payment( - state_root_hash, - block_time, - custom_payment_gas_limit, - &transaction, - ) { - Ok(pay_request) => execution_engine_v1.execute(&scratch_state, pay_request), - Err(error) => { - WasmV1Result::invalid_executable_item(custom_payment_gas_limit, error) - } - }; - artifact_builder - .with_wasm_v1_result(pay_result) - .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; - BalanceIdentifier::Payment - } else { - initiator_addr.clone().into() + let is_account_session = transaction.is_account_session(); + let is_standard_payment = transaction.is_standard_payment(); + // if standard payment & is session based...use account main purse + // if standard payment & is targeting a contract + // load contract & check entry point, if it pays use contract main purse + // if custom payment, attempt execute custom payment + // if custom payment fails, take remaining balance up to amount + // currently contracts cannot provide custom payment, but considering adding it in + // future + match (is_account_session, is_standard_payment) { + (ACCOUNT_SESSION, STANDARD_PAYMENT) => { + // this is the typical scenario; the initiating account pays using its main + // purse + trace!(%transaction_hash, "account session with standard payment"); + initiator_addr.clone().into() + } + (ACCOUNT_SESSION, CUSTOM_PAYMENT) => { + // the initiating account will pay, but wants to do so with a different purse or + // in a custom way. If anything goes wrong, penalize the sender, do not execute + let custom_payment_gas_limit = Gas::new( + // TODO: this should have it's own chainspec value; in the meantime + // using a multiple of a small value. + chainspec.transaction_config.native_transfer_minimum_motes * 5, + ); + let pay_result = match WasmV1Request::new_custom_payment( + state_root_hash, + block_time, + custom_payment_gas_limit, + &transaction, + ) { + Ok(pay_request) => execution_engine_v1.execute(&scratch_state, pay_request), + Err(error) => { + WasmV1Result::invalid_executable_item(custom_payment_gas_limit, error) + } + }; + let balance_identifier = { + if pay_result.error().is_some() { + BalanceIdentifier::PenalizedAccount(initiator_addr.account_hash()) + } else { + BalanceIdentifier::Payment + } + }; + artifact_builder + .with_wasm_v1_result(pay_result) + .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; + trace!(%transaction_hash, ?balance_identifier, "account session with custom payment"); + balance_identifier + } + (DIRECT_CONTRACT, STANDARD_PAYMENT) => { + // TODO: get the contract, check the entry point indicated in the transaction + // if the contract pays for itself, use its main purse + // <-- contract paying for things wire up goes here --> + // use scratch_state to read the contract & check it here + // if the contract does not exist, the entrypoint does not exist, + // the entrypoint does not pay for itself, and every other sad path + // outcome... penalize the sender, do not execute + debug!("direct contract invocation is currently unsupported; penalize the account that sent it."); + BalanceIdentifier::PenalizedAccount(initiator_addr.account_hash()) + } + (DIRECT_CONTRACT, CUSTOM_PAYMENT) => { + // currently not supported. penalize the sender, do not execute. + warn!("direct contract invocation is currently unsupported; penalize the account that sent it."); + BalanceIdentifier::PenalizedAccount(initiator_addr.account_hash()) + } } }; + let initial_balance_result = scratch_state.balance(BalanceRequest::new( state_root_hash, protocol_version, @@ -162,9 +223,16 @@ pub fn execute_finalized_block( balance_handling, )); - let sufficient_balance = initial_balance_result.is_sufficient(cost.value()); - if sufficient_balance { + let allow_execution = { + let is_not_penalized = !balance_identifier.is_penalty(); + let sufficient_balance = initial_balance_result.is_sufficient(cost); + trace!(%transaction_hash, ?sufficient_balance, ?is_not_penalized, "payment preprocessing"); + is_not_penalized && sufficient_balance + }; + + if allow_execution { let category = transaction.category(); + trace!(%transaction_hash, ?category, "eligible for execution"); match category { TransactionCategory::Mint => { let transfer_result = @@ -177,9 +245,10 @@ pub fn execute_finalized_block( initiator_addr, authorization_keys, runtime_args, - cost, )); + let consumed = gas_limit; artifact_builder + .with_added_consumed(consumed) .with_transfer_result(transfer_result) .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; } @@ -200,7 +269,9 @@ pub fn execute_finalized_block( authorization_keys, auction_method, )); + let consumed = gas_limit; artifact_builder + .with_added_consumed(consumed) .with_bidding_result(bidding_result) .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; } @@ -226,6 +297,7 @@ pub fn execute_finalized_block( let wasm_v1_result = execution_engine_v1.execute(&scratch_state, wasm_v1_request); trace!(%transaction_hash, ?category, ?wasm_v1_result, "able to get wasm v1 result"); + // note: consumed is scraped from wasm_v1_result along w/ other fields artifact_builder .with_wasm_v1_result(wasm_v1_result) .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; @@ -238,22 +310,20 @@ pub fn execute_finalized_block( } } } else { - debug!(%transaction_hash, "skipping execution due to insufficient balance"); + debug!(%transaction_hash, "not eligible for execution"); } let fee_handling = chainspec.core_config.fee_handling; - trace!(%transaction_hash, ?fee_handling, ?sufficient_balance, "fee handling"); // handle payment per the chainspec determined fee setting match fee_handling { FeeHandling::NoFee => { - // this is the "fee elimination" model...a BalanceHold for the full cost is placed - // on the initiator's purse. + // in this mode, a hold for full cost is placed on the payer's purse. let hold_result = scratch_state.balance_hold(BalanceHoldRequest::new( state_root_hash, protocol_version, balance_identifier, BalanceHoldAddrTag::Gas, - cost.value(), + cost, block_time, chainspec.core_config.balance_hold_interval, insufficient_balance_handling, @@ -263,25 +333,60 @@ pub fn execute_finalized_block( .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; } FeeHandling::PayToProposer => { - // this is the current mainnet mechanism...pay up front - // finalize at the end - // we have the proposer of this block...just deposit to them - // call handle_payment and done - // add data_provider.fee(.. pay_to_proposer), get effects and done + // in this mode, the consumed gas is paid as a fee to the block proposer + let consumed = Gas::new(artifact_builder.consumed()); + let handle_payment_request = HandlePaymentRequest::new( + native_runtime_config.clone(), + state_root_hash, + protocol_version, + transaction_hash, + HandlePaymentMode::finalize( + gas_limit, + gas_price, + cost, + consumed, + balance_identifier, + BalanceIdentifier::Public(*(proposer.clone())), + holds_epoch, + ), + ); + let handle_payment_result = scratch_state.handle_payment(handle_payment_request); + artifact_builder + .with_handle_payment_result(&handle_payment_result) + .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; } FeeHandling::Accumulate => { - // this is a variation on PayToProposer that was added for - // for some private networks...the fees are all accumulated - // and distributed to administrative accounts as part of fee - // distribution. So, we just send the payment to the accumulator - // purse and move on. - // add data_provider.fee(.. accumulate), get effects and done + // in this mode, consumed gas is accumulated into a single purse for later + // distribution + let consumed = Gas::new(artifact_builder.consumed()); + let handle_payment_request = HandlePaymentRequest::new( + native_runtime_config.clone(), + state_root_hash, + protocol_version, + transaction_hash, + HandlePaymentMode::distribute_accumulated( + BalanceIdentifier::Accumulate, + Some(consumed), + ), + ); + let handle_payment_result = scratch_state.handle_payment(handle_payment_request); + artifact_builder + .with_handle_payment_result(&handle_payment_result) + .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; } FeeHandling::Burn => { - // this is a new variation that is not currently supported. - // this is for future use...but it is very simple...the - // fees are simply burned, lowering total supply. - // add data_provider.fee(.. burn), get effects and done + let consumed = artifact_builder.consumed(); + let handle_payment_request = HandlePaymentRequest::new( + native_runtime_config.clone(), + state_root_hash, + protocol_version, + transaction_hash, + HandlePaymentMode::burn(balance_identifier, Some(consumed)), + ); + let handle_payment_result = scratch_state.handle_payment(handle_payment_request); + artifact_builder + .with_handle_payment_result(&handle_payment_result) + .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; } } @@ -299,7 +404,7 @@ pub fn execute_finalized_block( // data can be verified if necessary for a given block. the block synchronizer in particular // depends on the existence of such checksums. let txns_approvals_hashes = { - let approvals_checksum = types::compute_approvals_checksum(txn_ids.clone()) + let approvals_checksum = types::compute_approvals_checksum(transaction_ids.clone()) .map_err(BlockExecutionError::FailedToComputeApprovalsChecksum)?; let execution_results_checksum = compute_execution_results_checksum( artifacts.iter().map(|artifact| &artifact.execution_result), @@ -318,7 +423,10 @@ pub fn execute_finalized_block( ), )); scratch_state.commit(state_root_hash, effects)?; - txn_ids.into_iter().map(|id| id.approvals_hash()).collect() + transaction_ids + .into_iter() + .map(|id| id.approvals_hash()) + .collect() }; // Pay out block fees, if relevant. This auto-commits @@ -335,16 +443,9 @@ pub fn execute_finalized_block( } FeeResult::Failure(fer) => return Err(BlockExecutionError::DistributeFees(fer)), FeeResult::Success { - //transfers: fee_transfers, - post_state_hash, - .. + post_state_hash, .. } => { - //transfers.extend(fee_transfers); state_root_hash = post_state_hash; - // TODO: looks like effects & transfer records are associated with the - // ExecutionResult struct which assumes they were caused by a - // deploy. however, systemic operations produce effects and transfer - // records also. } } } @@ -570,7 +671,7 @@ pub fn execute_finalized_block( executable_block.era_id, executable_block.height, protocol_version, - (*executable_block.proposer).clone(), + (*proposer).clone(), executable_block.mint, executable_block.auction, executable_block.install_upgrade, diff --git a/node/src/components/contract_runtime/types.rs b/node/src/components/contract_runtime/types.rs index 9620a32e13..025f42bd1a 100644 --- a/node/src/components/contract_runtime/types.rs +++ b/node/src/components/contract_runtime/types.rs @@ -10,8 +10,8 @@ use casper_execution_engine::engine_state::{ use casper_storage::{ block_store::types::ApprovalsHashes, data_access_layer::{ - bidding::AuctionMethodError, BalanceHoldResult, BiddingResult, EraValidatorsRequest, - TransferResult, + auction::AuctionMethodError, BalanceHoldResult, BiddingResult, EraValidatorsRequest, + HandlePaymentResult, TransferResult, }, }; use casper_types::{ @@ -72,7 +72,9 @@ pub(crate) struct ExecutionArtifactBuilder { transfers: Vec, initiator: InitiatorAddr, payment: Vec, - gas: Gas, + cost: U512, + limit: Gas, + consumed: Gas, } impl ExecutionArtifactBuilder { @@ -86,7 +88,9 @@ impl ExecutionArtifactBuilder { messages: Default::default(), initiator: transaction.initiator_addr(), payment: vec![], - gas: Gas::zero(), + cost: U512::zero(), + limit: Gas::zero(), + consumed: Gas::zero(), } } @@ -94,6 +98,10 @@ impl ExecutionArtifactBuilder { self.effects.clone() } + pub fn consumed(&self) -> U512 { + self.consumed.value() + } + pub fn with_appended_transfers(&mut self, transfers: &mut Vec) -> &mut Self { self.transfers.append(transfers); self @@ -116,12 +124,33 @@ impl ExecutionArtifactBuilder { if let (None, Some(err)) = (&self.error_message, wasm_v1_result.error()) { self.error_message = Some(format!("{}", err)); } - self.with_appended_messages(&mut wasm_v1_result.messages().clone()) + self.with_added_consumed(wasm_v1_result.consumed()) + .with_appended_messages(&mut wasm_v1_result.messages().clone()) .with_appended_transfers(&mut wasm_v1_result.transfers().clone()) .with_appended_effects(wasm_v1_result.effects().clone()); Ok(self) } + pub fn with_handle_payment_result( + &mut self, + handle_payment_result: &HandlePaymentResult, + ) -> Result<&mut Self, ()> { + if let HandlePaymentResult::RootNotFound = handle_payment_result { + return Err(()); + } + if let (None, HandlePaymentResult::Failure(err)) = + (&self.error_message, handle_payment_result) + { + self.error_message = Some(format!("{}", err)); + // NOTE: if handle payment fails, we revert any prior effects. + // and only commit effects produced by handle payment (if any). + self.effects = handle_payment_result.effects(); + return Ok(self); + } + self.with_appended_effects(handle_payment_result.effects()); + Ok(self) + } + pub fn with_balance_hold_result( &mut self, hold_result: &BalanceHoldResult, @@ -136,8 +165,18 @@ impl ExecutionArtifactBuilder { Ok(self) } - pub fn with_added_gas(&mut self, gas: Gas) -> &mut Self { - self.gas = self.gas.saturating_add(gas); + pub fn with_added_cost(&mut self, cost: U512) -> &mut Self { + self.cost = self.cost.saturating_add(cost); + self + } + + pub fn with_gas_limit(&mut self, limit: Gas) -> &mut Self { + self.limit = limit; + self + } + + pub fn with_added_consumed(&mut self, consumed: Gas) -> &mut Self { + self.consumed = self.consumed.saturating_add(consumed); self } @@ -223,8 +262,10 @@ impl ExecutionArtifactBuilder { effects: self.effects, transfers: self.transfers, initiator: self.initiator, + limit: self.limit, + consumed: self.consumed, + cost: self.cost, payment: self.payment, - gas: self.gas, error_message: self.error_message, }; let execution_result = ExecutionResult::V2(result); diff --git a/node/src/components/event_stream_server/tests.rs b/node/src/components/event_stream_server/tests.rs index b4d468ef5f..4073a49bcb 100644 --- a/node/src/components/event_stream_server/tests.rs +++ b/node/src/components/event_stream_server/tests.rs @@ -1071,8 +1071,6 @@ fn json_schema_check() { "{}/../resources/test/sse_data_schema.json", env!("CARGO_MANIFEST_DIR") ); - assert_schema( - schema_path, - serde_json::to_string_pretty(&schema_for!(SseData)).unwrap(), - ); + let pretty = serde_json::to_string_pretty(&schema_for!(SseData)).unwrap(); + assert_schema(schema_path, pretty); } diff --git a/node/src/components/storage/tests.rs b/node/src/components/storage/tests.rs index 1333aa30b4..d88ce58972 100644 --- a/node/src/components/storage/tests.rs +++ b/node/src/components/storage/tests.rs @@ -1363,13 +1363,16 @@ fn prepare_exec_result_with_transfer( Gas::from(rng.gen::()), Some(rng.gen()), )); + let limit = Gas::new(rng.gen::()); let exec_result = ExecutionResult::V2(ExecutionResultV2 { - effects: Effects::new(), - transfers: vec![transfer.clone()], initiator: initiator_addr, - gas: Gas::new(rng.gen::()), - payment: vec![], error_message: None, + limit, + cost: limit.value(), + consumed: limit, + payment: vec![], + transfers: vec![transfer.clone()], + effects: Effects::new(), }); (exec_result, transfer) } diff --git a/node/src/components/transaction_acceptor/tests.rs b/node/src/components/transaction_acceptor/tests.rs index 7d1bd443a5..7310a0cf3e 100644 --- a/node/src/components/transaction_acceptor/tests.rs +++ b/node/src/components/transaction_acceptor/tests.rs @@ -738,7 +738,10 @@ impl reactor::Reactor for Reactor { BalanceIdentifier::Public(public_key) => { Key::Account(public_key.to_account_hash()) } - BalanceIdentifier::Account(account_hash) => Key::Account(*account_hash), + BalanceIdentifier::Account(account_hash) + | BalanceIdentifier::PenalizedAccount(account_hash) => { + Key::Account(*account_hash) + } BalanceIdentifier::Entity(entity_addr) => { Key::AddressableEntity(*entity_addr) } @@ -751,6 +754,14 @@ impl reactor::Reactor for Reactor { .ignore::(); return Effects::new(); } + BalanceIdentifier::Accumulate => { + responder + .respond(BalanceResult::Failure( + TrackingCopyError::NamedKeyNotFound("accumulate".to_string()), + )) + .ignore::(); + return Effects::new(); + } }; let purse_addr = match balance_request.identifier().as_purse_addr() { Some(purse_addr) => purse_addr, diff --git a/node/src/reactor/main_reactor/tests.rs b/node/src/reactor/main_reactor/tests.rs index 245ee733e7..4de8b94dba 100644 --- a/node/src/reactor/main_reactor/tests.rs +++ b/node/src/reactor/main_reactor/tests.rs @@ -694,7 +694,7 @@ impl TestFixture { ExecutionResult::V1(_) => unreachable!(), ExecutionResult::V2(ExecutionResultV2 { effects, - gas, + consumed: gas, error_message, .. }) => { diff --git a/resources/local/chainspec.toml.in b/resources/local/chainspec.toml.in index 3f06f5b9ae..5b506196d5 100644 --- a/resources/local/chainspec.toml.in +++ b/resources/local/chainspec.toml.in @@ -91,7 +91,8 @@ compute_rewards = true # # Valid options are: # 'refund': a ratio of the unspent token is returned to the spender. -# 'burn': unspent token is burned +# 'burn': a ratio of the unspent token is burned. +# 'no_refund': no refunds are paid out; this is functionally equivalent to refund with 0% ratio. # This causes excess payment amounts to be sent to either a # pre-defined purse, or back to the sender. The refunded amount is calculated as the given ratio of the payment amount # minus the execution costs. diff --git a/resources/production/chainspec.toml b/resources/production/chainspec.toml index 5fa207078d..1f8366306c 100644 --- a/resources/production/chainspec.toml +++ b/resources/production/chainspec.toml @@ -101,7 +101,8 @@ compute_rewards = true # # Valid options are: # 'refund': a ratio of the unspent token is returned to the spender. -# 'burn': unspent token is burned +# 'burn': a ratio of the unspent token is burned. +# 'no_refund': no refunds are paid out; this is functionally equivalent to refund with 0% ratio. # This causes excess payment amounts to be sent to either a # pre-defined purse, or back to the sender. The refunded amount is calculated as the given ratio of the payment amount # minus the execution costs. diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index 286af6d375..adf40d8793 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -3292,33 +3292,51 @@ "description": "The result of executing a single transaction.", "type": "object", "required": [ + "consumed", + "cost", "effects", - "gas", "initiator", + "limit", "payment", "transfers" ], "properties": { - "effects": { - "description": "The effects of executing the transaction.", + "initiator": { + "description": "Who initiatied this transaction.", "allOf": [ { - "$ref": "#/definitions/Effects" + "$ref": "#/definitions/InitiatorAddr" } ] }, - "transfers": { - "description": "A record of transfers performed while executing the transaction.", - "type": "array", - "items": { - "$ref": "#/definitions/Transfer" - } + "error_message": { + "description": "If there is no error message, this execution was processed successfully. If there is an error message, this execution failed to fully process for the stated reason.", + "type": [ + "string", + "null" + ] }, - "initiator": { - "description": "Identifier of the initiator of the transaction.", + "limit": { + "description": "What was the maximum allowed gas limit for this transaction?.", "allOf": [ { - "$ref": "#/definitions/InitiatorAddr" + "$ref": "#/definitions/Gas" + } + ] + }, + "consumed": { + "description": "How much gas was consumed executing this transaction.", + "allOf": [ + { + "$ref": "#/definitions/Gas" + } + ] + }, + "cost": { + "description": "How much was paid for this transaction.", + "allOf": [ + { + "$ref": "#/definitions/U512" } ] }, @@ -3329,20 +3347,159 @@ "$ref": "#/definitions/PaymentInfo" } }, + "transfers": { + "description": "A record of transfers performed while executing this transaction.", + "type": "array", + "items": { + "$ref": "#/definitions/Transfer" + } + }, + "effects": { + "description": "The effects of executing this transaction.", + "allOf": [ + { + "$ref": "#/definitions/Effects" + } + ] + } + }, + "additionalProperties": false + }, + "Gas": { + "description": "The `Gas` struct represents a `U512` amount of gas.", + "allOf": [ + { + "$ref": "#/definitions/U512" + } + ] + }, + "PaymentInfo": { + "description": "Breakdown of payments made to cover the cost.", + "type": "object", + "required": [ + "source" + ], + "properties": { + "source": { + "description": "Source purse used for payment of the transaction.", + "allOf": [ + { + "$ref": "#/definitions/URef" + } + ] + } + } + }, + "Transfer": { + "description": "A versioned wrapper for a transfer.", + "oneOf": [ + { + "description": "A version 1 transfer.", + "type": "object", + "required": [ + "Version1" + ], + "properties": { + "Version1": { + "$ref": "#/definitions/TransferV1" + } + }, + "additionalProperties": false + }, + { + "description": "A version 2 transfer.", + "type": "object", + "required": [ + "Version2" + ], + "properties": { + "Version2": { + "$ref": "#/definitions/TransferV2" + } + }, + "additionalProperties": false + } + ] + }, + "TransferV2": { + "description": "Represents a version 2 transfer from one purse to another.", + "type": "object", + "required": [ + "amount", + "from", + "gas", + "source", + "target", + "transaction_hash" + ], + "properties": { + "transaction_hash": { + "description": "Transaction that created the transfer.", + "allOf": [ + { + "$ref": "#/definitions/TransactionHash" + } + ] + }, + "from": { + "description": "Entity from which transfer was executed.", + "allOf": [ + { + "$ref": "#/definitions/InitiatorAddr" + } + ] + }, + "to": { + "description": "Account to which funds are transferred.", + "anyOf": [ + { + "$ref": "#/definitions/AccountHash" + }, + { + "type": "null" + } + ] + }, + "source": { + "description": "Source purse.", + "allOf": [ + { + "$ref": "#/definitions/URef" + } + ] + }, + "target": { + "description": "Target purse.", + "allOf": [ + { + "$ref": "#/definitions/URef" + } + ] + }, + "amount": { + "description": "Transfer amount.", + "allOf": [ + { + "$ref": "#/definitions/U512" + } + ] + }, "gas": { - "description": "The gas consumed executing the transaction.", + "description": "Gas.", "allOf": [ { "$ref": "#/definitions/Gas" } ] }, - "error_message": { - "description": "The error message associated with executing the transaction if the transaction failed.", + "id": { + "description": "User-defined ID.", "type": [ - "string", + "integer", "null" - ] + ], + "format": "uint64", + "minimum": 0.0 } }, "additionalProperties": false @@ -4681,145 +4838,6 @@ } } }, - "Transfer": { - "description": "A versioned wrapper for a transfer.", - "oneOf": [ - { - "description": "A version 1 transfer.", - "type": "object", - "required": [ - "Version1" - ], - "properties": { - "Version1": { - "$ref": "#/definitions/TransferV1" - } - }, - "additionalProperties": false - }, - { - "description": "A version 2 transfer.", - "type": "object", - "required": [ - "Version2" - ], - "properties": { - "Version2": { - "$ref": "#/definitions/TransferV2" - } - }, - "additionalProperties": false - } - ] - }, - "TransferV2": { - "description": "Represents a version 2 transfer from one purse to another.", - "type": "object", - "required": [ - "amount", - "from", - "gas", - "source", - "target", - "transaction_hash" - ], - "properties": { - "transaction_hash": { - "description": "Transaction that created the transfer.", - "allOf": [ - { - "$ref": "#/definitions/TransactionHash" - } - ] - }, - "from": { - "description": "Entity from which transfer was executed.", - "allOf": [ - { - "$ref": "#/definitions/InitiatorAddr" - } - ] - }, - "to": { - "description": "Account to which funds are transferred.", - "anyOf": [ - { - "$ref": "#/definitions/AccountHash" - }, - { - "type": "null" - } - ] - }, - "source": { - "description": "Source purse.", - "allOf": [ - { - "$ref": "#/definitions/URef" - } - ] - }, - "target": { - "description": "Target purse.", - "allOf": [ - { - "$ref": "#/definitions/URef" - } - ] - }, - "amount": { - "description": "Transfer amount.", - "allOf": [ - { - "$ref": "#/definitions/U512" - } - ] - }, - "gas": { - "description": "Gas.", - "allOf": [ - { - "$ref": "#/definitions/Gas" - } - ] - }, - "id": { - "description": "User-defined ID.", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "Gas": { - "description": "The `Gas` struct represents a `U512` amount of gas.", - "allOf": [ - { - "$ref": "#/definitions/U512" - } - ] - }, - "PaymentInfo": { - "description": "Breakdown of payments made to cover the cost.", - "type": "object", - "required": [ - "source" - ], - "properties": { - "source": { - "description": "Source purse used for payment of the transaction.", - "allOf": [ - { - "$ref": "#/definitions/URef" - } - ] - } - } - }, "Message": { "description": "Message that was emitted by an addressable entity during execution.", "type": "object", diff --git a/storage/src/data_access_layer.rs b/storage/src/data_access_layer.rs index 33e11d08f4..c264576d98 100644 --- a/storage/src/data_access_layer.rs +++ b/storage/src/data_access_layer.rs @@ -7,9 +7,9 @@ use casper_types::{execution::Effects, Digest, EraId}; use crate::tracking_copy::TrackingCopy; mod addressable_entity; +pub mod auction; pub mod balance; mod balance_hold; -pub mod bidding; pub mod bids; pub mod block_rewards; pub mod era_validators; @@ -17,6 +17,8 @@ mod execution_results_checksum; mod fee; mod flush; mod genesis; +pub mod handle_payment; +pub mod mint; mod protocol_upgrade; pub mod prune; pub mod query; @@ -25,15 +27,14 @@ pub mod step; mod system_entity_registry; pub mod tagged_values; mod total_supply; -pub mod transfer; mod trie; pub use addressable_entity::{AddressableEntityRequest, AddressableEntityResult}; +pub use auction::{AuctionMethod, BiddingRequest, BiddingResult}; pub use balance::{BalanceIdentifier, BalanceRequest, BalanceResult}; pub use balance_hold::{ BalanceHoldError, BalanceHoldRequest, BalanceHoldResult, InsufficientBalanceHandling, }; -pub use bidding::{BiddingRequest, BiddingResult}; pub use bids::{BidsRequest, BidsResult}; pub use block_rewards::{BlockRewardsError, BlockRewardsRequest, BlockRewardsResult}; pub use era_validators::{EraValidatorsRequest, EraValidatorsResult}; @@ -44,6 +45,8 @@ pub use execution_results_checksum::{ pub use fee::{FeeError, FeeRequest, FeeResult}; pub use flush::{FlushRequest, FlushResult}; pub use genesis::{GenesisRequest, GenesisResult}; +pub use handle_payment::{HandlePaymentMode, HandlePaymentRequest, HandlePaymentResult}; +pub use mint::{TransferRequest, TransferResult}; pub use protocol_upgrade::{ProtocolUpgradeRequest, ProtocolUpgradeResult}; pub use prune::{PruneRequest, PruneResult}; pub use query::{QueryRequest, QueryResult}; @@ -54,11 +57,8 @@ pub use system_entity_registry::{ SystemEntityRegistrySelector, }; pub use total_supply::{TotalSupplyRequest, TotalSupplyResult}; -pub use transfer::{TransferRequest, TransferResult}; pub use trie::{PutTrieRequest, PutTrieResult, TrieElement, TrieRequest, TrieResult}; -pub use bidding::AuctionMethod; - pub struct Block { _era_id: EraId, } diff --git a/storage/src/data_access_layer/bidding.rs b/storage/src/data_access_layer/auction.rs similarity index 99% rename from storage/src/data_access_layer/bidding.rs rename to storage/src/data_access_layer/auction.rs index 226c9321af..2774185d46 100644 --- a/storage/src/data_access_layer/bidding.rs +++ b/storage/src/data_access_layer/auction.rs @@ -271,14 +271,14 @@ pub enum AuctionMethodRet { pub enum BiddingResult { /// Invalid state root hash. RootNotFound, - /// Transfer succeeded + /// Bidding request succeeded Success { // The ret value, if any. ret: AuctionMethodRet, /// Effects of bidding interaction. effects: Effects, }, - /// Bidding request failed + /// Bidding request failed. Failure(TrackingCopyError), } diff --git a/storage/src/data_access_layer/balance.rs b/storage/src/data_access_layer/balance.rs index 230985c3b6..422fca42f7 100644 --- a/storage/src/data_access_layer/balance.rs +++ b/storage/src/data_access_layer/balance.rs @@ -3,7 +3,11 @@ use crate::data_access_layer::BalanceHoldRequest; use casper_types::{ account::AccountHash, global_state::TrieMerkleProof, - system::{handle_payment::PAYMENT_PURSE_KEY, mint::BalanceHoldAddrTag, HANDLE_PAYMENT}, + system::{ + handle_payment::{ACCUMULATION_PURSE_KEY, PAYMENT_PURSE_KEY}, + mint::BalanceHoldAddrTag, + HANDLE_PAYMENT, + }, AccessRights, BlockTime, Digest, EntityAddr, InitiatorAddr, Key, ProtocolVersion, PublicKey, StoredValue, URef, URefAddr, U512, }; @@ -29,23 +33,27 @@ pub enum BalanceHandling { /// Represents a way to make a balance inquiry. #[derive(Debug, Clone, PartialEq, Eq)] pub enum BalanceIdentifier { + Payment, + Accumulate, Purse(URef), Public(PublicKey), Account(AccountHash), Entity(EntityAddr), Internal(URefAddr), - Payment, + PenalizedAccount(AccountHash), } impl BalanceIdentifier { pub fn as_purse_addr(&self) -> Option { match self { - BalanceIdentifier::Purse(uref) => Some(uref.addr()), BalanceIdentifier::Internal(addr) => Some(*addr), + BalanceIdentifier::Purse(uref) => Some(uref.addr()), BalanceIdentifier::Public(_) | BalanceIdentifier::Account(_) + | BalanceIdentifier::PenalizedAccount(_) | BalanceIdentifier::Entity(_) - | BalanceIdentifier::Payment => None, + | BalanceIdentifier::Payment + | BalanceIdentifier::Accumulate => None, } } @@ -59,6 +67,7 @@ impl BalanceIdentifier { S: StateReader, { let purse_uref = match self { + BalanceIdentifier::Internal(addr) => URef::new(*addr, AccessRights::READ), BalanceIdentifier::Purse(purse_uref) => *purse_uref, BalanceIdentifier::Public(public_key) => { let account_hash = public_key.to_account_hash(); @@ -67,7 +76,8 @@ impl BalanceIdentifier { Err(tce) => return Err(tce), } } - BalanceIdentifier::Account(account_hash) => { + BalanceIdentifier::Account(account_hash) + | BalanceIdentifier::PenalizedAccount(account_hash) => { match tc.get_addressable_entity_by_account_hash(protocol_version, *account_hash) { Ok(entity) => entity.main_purse(), Err(tce) => return Err(tce), @@ -79,31 +89,53 @@ impl BalanceIdentifier { Err(tce) => return Err(tce), } } - BalanceIdentifier::Internal(addr) => URef::new(*addr, AccessRights::READ), BalanceIdentifier::Payment => { - let system_contract_registry = tc.get_system_entity_registry()?; - - let handle_payment_hash = - system_contract_registry - .get(HANDLE_PAYMENT) - .ok_or_else(|| { - error!("Missing system handle payment contract hash"); - TrackingCopyError::MissingSystemContractHash(HANDLE_PAYMENT.to_string()) - })?; - - let named_keys = - tc.get_named_keys(EntityAddr::System(handle_payment_hash.value()))?; - let named_key = named_keys.get(PAYMENT_PURSE_KEY).ok_or( - TrackingCopyError::NamedKeyNotFound(PAYMENT_PURSE_KEY.to_string()), - )?; - let uref = named_key - .as_uref() - .ok_or(TrackingCopyError::UnexpectedKeyVariant(*named_key))?; - *uref + self.get_system_purse(tc, HANDLE_PAYMENT, PAYMENT_PURSE_KEY)? + } + BalanceIdentifier::Accumulate => { + self.get_system_purse(tc, HANDLE_PAYMENT, ACCUMULATION_PURSE_KEY)? } }; Ok(purse_uref) } + + fn get_system_purse( + &self, + tc: &mut TrackingCopy, + system_contract_name: &str, + named_key_name: &str, + ) -> Result + where + S: StateReader, + { + let system_contract_registry = tc.get_system_entity_registry()?; + + let entity_hash = system_contract_registry + .get(system_contract_name) + .ok_or_else(|| { + error!("Missing system handle payment contract hash"); + TrackingCopyError::MissingSystemContractHash(system_contract_name.to_string()) + })?; + + let named_keys = tc.get_named_keys(EntityAddr::System(entity_hash.value()))?; + let named_key = + named_keys + .get(named_key_name) + .ok_or(TrackingCopyError::NamedKeyNotFound( + named_key_name.to_string(), + ))?; + let uref = named_key + .as_uref() + .ok_or(TrackingCopyError::UnexpectedKeyVariant(*named_key))?; + Ok(*uref) + } + + /// Is this balance identifier for penalty? + pub fn is_penalty(&self) -> bool { + // currently there is one variant of this kind, but more may be added later to + // support more use cases. + matches!(self, BalanceIdentifier::PenalizedAccount(_)) + } } impl Default for BalanceIdentifier { diff --git a/storage/src/data_access_layer/handle_payment.rs b/storage/src/data_access_layer/handle_payment.rs new file mode 100644 index 0000000000..fedaf2580a --- /dev/null +++ b/storage/src/data_access_layer/handle_payment.rs @@ -0,0 +1,139 @@ +use crate::{ + data_access_layer::BalanceIdentifier, system::runtime_native::Config as NativeRuntimeConfig, + tracking_copy::TrackingCopyError, +}; +use casper_types::{execution::Effects, Digest, Gas, ProtocolVersion, TransactionHash, U512}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum HandlePaymentMode { + Finalize { + limit: Gas, + gas_price: Option, + cost: U512, + consumed: Gas, + source: Box, + target: Box, + holds_epoch: Option, + }, + Distribute { + source: BalanceIdentifier, + amount: Option, + }, + Burn { + source: BalanceIdentifier, + amount: Option, + }, +} + +impl HandlePaymentMode { + pub fn finalize( + limit: Gas, + gas_price: Option, + cost: U512, + consumed: Gas, + source: BalanceIdentifier, + target: BalanceIdentifier, + holds_epoch: Option, + ) -> Self { + HandlePaymentMode::Finalize { + limit, + gas_price, + cost, + consumed, + source: Box::new(source), + target: Box::new(target), + holds_epoch, + } + } + + /// What source should be used to distribute from (typically the Accumulate purse), and how + /// much? If amount is None or greater than the available balance, the full available + /// balance will be distributed. If amount is less than available balance, only that much + /// will be distributed leaving a remaining balance. + pub fn distribute_accumulated(source: BalanceIdentifier, amount: Option) -> Self { + HandlePaymentMode::Distribute { source, amount } + } + + /// What source should be used to burn from, and how much? + /// If amount is None or greater than the available balance, the full available balance + /// will be burned. If amount is less than available balance, only that much will be + /// burned leaving a remaining balance. + pub fn burn(source: BalanceIdentifier, amount: Option) -> Self { + HandlePaymentMode::Burn { source, amount } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct HandlePaymentRequest { + /// The runtime config. + pub(crate) config: NativeRuntimeConfig, + /// State root hash. + pub(crate) state_hash: Digest, + /// The protocol version. + pub(crate) protocol_version: ProtocolVersion, + /// Transaction hash. + pub(crate) transaction_hash: TransactionHash, + /// Handle payment mode. + pub(crate) handle_payment_mode: HandlePaymentMode, +} + +impl HandlePaymentRequest { + /// Creates new request instance with runtime args. + #[allow(clippy::too_many_arguments)] + pub fn new( + config: NativeRuntimeConfig, + state_hash: Digest, + protocol_version: ProtocolVersion, + transaction_hash: TransactionHash, + handle_payment_mode: HandlePaymentMode, + ) -> Self { + Self { + config, + state_hash, + protocol_version, + transaction_hash, + handle_payment_mode, + } + } + + pub fn config(&self) -> &NativeRuntimeConfig { + &self.config + } + + pub fn state_hash(&self) -> Digest { + self.state_hash + } + + pub fn protocol_version(&self) -> ProtocolVersion { + self.protocol_version + } + + pub fn transaction_hash(&self) -> TransactionHash { + self.transaction_hash + } + + pub fn handle_payment_mode(&self) -> &HandlePaymentMode { + &self.handle_payment_mode + } +} + +/// Result enum that represents all possible outcomes of a handle payment request. +#[derive(Debug)] +pub enum HandlePaymentResult { + /// Invalid state root hash. + RootNotFound, + /// Handle payment request succeeded. + Success { effects: Effects }, + /// Handle payment request failed. + Failure(TrackingCopyError), +} + +impl HandlePaymentResult { + /// The effects, if any. + pub fn effects(&self) -> Effects { + match self { + HandlePaymentResult::RootNotFound | HandlePaymentResult::Failure(_) => Effects::new(), + HandlePaymentResult::Success { effects, .. } => effects.clone(), + } + } +} diff --git a/storage/src/data_access_layer/transfer.rs b/storage/src/data_access_layer/mint.rs similarity index 93% rename from storage/src/data_access_layer/transfer.rs rename to storage/src/data_access_layer/mint.rs index 3bee0152d6..cb8ceb8c6e 100644 --- a/storage/src/data_access_layer/transfer.rs +++ b/storage/src/data_access_layer/mint.rs @@ -2,8 +2,8 @@ use std::collections::BTreeSet; use crate::system::runtime_native::{Config as NativeRuntimeConfig, TransferConfig}; use casper_types::{ - account::AccountHash, execution::Effects, Digest, Gas, InitiatorAddr, ProtocolVersion, - RuntimeArgs, TransactionHash, Transfer, + account::AccountHash, execution::Effects, Digest, InitiatorAddr, ProtocolVersion, RuntimeArgs, + TransactionHash, Transfer, }; use crate::system::transfer::{TransferArgs, TransferError}; @@ -34,8 +34,6 @@ pub struct TransferRequest { authorization_keys: BTreeSet, /// Args. args: TransferRequestArgs, - /// Cost. - gas: Gas, } impl TransferRequest { @@ -50,7 +48,6 @@ impl TransferRequest { initiator: InitiatorAddr, authorization_keys: BTreeSet, args: TransferArgs, - gas: Gas, ) -> Self { let args = TransferRequestArgs::Explicit(args); Self { @@ -62,7 +59,6 @@ impl TransferRequest { initiator, authorization_keys, args, - gas, } } @@ -77,7 +73,6 @@ impl TransferRequest { initiator: InitiatorAddr, authorization_keys: BTreeSet, args: RuntimeArgs, - gas: Gas, ) -> Self { let args = TransferRequestArgs::Raw(args); Self { @@ -89,7 +84,6 @@ impl TransferRequest { initiator, authorization_keys, args, - gas, } } @@ -131,11 +125,6 @@ impl TransferRequest { self.transaction_hash } - /// The cost. - pub fn gas(&self) -> Gas { - self.gas - } - /// Returns transfer args. pub fn args(&self) -> &TransferRequestArgs { &self.args diff --git a/storage/src/global_state/state/mod.rs b/storage/src/global_state/state/mod.rs index 68a1a96fb5..40534b8c22 100644 --- a/storage/src/global_state/state/mod.rs +++ b/storage/src/global_state/state/mod.rs @@ -31,19 +31,20 @@ use casper_types::{ }, AUCTION, HANDLE_PAYMENT, MINT, }, - Account, AddressableEntity, CLValue, Digest, EntityAddr, Gas, InitiatorAddr, Key, KeyTag, - Phase, PublicKey, RuntimeArgs, StoredValue, TransactionHash, TransactionV1Hash, U512, + Account, AddressableEntity, CLValue, Digest, EntityAddr, InitiatorAddr, Key, KeyTag, Phase, + PublicKey, RuntimeArgs, StoredValue, TransactionHash, TransactionV1Hash, U512, }; #[cfg(test)] pub use self::lmdb::make_temporary_global_state; use crate::{ data_access_layer::{ + auction::{AuctionMethodRet, BiddingRequest, BiddingResult}, balance::BalanceHandling, - bidding::{AuctionMethodRet, BiddingRequest, BiddingResult}, era_validators::EraValidatorsResult, + handle_payment::{HandlePaymentMode, HandlePaymentRequest, HandlePaymentResult}, + mint::{TransferRequest, TransferRequestArgs, TransferResult}, tagged_values::{TaggedValuesRequest, TaggedValuesResult}, - transfer::{TransferRequest, TransferRequestArgs, TransferResult}, AddressableEntityRequest, AddressableEntityResult, AuctionMethod, BalanceHoldError, BalanceHoldRequest, BalanceHoldResult, BalanceRequest, BalanceResult, BidsRequest, BidsResult, BlockRewardsError, BlockRewardsRequest, BlockRewardsResult, @@ -70,6 +71,7 @@ use crate::{ auction, auction::Auction, genesis::{GenesisError, GenesisInstaller}, + handle_payment::HandlePayment, mint::Mint, protocol_upgrade::{ProtocolUpgradeError, ProtocolUpgrader}, runtime_native::{Id, RuntimeNative}, @@ -585,7 +587,6 @@ pub trait CommitProvider: StateProvider { InitiatorAddr::from(system_account_key.clone()), authorization_keys.clone(), args, - Gas::zero(), ); match self.transfer(transfer_req) { TransferResult::RootNotFound => return FeeResult::RootNotFound, @@ -1018,6 +1019,97 @@ pub trait StateProvider { } } + /// Direct auction interaction for all variations of bid management. + fn handle_payment( + &self, + HandlePaymentRequest { + config, + state_hash, + protocol_version, + transaction_hash, + handle_payment_mode, + }: HandlePaymentRequest, + ) -> HandlePaymentResult { + // let mut tc = match self.tracking_copy(state_hash) { + // Ok(Some(tracking_copy)) => tracking_copy, + // Ok(None) => return HandlePaymentResult::RootNotFound, + // Err(err) => return HandlePaymentResult::Failure(TrackingCopyError::Storage(err)), + // }; + + let tc = match self.tracking_copy(state_hash) { + Ok(Some(tc)) => Rc::new(RefCell::new(tc)), + Ok(None) => return HandlePaymentResult::RootNotFound, + Err(err) => return HandlePaymentResult::Failure(TrackingCopyError::Storage(err)), + }; + + // this runtime uses the system's context + let mut runtime = match RuntimeNative::new_system_runtime( + config, + protocol_version, + Id::Transaction(transaction_hash), + Rc::clone(&tc), + Phase::Session, + ) { + Ok(rt) => rt, + Err(tce) => { + return HandlePaymentResult::Failure(tce); + } + }; + + let result = match handle_payment_mode { + HandlePaymentMode::Finalize { + limit, + gas_price, + cost, + consumed, + source, + target, + holds_epoch, + } => { + let source_purse = match source.purse_uref(&mut tc.borrow_mut(), protocol_version) { + Ok(value) => value, + Err(tce) => return HandlePaymentResult::Failure(tce), + }; + let target_purse = match target.purse_uref(&mut tc.borrow_mut(), protocol_version) { + Ok(value) => value, + Err(tce) => return HandlePaymentResult::Failure(tce), + }; + runtime.finalize_payment( + limit, + gas_price, + cost, + consumed, + source_purse, + target_purse, + holds_epoch, + ) + } + HandlePaymentMode::Distribute { source, amount } => { + let source_purse = match source.purse_uref(&mut tc.borrow_mut(), protocol_version) { + Ok(value) => value, + Err(tce) => return HandlePaymentResult::Failure(tce), + }; + runtime.distribute_accumulated_fees(source_purse, amount) + } + HandlePaymentMode::Burn { source, amount } => { + let source_purse = match source.purse_uref(&mut tc.borrow_mut(), protocol_version) { + Ok(value) => value, + Err(tce) => return HandlePaymentResult::Failure(tce), + }; + runtime.burn(source_purse, amount) + } + }; + + let effects = tc.borrow_mut().effects(); + + match result { + Ok(_) => HandlePaymentResult::Success { effects }, + Err(hpe) => HandlePaymentResult::Failure(TrackingCopyError::SystemContract( + system::Error::HandlePayment(hpe), + )), + } + } + /// Gets the execution result checksum. fn execution_result_checksum( &self, diff --git a/storage/src/system/handle_payment.rs b/storage/src/system/handle_payment.rs index 1624bd62d2..97e1600562 100644 --- a/storage/src/system/handle_payment.rs +++ b/storage/src/system/handle_payment.rs @@ -1,9 +1,10 @@ +mod handle_payment_native; mod internal; pub mod mint_provider; pub mod runtime_provider; pub mod storage_provider; -use casper_types::{account::AccountHash, system::handle_payment::Error, AccessRights, URef, U512}; +use casper_types::{system::handle_payment::Error, AccessRights, Gas, URef, U512}; use crate::system::handle_payment::{ mint_provider::MintProvider, runtime_provider::RuntimeProvider, @@ -34,17 +35,39 @@ pub trait HandlePayment: MintProvider + RuntimeProvider + StorageProvider + Size } /// Finalize payment with `amount_spent` and a given `account`. + #[allow(clippy::too_many_arguments)] fn finalize_payment( &mut self, - amount_spent: U512, - account: AccountHash, - target: URef, + limit: Gas, + gas_price: Option, + cost: U512, + consumed: Gas, + source_purse: URef, + target_purse: URef, + holds_epoch: Option, ) -> Result<(), Error> { - internal::finalize_payment(self, amount_spent, account, target) + internal::finalize_payment( + self, + limit, + gas_price, + cost, + consumed, + source_purse, + target_purse, + holds_epoch, + ) } /// Distribute fees from an accumulation purse. - fn distribute_accumulated_fees(&mut self) -> Result<(), Error> { - internal::distribute_accumulated_fees(self) + fn distribute_accumulated_fees( + &mut self, + source_uref: URef, + amount: Option, + ) -> Result<(), Error> { + internal::distribute_accumulated_fees(self, source_uref, amount) + } + + fn burn(&mut self, source_uref: URef, amount: Option) -> Result<(), Error> { + internal::burn(self, source_uref, amount) } } diff --git a/storage/src/system/handle_payment/handle_payment_native.rs b/storage/src/system/handle_payment/handle_payment_native.rs new file mode 100644 index 0000000000..4ded1aa4a9 --- /dev/null +++ b/storage/src/system/handle_payment/handle_payment_native.rs @@ -0,0 +1,224 @@ +use crate::{ + global_state::{error::Error as GlobalStateError, state::StateReader}, + system::{ + handle_payment::{ + mint_provider::MintProvider, runtime_provider::RuntimeProvider, + storage_provider::StorageProvider, HandlePayment, + }, + mint::Mint, + runtime_native::RuntimeNative, + }, + tracking_copy::TrackingCopyEntityExt, +}; +use casper_types::{ + account::AccountHash, + addressable_entity::{NamedKeyAddr, NamedKeyValue}, + system::handle_payment::Error, + AccessRights, AddressableEntityHash, CLValue, FeeHandling, GrantedAccess, Key, Phase, + RefundHandling, StoredValue, TransferredTo, URef, U512, +}; +use std::collections::BTreeSet; +use tracing::error; + +pub use casper_types::system::handle_payment::Error as HandlePaymentError; + +impl MintProvider for RuntimeNative +where + S: StateReader, +{ + fn transfer_purse_to_account( + &mut self, + source: URef, + target: AccountHash, + amount: U512, + ) -> Result { + let target_key = Key::Account(target); + let entity_key_value = match self.tracking_copy().borrow_mut().read(&target_key) { + Ok(Some(StoredValue::CLValue(cl_value))) => cl_value, // entity exists + Ok(Some(StoredValue::Account(_))) => { + // legacy account exists; attempt to migrate to entity + self.tracking_copy() + .borrow_mut() + .migrate_account(target, self.protocol_version()) + .map_err(|_| Error::Transfer)?; + // attempt to read back migrated entity + if let Ok(Some(StoredValue::CLValue(cl_value))) = + self.tracking_copy().borrow_mut().read(&target_key) + { + cl_value + } else { + return Err(Error::Transfer); + } + } + Ok(_) | Err(_) => return Err(Error::Transfer), + }; + + let entity_key = CLValue::into_t::(entity_key_value) + .map_err(|_| Error::FailedTransferToAccountPurse)?; + // get entity + let target_uref = { + if let Ok(Some(StoredValue::AddressableEntity(entity))) = + self.tracking_copy().borrow_mut().read(&entity_key) + { + entity.main_purse_add_only() + } else { + return Err(Error::Transfer); + } + }; + + // source and target are the same, noop + if source.with_access_rights(AccessRights::ADD) == target_uref { + return Ok(TransferredTo::ExistingAccount); + } + + // Temporarily grant ADD access to target if it is not already present. + let granted_access = self.access_rights_mut().grant_access(target_uref); + + let transfered = self + .transfer_purse_to_purse(source, target_uref, amount) + .is_ok(); + + // if ADD access was temporarily granted, remove it. + if let GrantedAccess::Granted { + uref_addr, + newly_granted_access_rights, + } = granted_access + { + self.access_rights_mut() + .remove_access(uref_addr, newly_granted_access_rights) + } + + if transfered { + Ok(TransferredTo::ExistingAccount) + } else { + Err(Error::Transfer) + } + } + + fn transfer_purse_to_purse( + &mut self, + source: URef, + target: URef, + amount: U512, + ) -> Result<(), Error> { + let holds_epoch = None; // system purses do not have holds on them + match self.transfer(None, source, target, amount, None, holds_epoch) { + Ok(ret) => Ok(ret), + Err(err) => { + error!("{}", err); + Err(Error::Transfer) + } + } + } + + fn available_balance( + &mut self, + purse: URef, + holds_epoch: Option, + ) -> Result, Error> { + match ::balance(self, purse, holds_epoch) { + Ok(ret) => Ok(ret), + Err(err) => { + error!("{}", err); + Err(Error::GetBalance) + } + } + } + + fn reduce_total_supply(&mut self, amount: U512) -> Result<(), Error> { + match ::reduce_total_supply(self, amount) { + Ok(ret) => Ok(ret), + Err(err) => { + println!("{}", err); + error!("{}", err); + Err(Error::ReduceTotalSupply) + } + } + } +} + +impl RuntimeProvider for RuntimeNative +where + S: StateReader, +{ + fn get_key(&mut self, name: &str) -> Option { + self.named_keys().get(name).cloned() + } + + fn put_key(&mut self, name: &str, key: Key) -> Result<(), Error> { + let name = name.to_string(); + let entity = self.addressable_entity(); + let addressable_entity_hash = AddressableEntityHash::new(self.address().value()); + let entity_addr = entity.entity_addr(addressable_entity_hash); + let named_key_value = StoredValue::NamedKey( + NamedKeyValue::from_concrete_values(key, name.clone()).map_err(|_| Error::PutKey)?, + ); + let named_key_addr = + NamedKeyAddr::new_from_string(entity_addr, name.clone()).map_err(|_| Error::PutKey)?; + let key = Key::NamedKey(named_key_addr); + // write to both tracking copy and in-mem named keys cache + self.tracking_copy() + .borrow_mut() + .write(key, named_key_value); + match self.named_keys_mut().insert(name, key) { + Some(_) => Ok(()), + None => Err(Error::PutKey), + } + } + + fn remove_key(&mut self, name: &str) -> Result<(), Error> { + self.named_keys_mut().remove(name); + let entity = self.addressable_entity(); + let addressable_entity_hash = AddressableEntityHash::new(self.address().value()); + let entity_addr = entity.entity_addr(addressable_entity_hash); + let named_key_addr = NamedKeyAddr::new_from_string(entity_addr, name.to_string()) + .map_err(|_| Error::RemoveKey)?; + let key = Key::NamedKey(named_key_addr); + let tc = self.tracking_copy(); + if let Some(StoredValue::NamedKey(_)) = + tc.borrow_mut().read(&key).map_err(|_| Error::RemoveKey)? + { + tc.borrow_mut().prune(key); + } + Ok(()) + } + + fn get_phase(&self) -> Phase { + self.phase() + } + + fn get_caller(&self) -> AccountHash { + self.address() + } + + fn refund_handling(&self) -> RefundHandling { + *self.config().refund_handling() + } + + fn fee_handling(&self) -> FeeHandling { + *self.config().fee_handling() + } + + fn administrative_accounts(&self) -> BTreeSet { + self.transfer_config().administrative_accounts() + } +} + +impl StorageProvider for RuntimeNative +where + S: StateReader, +{ + fn write_balance(&mut self, purse_uref: URef, amount: U512) -> Result<(), Error> { + let cl_value = CLValue::from_t(amount).map_err(|_| Error::Storage)?; + self.tracking_copy().borrow_mut().write( + Key::Balance(purse_uref.addr()), + StoredValue::CLValue(cl_value), + ); + Ok(()) + } +} + +impl HandlePayment for RuntimeNative where + S: StateReader +{ +} diff --git a/storage/src/system/handle_payment/internal.rs b/storage/src/system/handle_payment/internal.rs index a5fdae0a20..ce02fe4112 100644 --- a/storage/src/system/handle_payment/internal.rs +++ b/storage/src/system/handle_payment/internal.rs @@ -1,14 +1,12 @@ +use casper_types::{ + system::handle_payment::{Error, PAYMENT_PURSE_KEY, REFUND_PURSE_KEY}, + FeeHandling, Gas, Key, Phase, PublicKey, RefundHandling, URef, U512, +}; use num::{CheckedMul, One}; use num_rational::Ratio; use num_traits::Zero; use tracing::error; -use casper_types::{ - account::AccountHash, - system::handle_payment::{Error, ACCUMULATION_PURSE_KEY, PAYMENT_PURSE_KEY, REFUND_PURSE_KEY}, - FeeHandling, Key, Phase, PublicKey, RefundHandling, URef, U512, -}; - use super::{ mint_provider::MintProvider, runtime_provider::RuntimeProvider, storage_provider::StorageProvider, @@ -45,20 +43,65 @@ pub fn get_refund_purse( } } -/// Returns tuple where 1st element is the refund, and 2nd element is the fee. +/// Returns tuple where 1st element is the portion of unspent payment (if any), and the 2nd element +/// is the fee (if any). /// /// # Note /// /// Any dust amounts are added to the fee. -fn calculate_refund_and_fee( - gas_spent: U512, - payment_purse_balance: U512, +fn calculate_overpayment_and_fee( + limit: Gas, + gas_price: Option, + cost: U512, + consumed: Gas, + available_balance: U512, refund_handling: RefundHandling, ) -> Result<(U512, U512), Error> { - let unspent = payment_purse_balance - .checked_sub(gas_spent) - .ok_or(Error::ArithmeticOverflow)?; - + /* + cost is limit * price, unused = limit - consumed + base refund is unused * price + refund rate is a percentage ranging from 0% to 100% + actual refund = base refund * refund rate + i.e. if rate == 100%, actual refund == base refund + if rate = 0%, actual refund = 0 (and we can skip refund processing) + EXAMPLE 1 + limit = 500, consumed = 450, price = 2, refund rate = 100% + cost = limit * price == 1000 + unused = limit - consumed == 50 + base refund = unused * price == 100 + actual refund = base refund * refund rate == 100 + + EXAMPLE 2 + limit = 5000, consumed = 0, price = 5, refund rate = 50% + cost = limit * price == 25000 + unused = limit - consumed == 5000 + base refund = unused * price == 25000 + actual refund = base refund * refund rate == 12500 + + Complicating factors: + if the source purse does not have enough to cover the cost, their available balance is taken + and there is no refund + if the refund rate is 0%, there is no refund (although it would be bizarre for a network to + run with RefundHandling turned on but with a 0% rate, they are technically independent + settings and thus the logic must account for the possibility) + cost might be higher than limit * price if additional costs have been incurred. + as the refund calculation is based on paid for but unused gas, such additional costs + are not subject to refund. This is handled by this logic correctly, but tests over logic + that incurs any additional costs need to use actual discrete variables for each value + and not assume limit * price == cost + */ + if available_balance < cost { + return Ok((U512::zero(), available_balance)); + } + if refund_handling.skip_refund() { + return Ok((U512::zero(), cost)); + } + let unspent = limit.saturating_sub(consumed); + if unspent == Gas::zero() { + return Ok((U512::zero(), cost)); + } + let gas_price = gas_price.unwrap_or(1); + let base_refund = unspent.value() * gas_price; let refund_ratio = match refund_handling { RefundHandling::Refund { refund_ratio } | RefundHandling::Burn { refund_ratio } => { debug_assert!( @@ -68,206 +111,194 @@ fn calculate_refund_and_fee( let (numer, denom) = refund_ratio.into(); Ratio::new_raw(U512::from(numer), U512::from(denom)) } - RefundHandling::None => Ratio::zero(), + RefundHandling::NoRefund => Ratio::zero(), }; - let refund = Ratio::from(unspent) + let adjusted_refund = Ratio::from(base_refund) .checked_mul(&refund_ratio) .ok_or(Error::ArithmeticOverflow)? .to_integer(); - let fee = payment_purse_balance - .checked_sub(refund) + let fee = cost + .checked_sub(adjusted_refund) .ok_or(Error::ArithmeticOverflow)?; - Ok((refund, fee)) + Ok((adjusted_refund, fee)) } -/// Transfers funds from the payment purse to the proposer, accumulation purse or burns the amount -/// depending on a [`FeeHandling`] configuration option. This function can also transfer funds to a -/// refund purse, depending on how much was spent on the computation, or burns the refund. This code -/// maintains the invariant that the balance of the payment purse is zero at the beginning and end -/// of each deploy and that the refund purse is unset at the beginning and end of each deploy. +/// This function handles payment post-processing to pay out fees and refunds. +/// +/// The behavior of this function is very load bearing and complex, based on every possible +/// combination of [`FeeHandling`] and [`RefundHandling`] handling variants. +/// +/// NOTE: If a network is configured for both NoFee and NoRefund, this method will error if called. +#[allow(clippy::too_many_arguments)] pub fn finalize_payment( provider: &mut P, - gas_spent: U512, - account: AccountHash, - target: URef, + limit: Gas, + gas_price: Option, + cost: U512, + consumed: Gas, + source_purse: URef, + target_purse: URef, + holds_epoch: Option, ) -> Result<(), Error> { + let refund_handling = provider.refund_handling(); + let fee_handling = provider.fee_handling(); + if fee_handling.skip_fee_handling() && refund_handling.skip_refund() { + // this method should not even be called if NoFee && NoRefund are set, + // as there is nothing to finalize + return Err(Error::IncompatiblePaymentSettings); + } + let caller = provider.get_caller(); if caller != PublicKey::System.to_account_hash() { return Err(Error::SystemFunctionCalledByUserAccount); } - let payment_purse = get_payment_purse(provider)?; - let mut payment_amount = match provider.available_balance( - payment_purse, - None, // the internal payment purse does not have holds - )? { + let source_available_balance = match provider.available_balance(source_purse, holds_epoch)? { Some(balance) => balance, None => return Err(Error::PaymentPurseBalanceNotFound), }; - if payment_amount < gas_spent { - return Err(Error::InsufficientPaymentForAmountSpent); - } - - let (refund, fee) = - calculate_refund_and_fee(gas_spent, payment_amount, provider.refund_handling())?; - - debug_assert_eq!(fee + refund, payment_amount); - - // Give or burn the refund. - match provider.refund_handling() { - RefundHandling::Refund { .. } => { - let refund_purse = get_refund_purse(provider)?; - - if let Some(refund_purse) = refund_purse { - if refund_purse.remove_access_rights() == payment_purse.remove_access_rights() { - // Make sure we're not refunding into a payment purse to invalidate payment - // code postconditions. - return Err(Error::RefundPurseIsPaymentPurse); - } - } - - provider.remove_key(REFUND_PURSE_KEY)?; //unset refund purse after reading it - - if !refund.is_zero() { - match refund_purse { - Some(refund_purse) => { - // In case of failure to transfer to refund purse we fall back on the - // account's main purse - match provider.transfer_purse_to_purse(payment_purse, refund_purse, refund) - { - Ok(()) => {} - Err(error) => { - error!( - %error, - %refund, - %account, - "unable to transfer refund to a refund purse; refunding to account" - ); - refund_to_account::

(provider, payment_purse, account, refund)?; - } - } + let (refund, fee) = calculate_overpayment_and_fee( + limit, + gas_price, + cost, + consumed, + source_available_balance, + refund_handling, + )?; + + if !refund.is_zero() { + match refund_handling { + RefundHandling::Refund { .. } => { + let maybe_refund_purse = get_refund_purse(provider)?; + if let Some(refund_purse) = maybe_refund_purse { + // refund purse cannot also be source purse + if refund_purse.remove_access_rights() == source_purse.remove_access_rights() { + return Err(Error::RefundPurseIsPaymentPurse); } - None => { - refund_to_account::

(provider, payment_purse, account, refund)?; + //unset refund purse after reading it + provider.remove_key(REFUND_PURSE_KEY)?; + if let Err(error) = + provider.transfer_purse_to_purse(source_purse, refund_purse, refund) + { + error!( + %error, + %refund, + %source_purse, + %refund_purse, + "unable to transfer refund to a refund purse" + ); } } } - } - - RefundHandling::Burn { .. } if !refund.is_zero() => { - // Fee-handling is set to `Burn`. Deduct the refund from the payment purse and - // reduce the total supply (i.e. burn the refund). - payment_amount = payment_amount - .checked_sub(refund) - .ok_or(Error::ArithmeticOverflow)?; - - provider.write_balance(payment_purse, payment_amount)?; - provider.reduce_total_supply(refund)?; - } - - RefundHandling::Burn { .. } => { - // No refund to burn - } - - RefundHandling::None => { - // noop + RefundHandling::Burn { .. } => { + burn(provider, source_purse, Some(refund))?; + } + RefundHandling::NoRefund => { + // this must be due to either programmer error or invalid chainspec settings + return Err(Error::IncompatiblePaymentSettings); + } } } // Pay or burn the fee. - match provider.fee_handling() { + match fee_handling { FeeHandling::PayToProposer | FeeHandling::Accumulate => { - // target purse is already resolved based on fee-handling config which is either a - // proposer or accumulation purse. - match provider.transfer_purse_to_purse(payment_purse, target, fee) { + match provider.transfer_purse_to_purse(source_purse, target_purse, fee) { Ok(()) => {} Err(error) => { - error!(%error, %fee, %target, "unable to transfer fee"); + error!(%error, %fee, %target_purse, "unable to transfer fee"); return Err(Error::FailedTransferToRewardsPurse); } } } FeeHandling::Burn => { - debug_assert_eq!( - target, - URef::default(), - "Caller should pass a defaulted URef if the fees are burned" - ); - // Fee-handling is set to `Burn`. Deduct the fee from the payment purse, leaving it - // empty, and reduce the total supply (i.e. burn the fee). - provider.write_balance(payment_purse, U512::zero())?; - provider.reduce_total_supply(fee)?; + burn(provider, source_purse, Some(refund))?; } FeeHandling::NoFee => { - // noop + if !fee.is_zero() { + // this must be due to either programmer error or invalid chainspec settings + return Err(Error::IncompatiblePaymentSettings); + } } } Ok(()) } -pub fn refund_to_account( - mint_provider: &mut M, - payment_purse: URef, - account: AccountHash, - amount: U512, +pub fn burn( + provider: &mut P, + purse: URef, + amount: Option, ) -> Result<(), Error> { - match mint_provider.transfer_purse_to_account(payment_purse, account, amount) { - Ok(_) => Ok(()), - Err(error) => { - error!(%error, %amount, %account, "unable to process refund from payment purse to account"); - Err(Error::FailedTransferToAccountPurse) - } - } -} - -/// Gets an accumulation purse from the named keys. -fn get_accumulation_purse(provider: &mut R) -> Result { - match provider.get_key(ACCUMULATION_PURSE_KEY) { - Some(Key::URef(purse_uref)) => Ok(purse_uref), - Some(_key) => Err(Error::AccumulationPurseKeyUnexpectedType), - None => Err(Error::AccumulationPurseNotFound), + // get the purse total balance (without holds) + let total_balance = match provider.available_balance(purse, None)? { + Some(balance) => balance, + None => return Err(Error::PaymentPurseBalanceNotFound), + }; + let burn_amount = match amount { + Some(amount) => amount, + None => total_balance, + }; + if burn_amount.is_zero() { + // nothing to burn == noop + return Ok(()); } + // Reduce the source purse and total supply by the refund amount + let adjusted_balance = total_balance + .checked_sub(burn_amount) + .ok_or(Error::ArithmeticOverflow)?; + provider.write_balance(purse, adjusted_balance)?; + provider.reduce_total_supply(burn_amount)?; + Ok(()) } /// This function distributes the fees according to the fee handling config. -pub fn distribute_accumulated_fees

(provider: &mut P) -> Result<(), Error> +/// +/// NOTE: If a network is not configured for fee accumulation, this method will error if called. +pub fn distribute_accumulated_fees

( + provider: &mut P, + source_uref: URef, + amount: Option, +) -> Result<(), Error> where P: RuntimeProvider + MintProvider, { - if provider.get_caller() != PublicKey::System.to_account_hash() { - return Err(Error::SystemFunctionCalledByUserAccount); + let fee_handling = provider.fee_handling(); + if !fee_handling.is_accumulate() { + return Err(Error::IncompatiblePaymentSettings); } - // Distribute accumulation purse balance into all administrators - match provider.fee_handling() { - FeeHandling::PayToProposer | FeeHandling::Burn | FeeHandling::NoFee => return Ok(()), - FeeHandling::Accumulate => {} + if provider.get_caller() != PublicKey::System.to_account_hash() { + return Err(Error::SystemFunctionCalledByUserAccount); } - let administrative_accounts = provider.administrative_accounts().clone(); - let accumulation_purse = get_accumulation_purse(provider)?; - let accumulated_balance = provider - .available_balance(accumulation_purse, None)? - .unwrap_or_default(); + let administrative_accounts = provider.administrative_accounts(); let reward_recipients = U512::from(administrative_accounts.len()); - if let Some(reward_amount) = accumulated_balance.checked_div(reward_recipients) { - if reward_amount.is_zero() { - // There is zero tokens to be paid out which means we can exit early. - return Ok(()); - } + let distribute_amount = match amount { + Some(amount) => amount.value(), + None => provider + .available_balance(source_uref, None)? + .unwrap_or_default(), + }; + + if distribute_amount.is_zero() { + return Ok(()); + } + + let portion = distribute_amount + .checked_div(reward_recipients) + .unwrap_or_else(U512::zero); + if !portion.is_zero() { for target in administrative_accounts { - provider.transfer_purse_to_account(accumulation_purse, target, reward_amount)?; + provider.transfer_purse_to_account(source_uref, target, portion)?; } } - // Any dust amount left in the accumulation purse for the next round. - Ok(()) } @@ -275,75 +306,181 @@ where mod tests { use super::*; + // both burn and refund use the same basic calculation for + // overpayment / unspent vs fee...the only difference is + // what is done with the overage _after_ the calculation + // refund returns it to payer, while burn destroys it + + #[test] + fn should_burn_expected_amount() { + let handling = RefundHandling::Burn { + refund_ratio: Ratio::new_raw(1, 1), + }; + test_handle_payment(handling); + } + #[test] - fn should_move_dust_to_reward() { - let refund_ratio = Ratio::new_raw(1, 3); - let refund = RefundHandling::Refund { refund_ratio }; - test_refund_handling(refund); + fn should_refund_expected_amount() { + let handling = RefundHandling::Refund { + refund_ratio: Ratio::new_raw(1, 1), + }; + test_handle_payment(handling); + } - let burn = RefundHandling::Burn { refund_ratio }; - test_refund_handling(burn); + #[test] + fn should_handle_straight_percentages() { + let limit = Gas::new(100u64); + let gas_price = Some(1); + let cost = limit.value(); + let consumed = Gas::from(50u64); + let available = U512::from(1000u64); + let denom = 100; + + for numer in 0..=denom { + let refund_ratio = Ratio::new_raw(numer, denom); + let handling = RefundHandling::Refund { refund_ratio }; + let (overpay, fee) = calculate_overpayment_and_fee( + limit, gas_price, cost, consumed, available, handling, + ) + .unwrap(); + + let unspent = limit.saturating_sub(consumed).value().as_u64(); + let expected = Ratio::from(unspent) + .checked_mul(&refund_ratio) + .ok_or(Error::ArithmeticOverflow) + .expect("should math") + .to_integer(); + assert_eq!(expected, overpay.as_u64(), "overpay"); + let expected_fee = limit.value().as_u64() - expected; + assert_eq!(expected_fee, fee.as_u64(), "fee"); + } } - fn test_refund_handling(refund_handling: RefundHandling) { - let purse_bal = U512::from(10u64); - let gas = U512::from(3u64); - let (a, b) = calculate_refund_and_fee(gas, purse_bal, refund_handling).unwrap(); - assert_eq!(a, U512::from(2u64)); - // (10 - 3) * 1/3 ~ 2.33 (.33 is dust) - assert_eq!(b, U512::from(8u64)); - // 10 - 2 = 8 + fn test_handle_payment(refund_handling: RefundHandling) { + let limit = Gas::new(6u64); + let gas_price = Some(1); + let cost = limit.value(); + let consumed = Gas::from(3u64); + let available = U512::from(10u64); + let (overpay, fee) = calculate_overpayment_and_fee( + limit, + gas_price, + cost, + consumed, + available, + refund_handling, + ) + .unwrap(); + + let unspent = limit.saturating_sub(consumed); + let expected = unspent.value(); + assert_eq!(expected, overpay, "{:?}", refund_handling); + let expected_fee = consumed.value(); + assert_eq!(expected_fee, fee, "fee"); } #[test] - fn should_account_refund_for_dust() { - let purse_bal = U512::from(9973u64); - let gas = U512::from(9161u64); + fn should_roll_over_dust() { + let limit = Gas::new(6u64); + let gas_price = Some(1); + let cost = limit.value(); + let consumed = Gas::from(3u64); + let available = U512::from(10u64); for percentage in 0..=100 { - let refund_ratio = Ratio::new_raw(percentage, 100); - let refund = RefundHandling::Refund { refund_ratio }; + let handling = RefundHandling::Refund { + refund_ratio: Ratio::new_raw(percentage, 100), + }; - let (a, b) = calculate_refund_and_fee(gas, purse_bal, refund).unwrap(); + let (overpay, fee) = calculate_overpayment_and_fee( + limit, gas_price, cost, consumed, available, handling, + ) + .expect("should have overpay and fee"); - let a = Ratio::from(a); - let b = Ratio::from(b); + let a = Ratio::from(overpay); + let b = Ratio::from(fee); - assert_eq!(a + b, Ratio::from(purse_bal)); + assert_eq!(a + b, Ratio::from(cost), "{}", percentage); } } -} -#[cfg(test)] -mod proptests { - use proptest::prelude::*; - - use super::*; - - const DENOM_MAX: u64 = 1000; - const BALANCE_MAX: u64 = 100_000_000; - - prop_compose! { - fn proper_fraction(max: u64) - (numerator in 0..=max) - (numerator in Just(numerator), denom in numerator..=max) -> Ratio { - Ratio::new(numerator, denom) - } + #[test] + fn should_take_all_of_insufficient_balance() { + let limit = Gas::new(6u64); + let gas_price = Some(1); + let cost = limit.value(); + let consumed = Gas::from(3u64); + let available = U512::from(5u64); + + let (overpay, fee) = calculate_overpayment_and_fee( + limit, + gas_price, + cost, + consumed, + available, + RefundHandling::Refund { + refund_ratio: Ratio::new_raw(1, 1), + }, + ) + .unwrap(); + + assert_eq!(U512::zero(), overpay, "overpay"); + let expected = available; + assert_eq!(expected, fee, "fee"); } - prop_compose! { - fn balance_and_gas(max_balance: u64)(balance in 100..=max_balance)(balance in Just(balance), gas in 1..=balance) -> (U512, U512) { - (U512::from(balance), U512::from(gas)) - } + #[test] + fn should_handle_non_1_gas_price() { + let limit = Gas::new(6u64); + let gas_price = 2; + let cost = limit.value() * gas_price; + let consumed = Gas::from(3u64); + let available = U512::from(12u64); + + let (overpay, fee) = calculate_overpayment_and_fee( + limit, + Some(gas_price), + cost, + consumed, + available, + RefundHandling::Refund { + refund_ratio: Ratio::new_raw(1, 1), + }, + ) + .unwrap(); + + let unspent = limit.saturating_sub(consumed); + let expected = unspent.value() * gas_price; + assert_eq!(expected, overpay, "overpay"); + let expected_fee = consumed.value() * gas_price; + assert_eq!(expected_fee, fee, "fee"); } - proptest! { - #[test] - fn refund_and_fee_equals_balance(refund_ratio in proper_fraction(DENOM_MAX), (balance, gas) in balance_and_gas(BALANCE_MAX)) { - let refund = RefundHandling::Refund { refund_ratio }; - - let (refund, fee) = calculate_refund_and_fee(gas, balance, refund).unwrap(); - prop_assert_eq!(refund + fee, balance); - } + #[test] + fn should_handle_extra_cost() { + let limit = Gas::new(6u64); + let gas_price = 2; + let extra_cost = U512::from(1u64); + let cost = limit.value() * gas_price + extra_cost; + let consumed = Gas::from(3u64); + let available = U512::from(21u64); + + let (overpay, fee) = calculate_overpayment_and_fee( + limit, + Some(gas_price), + cost, + consumed, + available, + RefundHandling::Refund { + refund_ratio: Ratio::new_raw(1, 1), + }, + ) + .unwrap(); + + let unspent = limit.saturating_sub(consumed); + let expected = unspent.value() * gas_price; + assert_eq!(expected, overpay, "overpay"); + let expected_fee = consumed.value() * gas_price + extra_cost; + assert_eq!(expected_fee, fee, "fee"); } } diff --git a/storage/src/system/handle_payment/mint_provider.rs b/storage/src/system/handle_payment/mint_provider.rs index b1bd6ce7ff..6411e33e02 100644 --- a/storage/src/system/handle_payment/mint_provider.rs +++ b/storage/src/system/handle_payment/mint_provider.rs @@ -5,6 +5,9 @@ use casper_types::{ /// Provides an access to mint. pub trait MintProvider { /// Transfer `amount` from `source` purse to a `target` account. + /// Note: the source should always be a system purse of some kind, + /// such as the payment purse or an accumulator purse. + /// The target should be the recipient of a refund or a reward fn transfer_purse_to_account( &mut self, source: URef, @@ -13,6 +16,9 @@ pub trait MintProvider { ) -> Result; /// Transfer `amount` from `source` purse to a `target` purse. + /// Note: the source should always be a system purse of some kind, + /// such as the payment purse or an accumulator purse. + /// The target should be the recipient of a refund or a reward fn transfer_purse_to_purse( &mut self, source: URef, diff --git a/storage/src/system/handle_payment/runtime_provider.rs b/storage/src/system/handle_payment/runtime_provider.rs index f362127c9e..b504605f13 100644 --- a/storage/src/system/handle_payment/runtime_provider.rs +++ b/storage/src/system/handle_payment/runtime_provider.rs @@ -1,8 +1,7 @@ use std::collections::BTreeSet; use casper_types::{ - account::AccountHash, system::handle_payment::Error, BlockTime, FeeHandling, Key, Phase, - RefundHandling, + account::AccountHash, system::handle_payment::Error, FeeHandling, Key, Phase, RefundHandling, }; /// Provider of runtime host functionality. @@ -19,9 +18,6 @@ pub trait RuntimeProvider { /// Get current execution phase. fn get_phase(&self) -> Phase; - /// Get current block time. - fn get_block_time(&self) -> BlockTime; - /// Get caller. fn get_caller(&self) -> AccountHash; @@ -32,5 +28,5 @@ pub trait RuntimeProvider { fn fee_handling(&self) -> FeeHandling; /// Returns list of administrative accounts. - fn administrative_accounts(&self) -> &BTreeSet; + fn administrative_accounts(&self) -> BTreeSet; } diff --git a/storage/src/system/runtime_native.rs b/storage/src/system/runtime_native.rs index b0fd3c1a66..54995eaa6d 100644 --- a/storage/src/system/runtime_native.rs +++ b/storage/src/system/runtime_native.rs @@ -345,10 +345,18 @@ where &self.named_keys } - pub fn access_rights(&self) -> &ContextAccessRights { + pub fn named_keys_mut(&mut self) -> &mut NamedKeys { + &mut self.named_keys + } + + pub fn access_rights(&mut self) -> &ContextAccessRights { &self.access_rights } + pub fn access_rights_mut(&mut self) -> &mut ContextAccessRights { + &mut self.access_rights + } + pub fn extend_access_rights(&mut self, urefs: &[URef]) { self.access_rights.extend(urefs) } diff --git a/types/src/chainspec/core_config.rs b/types/src/chainspec/core_config.rs index c46b0f9c95..946d70a397 100644 --- a/types/src/chainspec/core_config.rs +++ b/types/src/chainspec/core_config.rs @@ -31,14 +31,16 @@ pub const DEFAULT_MAX_ASSOCIATED_KEYS: u32 = 100; pub const DEFAULT_MAX_RUNTIME_CALL_STACK_HEIGHT: u32 = 12; /// Default refund handling. -pub const DEFAULT_REFUND_HANDLING: RefundHandling = RefundHandling::Refund { - refund_ratio: Ratio::new_raw(99, 100), -}; +pub const DEFAULT_REFUND_HANDLING: RefundHandling = RefundHandling::NoRefund; +/// Default pricing handling. pub const DEFAULT_PRICING_HANDLING: PricingHandling = PricingHandling::Fixed; /// Default fee handling. -pub const DEFAULT_FEE_HANDLING: FeeHandling = FeeHandling::PayToProposer; +pub const DEFAULT_FEE_HANDLING: FeeHandling = FeeHandling::NoFee; + +/// Default allow reservations. +pub const DEFAULT_ALLOW_RESERVATIONS: bool = false; /// Default balance hold interval. pub const DEFAULT_BALANCE_HOLD_INTERVAL: TimeDiff = TimeDiff::from_seconds(24 * 60 * 60); @@ -223,7 +225,7 @@ impl CoreConfig { PricingHandling::Fixed }; - let allow_reservations = false; + let allow_reservations = DEFAULT_ALLOW_RESERVATIONS; let fee_handling = if rng.gen() { FeeHandling::PayToProposer @@ -304,7 +306,7 @@ impl Default for CoreConfig { refund_handling: DEFAULT_REFUND_HANDLING, pricing_handling: DEFAULT_PRICING_HANDLING, fee_handling: DEFAULT_FEE_HANDLING, - allow_reservations: false, + allow_reservations: DEFAULT_ALLOW_RESERVATIONS, balance_hold_interval: DEFAULT_BALANCE_HOLD_INTERVAL, } } @@ -346,6 +348,7 @@ impl ToBytes for CoreConfig { buffer.extend(self.refund_handling.to_bytes()?); buffer.extend(self.pricing_handling.to_bytes()?); buffer.extend(self.fee_handling.to_bytes()?); + buffer.extend(self.allow_reservations.to_bytes()?); buffer.extend(self.balance_hold_interval.to_bytes()?); Ok(buffer) } diff --git a/types/src/chainspec/fee_handling.rs b/types/src/chainspec/fee_handling.rs index a5e9b76fba..4ec10ca64a 100644 --- a/types/src/chainspec/fee_handling.rs +++ b/types/src/chainspec/fee_handling.rs @@ -34,6 +34,11 @@ impl FeeHandling { pub fn is_accumulate(&self) -> bool { matches!(self, FeeHandling::Accumulate) } + + /// Returns true if configured for no fees. + pub fn skip_fee_handling(&self) -> bool { + matches!(self, FeeHandling::NoFee) + } } impl ToBytes for FeeHandling { @@ -66,10 +71,10 @@ impl FromBytes for FeeHandling { impl Default for FeeHandling { fn default() -> Self { - // in 2.x the default is None as there are no fees. - // FeeHandling::None // in 1.x the (implicit) default was PayToProposer - FeeHandling::PayToProposer + // FeeHandling::PayToProposer + // in 2.x the default is NoFee as there are no fees. + FeeHandling::NoFee } } @@ -94,4 +99,10 @@ mod tests { let fee_config = FeeHandling::Burn; bytesrepr::test_serialization_roundtrip(&fee_config); } + + #[test] + fn bytesrepr_roundtrip_for_no_fee() { + let fee_config = FeeHandling::NoFee; + bytesrepr::test_serialization_roundtrip(&fee_config); + } } diff --git a/types/src/chainspec/refund_handling.rs b/types/src/chainspec/refund_handling.rs index 0bda9edbd1..56e2a0831f 100644 --- a/types/src/chainspec/refund_handling.rs +++ b/types/src/chainspec/refund_handling.rs @@ -1,6 +1,7 @@ /// Configuration options of refund handling that are executed as part of handle payment /// finalization. use num_rational::Ratio; +use num_traits::Zero; use serde::{Deserialize, Serialize}; use crate::bytesrepr::{self, FromBytes, ToBytes}; @@ -32,7 +33,18 @@ pub enum RefundHandling { refund_ratio: Ratio, }, /// No refunds. - None, + NoRefund, +} + +impl RefundHandling { + /// Returns true if we don't need to process a refund. + pub fn skip_refund(&self) -> bool { + match self { + RefundHandling::NoRefund => true, + RefundHandling::Refund { refund_ratio } => refund_ratio.is_zero(), + RefundHandling::Burn { .. } => false, + } + } } impl ToBytes for RefundHandling { @@ -48,7 +60,7 @@ impl ToBytes for RefundHandling { buffer.push(REFUND_HANDLING_BURN_TAG); buffer.extend(refund_ratio.to_bytes()?); } - RefundHandling::None => { + RefundHandling::NoRefund => { buffer.push(REFUND_HANDLING_NONE_TAG); } } @@ -60,7 +72,7 @@ impl ToBytes for RefundHandling { 1 + match self { RefundHandling::Refund { refund_ratio } => refund_ratio.serialized_length(), RefundHandling::Burn { refund_ratio } => refund_ratio.serialized_length(), - RefundHandling::None => 0, + RefundHandling::NoRefund => 0, } } } @@ -77,7 +89,7 @@ impl FromBytes for RefundHandling { let (refund_ratio, rem) = FromBytes::from_bytes(rem)?; Ok((RefundHandling::Burn { refund_ratio }, rem)) } - REFUND_HANDLING_NONE_TAG => Ok((RefundHandling::None, rem)), + REFUND_HANDLING_NONE_TAG => Ok((RefundHandling::NoRefund, rem)), _ => Err(bytesrepr::Error::Formatting), } } @@ -85,13 +97,13 @@ impl FromBytes for RefundHandling { impl Default for RefundHandling { fn default() -> Self { + // in 1.x the default was Refund + // RefundHandling::Refund { + // refund_ratio: Ratio::new(99, 100), + // } // in 2.0 the default payment mode is Fixed with Fee Elimination on, // thus there is nothing to refund. - // RefundHandling::None - // in 1.x the default was Refund - RefundHandling::Refund { - refund_ratio: Ratio::new(99, 100), - } + RefundHandling::NoRefund } } @@ -114,4 +126,10 @@ mod tests { }; bytesrepr::test_serialization_roundtrip(&refund_config); } + + #[test] + fn bytesrepr_roundtrip_for_no_refund() { + let refund_config = RefundHandling::NoRefund; + bytesrepr::test_serialization_roundtrip(&refund_config); + } } diff --git a/types/src/execution/execution_result_v2.rs b/types/src/execution/execution_result_v2.rs index 7337b40608..d240cca4ac 100644 --- a/types/src/execution/execution_result_v2.rs +++ b/types/src/execution/execution_result_v2.rs @@ -27,7 +27,7 @@ use crate::testing::TestRng; use crate::Key; use crate::{ bytesrepr::{self, FromBytes, ToBytes}, - Gas, InitiatorAddr, Transfer, URef, + Gas, InitiatorAddr, Transfer, URef, U512, }; #[cfg(feature = "json-schema")] @@ -47,14 +47,16 @@ static EXECUTION_RESULT: Lazy = Lazy::new(|| { let transfers = vec![Transfer::example().clone()]; ExecutionResultV2 { - effects, - transfers, - gas: Gas::new(123_456), + initiator: InitiatorAddr::from(crate::PublicKey::example().clone()), + error_message: None, + limit: Gas::new(123_456), + consumed: Gas::new(100_000), + cost: U512::from(246_912), payment: vec![PaymentInfo { source: URef::new([1; crate::UREF_ADDR_LENGTH], crate::AccessRights::READ), }], - initiator: InitiatorAddr::from(crate::PublicKey::example().clone()), - error_message: None, + transfers, + effects, } }); @@ -96,18 +98,23 @@ impl FromBytes for PaymentInfo { #[cfg_attr(feature = "json-schema", derive(JsonSchema))] #[serde(deny_unknown_fields)] pub struct ExecutionResultV2 { - /// The effects of executing the transaction. - pub effects: Effects, - /// A record of transfers performed while executing the transaction. - pub transfers: Vec, - /// Identifier of the initiator of the transaction. + /// Who initiatied this transaction. pub initiator: InitiatorAddr, + /// If there is no error message, this execution was processed successfully. + /// If there is an error message, this execution failed to fully process for the stated reason. + pub error_message: Option, + /// What was the maximum allowed gas limit for this transaction?. + pub limit: Gas, + /// How much gas was consumed executing this transaction. + pub consumed: Gas, + /// How much was paid for this transaction. + pub cost: U512, /// Breakdown of payments made to cover the cost. pub payment: Vec, - /// The gas consumed executing the transaction. - pub gas: Gas, - /// The error message associated with executing the transaction if the transaction failed. - pub error_message: Option, + /// A record of transfers performed while executing this transaction. + pub transfers: Vec, + /// The effects of executing this transaction. + pub effects: Effects, } impl ExecutionResultV2 { @@ -129,15 +136,24 @@ impl ExecutionResultV2 { transfers.push(Transfer::random(rng)) } - let gas = Gas::new(rng.gen::()); + let limit = Gas::new(rng.gen::()); + let gas_price = rng.gen_range(1..6); + // cost = the limit * the price + let cost = limit.value() * U512::from(gas_price); + let range = limit.value().as_u64(); + + // can range from 0 to limit + let consumed = limit - Gas::new(rng.gen_range(0..=range)); let payment = vec![PaymentInfo { source: rng.gen() }]; ExecutionResultV2 { + initiator: InitiatorAddr::random(rng), effects, transfers, - gas, + cost, payment, - initiator: InitiatorAddr::random(rng), + limit, + consumed, error_message: if rng.gen() { Some(format!("Error message {}", rng.gen::())) } else { @@ -149,12 +165,14 @@ impl ExecutionResultV2 { impl ToBytes for ExecutionResultV2 { fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - self.effects.write_bytes(writer)?; - self.transfers.write_bytes(writer)?; - self.initiator.write_bytes(writer)?; + self.initiator.write_bytes(writer)?; // initiator should logically be first + self.error_message.write_bytes(writer)?; + self.limit.write_bytes(writer)?; + self.consumed.write_bytes(writer)?; + self.cost.write_bytes(writer)?; self.payment.write_bytes(writer)?; - self.gas.write_bytes(writer)?; - self.error_message.write_bytes(writer) + self.transfers.write_bytes(writer)?; + self.effects.write_bytes(writer) } fn to_bytes(&self) -> Result, bytesrepr::Error> { @@ -164,30 +182,36 @@ impl ToBytes for ExecutionResultV2 { } fn serialized_length(&self) -> usize { - self.effects.serialized_length() - + self.transfers.serialized_length() - + self.initiator.serialized_length() - + self.payment.serialized_length() - + self.gas.serialized_length() + self.initiator.serialized_length() + self.error_message.serialized_length() + + self.limit.serialized_length() + + self.consumed.serialized_length() + + self.cost.serialized_length() + + self.payment.serialized_length() + + self.transfers.serialized_length() + + self.effects.serialized_length() } } impl FromBytes for ExecutionResultV2 { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (effects, remainder) = Effects::from_bytes(bytes)?; - let (transfers, remainder) = Vec::::from_bytes(remainder)?; - let (initiator, remainder) = InitiatorAddr::from_bytes(remainder)?; - let (payment, remainder) = Vec::::from_bytes(remainder)?; - let (gas, remainder) = Gas::from_bytes(remainder)?; + let (initiator, remainder) = InitiatorAddr::from_bytes(bytes)?; let (error_message, remainder) = Option::::from_bytes(remainder)?; + let (limit, remainder) = Gas::from_bytes(remainder)?; + let (consumed, remainder) = Gas::from_bytes(remainder)?; + let (cost, remainder) = U512::from_bytes(remainder)?; + let (payment, remainder) = Vec::::from_bytes(remainder)?; + let (transfers, remainder) = Vec::::from_bytes(remainder)?; + let (effects, remainder) = Effects::from_bytes(remainder)?; let execution_result = ExecutionResultV2 { - effects, - transfers, initiator, - payment, - gas, error_message, + limit, + consumed, + cost, + payment, + transfers, + effects, }; Ok((execution_result, remainder)) } diff --git a/types/src/gas.rs b/types/src/gas.rs index 10717aa0ee..f42b3ea9d7 100644 --- a/types/src/gas.rs +++ b/types/src/gas.rs @@ -63,6 +63,11 @@ impl Gas { Gas(self.0.saturating_add(rhs.value())) } + /// Saturating integer subtraction. Computes `self + rhs`, returning min if overflow occurred. + pub fn saturating_sub(self, rhs: Self) -> Self { + Gas(self.0.saturating_sub(rhs.value())) + } + /// Checked integer subtraction. Computes `self - rhs`, returning `None` if overflow occurred. pub fn checked_sub(&self, rhs: Self) -> Option { self.0.checked_sub(rhs.value()).map(Self::new) diff --git a/types/src/system/handle_payment/constants.rs b/types/src/system/handle_payment/constants.rs index ef0feedd54..24fd10bada 100644 --- a/types/src/system/handle_payment/constants.rs +++ b/types/src/system/handle_payment/constants.rs @@ -13,10 +13,6 @@ pub const METHOD_GET_PAYMENT_PURSE: &str = "get_payment_purse"; pub const METHOD_SET_REFUND_PURSE: &str = "set_refund_purse"; /// Named constant for method `get_refund_purse`. pub const METHOD_GET_REFUND_PURSE: &str = "get_refund_purse"; -/// Named constant for method `finalize_payment`. -pub const METHOD_FINALIZE_PAYMENT: &str = "finalize_payment"; -/// Named constant for method `distribute_accumulated_fees`. -pub const METHOD_DISTRIBUTE_ACCUMULATED_FEES: &str = "distribute_accumulated_fees"; /// Storage for handle payment contract hash. pub const CONTRACT_HASH_KEY: &str = "contract_hash"; diff --git a/types/src/system/handle_payment/entry_points.rs b/types/src/system/handle_payment/entry_points.rs index daf8926f9e..3c7d77e4f1 100644 --- a/types/src/system/handle_payment/entry_points.rs +++ b/types/src/system/handle_payment/entry_points.rs @@ -2,14 +2,11 @@ use alloc::boxed::Box; use crate::{ system::handle_payment::{ - ARG_ACCOUNT, ARG_AMOUNT, ARG_PURSE, METHOD_FINALIZE_PAYMENT, METHOD_GET_PAYMENT_PURSE, - METHOD_GET_REFUND_PURSE, METHOD_SET_REFUND_PURSE, + ARG_PURSE, METHOD_GET_PAYMENT_PURSE, METHOD_GET_REFUND_PURSE, METHOD_SET_REFUND_PURSE, }, CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Parameter, }; -use super::METHOD_DISTRIBUTE_ACCUMULATED_FEES; - /// Creates handle payment contract entry points. pub fn handle_payment_entry_points() -> EntryPoints { let mut entry_points = EntryPoints::new(); @@ -41,26 +38,5 @@ pub fn handle_payment_entry_points() -> EntryPoints { ); entry_points.add_entry_point(get_refund_purse); - let finalize_payment = EntryPoint::new( - METHOD_FINALIZE_PAYMENT, - vec![ - Parameter::new(ARG_AMOUNT, CLType::U512), - Parameter::new(ARG_ACCOUNT, CLType::ByteArray(32)), - ], - CLType::Unit, - EntryPointAccess::Public, - EntryPointType::Called, - ); - entry_points.add_entry_point(finalize_payment); - - let distribute_accumulated_fees = EntryPoint::new( - METHOD_DISTRIBUTE_ACCUMULATED_FEES, - vec![], - CLType::Unit, - EntryPointAccess::Public, - EntryPointType::Called, - ); - entry_points.add_entry_point(distribute_accumulated_fees); - entry_points } diff --git a/types/src/system/handle_payment/error.rs b/types/src/system/handle_payment/error.rs index 77867a360d..449d5694a7 100644 --- a/types/src/system/handle_payment/error.rs +++ b/types/src/system/handle_payment/error.rs @@ -255,6 +255,12 @@ pub enum Error { /// assert_eq!(37, Error::AccumulationPurseKeyUnexpectedType as u8); /// ``` AccumulationPurseKeyUnexpectedType = 37, + /// Internal error: invalid fee and / or refund settings encountered during payment processing. + /// ``` + /// # use casper_types::system::handle_payment::Error; + /// assert_eq!(38, Error::IncompatiblePaymentSettings as u8); + /// ``` + IncompatiblePaymentSettings = 38, } impl Display for Error { @@ -326,6 +332,9 @@ impl Display for Error { Error::AccumulationPurseKeyUnexpectedType => { formatter.write_str("Accumulation purse has unexpected type") } + Error::IncompatiblePaymentSettings => { + formatter.write_str("Incompatible payment settings") + } } } } @@ -400,6 +409,9 @@ impl TryFrom for Error { v if v == Error::AccumulationPurseKeyUnexpectedType as u8 => { Error::AccumulationPurseKeyUnexpectedType } + v if v == Error::IncompatiblePaymentSettings as u8 => { + Error::IncompatiblePaymentSettings + } _ => return Err(()), }; Ok(error) diff --git a/types/src/transaction.rs b/types/src/transaction.rs index 7d0f8ac777..c509f0baa0 100644 --- a/types/src/transaction.rs +++ b/types/src/transaction.rs @@ -336,6 +336,14 @@ impl Transaction { } } + /// Should this transaction start in the initiating accounts context? + pub fn is_account_session(&self) -> bool { + match self { + Transaction::Deploy(deploy) => deploy.is_account_session(), + Transaction::V1(v1) => v1.is_account_session(), + } + } + /// Authorization keys. pub fn authorization_keys(&self) -> BTreeSet { match self { diff --git a/types/src/transaction/deploy.rs b/types/src/transaction/deploy.rs index c02c0a4277..73d310a706 100644 --- a/types/src/transaction/deploy.rs +++ b/types/src/transaction/deploy.rs @@ -381,6 +381,12 @@ impl Deploy { self.session.is_transfer() } + /// Should this transaction start in the initiating accounts context? + pub fn is_account_session(&self) -> bool { + // legacy deploys are always initiated by an account + true + } + /// Returns `Ok` if and only if: /// * the chain_name is correct, /// * the configured parameters are complied with at the given timestamp diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index 5381e6cab0..31e4dedc0d 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -235,6 +235,12 @@ impl TransactionV1 { } } + /// Should this transaction start in the initiating accounts context? + pub fn is_account_session(&self) -> bool { + let target_is_stored_contract = matches!(self.target(), TransactionTarget::Stored { .. }); + !target_is_stored_contract + } + /// Returns the approvals for this transaction. pub fn approvals(&self) -> &BTreeSet { &self.approvals From b2c290c6b2fb120460eb252592c0c0fd49c0bfff Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Mon, 25 Mar 2024 01:47:55 -0700 Subject: [PATCH 34/70] triaging ee tests, misc tweaks --- .../src/engine_state/engine_config.rs | 2 +- .../src/engine_state/execution_kind.rs | 11 +- execution_engine/src/engine_state/mod.rs | 23 ++-- execution_engine/src/engine_state/wasm_v1.rs | 61 ++++++--- execution_engine/src/runtime/mod.rs | 62 +++++---- .../test_support/src/wasm_test_builder.rs | 12 +- .../src/test/contract_api/get_call_stack.rs | 72 ++++++---- .../tests/src/test/contract_api/transfer.rs | 3 +- .../contract_api/transfer_purse_to_account.rs | 3 +- .../contract_api/transfer_purse_to_purse.rs | 6 +- .../src/test/deploy/non_standard_payment.rs | 3 +- .../tests/src/test/deploy/stored_contracts.rs | 21 ++- .../tests/src/test/explorer/faucet.rs | 17 ++- .../tests/src/test/groups.rs | 6 +- .../private_chain/burn_fees_and_refund.rs | 21 ++- .../test/private_chain/fees_accumulation.rs | 9 +- .../private_chain/unrestricted_transfers.rs | 6 +- .../tests/src/test/regression/ee_1129.rs | 9 +- .../tests/src/test/regression/ee_1225.rs | 3 +- .../tests/src/test/regression/ee_532.rs | 2 +- .../tests/src/test/regression/ee_584.rs | 3 +- .../tests/src/test/regression/gh_1902.rs | 3 +- .../tests/src/test/regression/gov_42.rs | 38 ++++-- .../test/regression/regression_20210707.rs | 10 +- .../test/regression/regression_20210924.rs | 9 +- .../tests/src/test/storage_costs.rs | 18 ++- .../system_contracts/auction/distribute.rs | 3 +- .../test/system_contracts/auction_bidding.rs | 3 +- .../handle_payment/finalize_payment.rs | 3 +- .../handle_payment/get_payment_purse.rs | 6 +- .../test/system_contracts/standard_payment.rs | 27 ++-- .../src/test/system_contracts/upgrade.rs | 49 ------- .../components/contract_runtime/operations.rs | 3 +- node/src/components/transaction_acceptor.rs | 8 +- types/src/cl_value.rs | 6 +- types/src/gens.rs | 4 +- types/src/key.rs | 85 +++++++----- types/src/system/caller.rs | 4 +- .../transaction_invocation_target.rs | 128 ++++++++++-------- .../transaction_v1/transaction_v1_body.rs | 2 +- utils/validation/src/generators.rs | 2 +- 41 files changed, 436 insertions(+), 330 deletions(-) diff --git a/execution_engine/src/engine_state/engine_config.rs b/execution_engine/src/engine_state/engine_config.rs index 19c45588a3..f362aced80 100644 --- a/execution_engine/src/engine_state/engine_config.rs +++ b/execution_engine/src/engine_state/engine_config.rs @@ -51,7 +51,7 @@ pub const DEFAULT_BALANCE_HOLD_INTERVAL: TimeDiff = TimeDiff::from_seconds(24 * #[derive(Debug, Clone)] pub struct EngineConfig { /// Maximum number of associated keys (i.e. map of - /// [`AccountHash`](casper_types::account::AccountHash)s to + /// [`AccountHash`](AccountHash)s to /// [`Weight`](casper_types::account::Weight)s) for a single account. max_associated_keys: u32, max_runtime_call_stack_height: u32, diff --git a/execution_engine/src/engine_state/execution_kind.rs b/execution_engine/src/engine_state/execution_kind.rs index 5b9d21e818..06062663a9 100644 --- a/execution_engine/src/engine_state/execution_kind.rs +++ b/execution_engine/src/engine_state/execution_kind.rs @@ -93,8 +93,8 @@ impl<'a> ExecutionKind<'a> { R: StateReader, { let entity_hash = match target { - TransactionInvocationTarget::InvocableEntity(addr) => AddressableEntityHash::new(*addr), - TransactionInvocationTarget::InvocableEntityAlias(alias) => { + TransactionInvocationTarget::ByHash(addr) => AddressableEntityHash::new(*addr), + TransactionInvocationTarget::ByName(alias) => { let entity_key = named_keys .get(alias) .ok_or_else(|| Error::Exec(ExecError::NamedKeyNotFound(alias.clone())))?; @@ -107,7 +107,7 @@ impl<'a> ExecutionKind<'a> { _ => return Err(Error::InvalidKeyVariant(*entity_key)), } } - TransactionInvocationTarget::Package { addr, version } => { + TransactionInvocationTarget::ByPackageHash { addr, version } => { let package_hash = PackageHash::from(*addr); let package = tracking_copy.get_package(package_hash)?; @@ -136,7 +136,10 @@ impl<'a> ExecutionKind<'a> { entity_version_key, )))? } - TransactionInvocationTarget::PackageAlias { alias, version } => { + TransactionInvocationTarget::ByPackageName { + name: alias, + version, + } => { let package_key = named_keys .get(alias) .ok_or_else(|| Error::Exec(ExecError::NamedKeyNotFound(alias.to_string())))?; diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index 7a78e3a33a..494dff622d 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -14,7 +14,7 @@ use casper_storage::{ global_state::state::StateProvider, tracking_copy::{TrackingCopyEntityExt, TrackingCopyError, TrackingCopyExt}, }; -use casper_types::{ProtocolVersion, U512}; +use casper_types::U512; use crate::{execution::Executor, runtime::RuntimeStack}; pub use deploy_item::DeployItem; @@ -40,11 +40,7 @@ pub static MAX_PAYMENT: Lazy = Lazy::new(|| U512::from(MAX_PAYMENT_AMOUNT) /// pay. pub const WASMLESS_TRANSFER_FIXED_GAS_PRICE: u64 = 1; -/// Main implementation of an execution engine state. -/// -/// Takes an engine's configuration and a provider of a state (aka the global state) to operate on. -/// Methods implemented on this structure are the external API intended to be used by the users such -/// as the node, test framework, and others. +/// The public api of the v1 execution engine, as of protocol version 2.0.0 #[derive(Debug, Clone, Default)] pub struct ExecutionEngineV1 { config: EngineConfig, @@ -61,15 +57,6 @@ impl ExecutionEngineV1 { &self.config } - /// Sets the protocol version of the config. - /// - /// NOTE: This is only useful to the WasmTestBuilder for emulating a network upgrade, and hence - /// is subject to change or deletion without notice. - #[doc(hidden)] - pub fn set_protocol_version(&mut self, protocol_version: ProtocolVersion) { - self.config.set_protocol_version(protocol_version) - } - /// Executes wasm, and that's all. Does not commit or handle payment or anything else. pub fn execute( &self, @@ -86,6 +73,12 @@ impl ExecutionEngineV1 { authorization_keys, }: WasmV1Request, ) -> WasmV1Result { + // NOTE to core engineers: it is intended for the EE to ONLY execute wasm targeting the + // casper v1 virtual machine. it should not handle native behavior, database / global state + // interaction, payment processing, or anything other than its single function. + // A good deal of effort has been put into removing all such behaviors; please do not + // come along and start adding it back. + let account_hash = initiator_addr.account_hash(); let protocol_version = self.config.protocol_version(); let tc = match state_provider.tracking_copy(state_hash) { diff --git a/execution_engine/src/engine_state/wasm_v1.rs b/execution_engine/src/engine_state/wasm_v1.rs index 39a87d6e3c..a5adc00a0a 100644 --- a/execution_engine/src/engine_state/wasm_v1.rs +++ b/execution_engine/src/engine_state/wasm_v1.rs @@ -339,22 +339,23 @@ impl WasmV1Result { /// Converts a transfer result to an execution result. pub fn from_transfer_result(transfer_result: TransferResult, consumed: Gas) -> Option { + // NOTE: for native / wasmless operations limit and consumed are always equal, and + // we can get away with simplifying to one or the other here. + // this is NOT true of wasm based operations however. match transfer_result { TransferResult::RootNotFound => None, - TransferResult::Success { transfers, effects } => { - Some(WasmV1Result { - transfers, - limit: consumed, // TODO - check this is legit. - consumed, - effects, - messages: Messages::default(), - error: None, - }) - } + TransferResult::Success { transfers, effects } => Some(WasmV1Result { + transfers, + limit: consumed, + consumed, + effects, + messages: Messages::default(), + error: None, + }), TransferResult::Failure(te) => { Some(WasmV1Result { transfers: vec![], - limit: consumed, // TODO - check this is legit. + limit: consumed, consumed, effects: Effects::default(), // currently not returning effects on failure messages: Messages::default(), @@ -516,11 +517,39 @@ impl<'a> TryFrom<(&'a ExecutableDeployItem, &'a DeployHash)> for PaymentInfo<'a> }) } } - ExecutableDeployItem::StoredContractByHash { .. } - | ExecutableDeployItem::StoredContractByName { .. } - | ExecutableDeployItem::StoredVersionedContractByHash { .. } - | ExecutableDeployItem::StoredVersionedContractByName { .. } - | ExecutableDeployItem::Transfer { .. } => Err(InvalidRequest::UnexpectedVariant( + ExecutableDeployItem::StoredContractByHash { hash, args, .. } => Ok(PaymentInfo { + payment: ExecutableItem::Stored(TransactionInvocationTarget::ByHash(hash.value())), + args: args.clone(), + }), + ExecutableDeployItem::StoredContractByName { name, args, .. } => Ok(PaymentInfo { + payment: ExecutableItem::Stored(TransactionInvocationTarget::ByName(name.clone())), + args: args.clone(), + }), + ExecutableDeployItem::StoredVersionedContractByHash { + args, + hash, + version, + .. + } => Ok(PaymentInfo { + payment: ExecutableItem::Stored(TransactionInvocationTarget::ByPackageHash { + addr: hash.value(), + version: version.clone(), + }), + args: args.clone(), + }), + ExecutableDeployItem::StoredVersionedContractByName { + name, + version, + args, + .. + } => Ok(PaymentInfo { + payment: ExecutableItem::Stored(TransactionInvocationTarget::ByPackageName { + name: name.clone(), + version: version.clone(), + }), + args: args.clone(), + }), + ExecutableDeployItem::Transfer { .. } => Err(InvalidRequest::UnexpectedVariant( transaction_hash, "payment item".to_string(), )), diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index 8be23a05f7..143bfe6a04 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -678,10 +678,12 @@ where // Charge just for the amount that particular entry point cost - using gas cost from the // isolated runtime might have a recursive costs whenever system contract calls other system // contract. - self.gas(match mint_runtime.gas_counter().checked_sub(gas_counter) { - None => gas_counter, - Some(new_gas) => new_gas, - })?; + self.gas( + mint_runtime + .gas_counter() + .checked_sub(gas_counter) + .unwrap_or(gas_counter), + )?; // Result still contains a result, but the entrypoints logic does not exit early on errors. let ret = result?; @@ -760,10 +762,12 @@ where _ => CLValue::from_t(()).map_err(Self::reverter), }; - self.gas(match runtime.gas_counter().checked_sub(gas_counter) { - None => gas_counter, - Some(new_gas) => new_gas, - })?; + self.gas( + runtime + .gas_counter() + .checked_sub(gas_counter) + .unwrap_or(gas_counter), + )?; let ret = result?; @@ -985,10 +989,12 @@ where }; // Charge for the gas spent during execution in an isolated runtime. - self.gas(match runtime.gas_counter().checked_sub(gas_counter) { - None => gas_counter, - Some(new_gas) => new_gas, - })?; + self.gas( + runtime + .gas_counter() + .checked_sub(gas_counter) + .unwrap_or(gas_counter), + )?; // Result still contains a result, but the entrypoints logic does not exit early on errors. let ret = result?; @@ -1059,15 +1065,13 @@ where // this is normal operation and we should return the value captured // in the Runtime result field. let downcasted_error = host_error.downcast_ref::(); - match downcasted_error { - Some(ExecError::Ret(ref _ret_urefs)) => { - return self - .take_host_buffer() - .ok_or(ExecError::ExpectedReturnValue); - } - Some(error) => return Err(error.clone()), - None => return Err(ExecError::Interpreter(host_error.to_string())), - } + return match downcasted_error { + Some(ExecError::Ret(ref _ret_urefs)) => self + .take_host_buffer() + .ok_or(ExecError::ExpectedReturnValue), + Some(error) => Err(error.clone()), + None => Err(ExecError::Interpreter(host_error.to_string())), + }; } Err(ExecError::Interpreter(error.into())) } @@ -1488,7 +1492,7 @@ where // operation and we should return the value captured in the Runtime result // field. let downcasted_error = host_error.downcast_ref::(); - match downcasted_error { + return match downcasted_error { Some(ExecError::Ret(ref ret_urefs)) => { // Insert extra urefs returned from call. // Those returned URef's are guaranteed to be valid as they were already @@ -1497,13 +1501,13 @@ where // Stored contracts are expected to always call a `ret` function, // otherwise it's an error. - return runtime + runtime .take_host_buffer() - .ok_or(ExecError::ExpectedReturnValue); + .ok_or(ExecError::ExpectedReturnValue) } - Some(error) => return Err(error.clone()), - None => return Err(ExecError::Interpreter(host_error.to_string())), - } + Some(error) => Err(error.clone()), + None => Err(ExecError::Interpreter(host_error.to_string())), + }; } Err(ExecError::Interpreter(error.into())) } @@ -2851,7 +2855,7 @@ where Some(cl_value) => cl_value.destructure(), }; - if serialized_value.len() > u32::max_value() as usize { + if serialized_value.len() > u32::MAX as usize { return Ok(Err(ApiError::OutOfMemory)); } if serialized_value.len() > dest_size { @@ -2899,7 +2903,7 @@ where let name = String::from_utf8_lossy(&name_bytes); let arg_size: u32 = match self.context.args().get(&name) { - Some(arg) if arg.inner_bytes().len() > u32::max_value() as usize => { + Some(arg) if arg.inner_bytes().len() > u32::MAX as usize => { return Ok(Err(ApiError::OutOfMemory)); } Some(arg) => { diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index 9fdff02611..7361c8d18c 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -264,9 +264,9 @@ impl LmdbWasmTestBuilder { .write_scratch_to_db(pre_state_hash, scratch_state) .unwrap(); self.post_state_hash = Some(post_state_hash); - Rc::get_mut(&mut self.execution_engine) - .unwrap() - .set_protocol_version(upgrade_config.new_protocol_version()); + let mut engine_config = self.chainspec.engine_config(); + engine_config.set_protocol_version(upgrade_config.new_protocol_version()); + self.execution_engine = Rc::new(ExecutionEngineV1::new(engine_config)); ProtocolUpgradeResult::Success { post_state_hash, effects, @@ -875,9 +875,9 @@ where post_state_hash, .. } = result { - Rc::get_mut(&mut self.execution_engine) - .unwrap() - .set_protocol_version(upgrade_config.new_protocol_version()); + let mut engine_config = self.chainspec.engine_config(); + engine_config.set_protocol_version(upgrade_config.new_protocol_version()); + self.execution_engine = Rc::new(ExecutionEngineV1::new(engine_config)); self.post_state_hash = Some(post_state_hash); } diff --git a/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs b/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs index b7832283bf..9601c8f4bf 100644 --- a/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs +++ b/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs @@ -3572,7 +3572,8 @@ mod payment { // Stored session + recursive subcall #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_versioned_payment_by_name_to_stored_versioned_session() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3597,7 +3598,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_versioned_payment_by_hash_to_stored_versioned_session() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3626,7 +3628,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_versioned_payment_by_name_to_stored_session() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3646,7 +3649,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_versioned_payment_by_hash_to_stored_session() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3674,7 +3678,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_payment_by_name_to_stored_versioned_session() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3699,7 +3704,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_payment_by_hash_to_stored_versioned_session() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3731,7 +3737,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_payment_by_name_to_stored_session() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3751,7 +3758,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_payment_by_hash_to_stored_session() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3776,7 +3784,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_versioned_payment_by_name_to_stored_versioned_contract() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3801,7 +3810,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_versioned_payment_by_hash_to_stored_versioned_contract() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3831,7 +3841,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_versioned_payment_by_name_to_stored_contract() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3851,7 +3862,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_versioned_payment_by_hash_to_stored_contract() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3879,7 +3891,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_payment_by_name_to_stored_versioned_contract() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3903,7 +3916,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_payment_by_hash_to_stored_versioned_contract() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3935,7 +3949,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_payment_by_name_to_stored_contract() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3955,7 +3970,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_payment_by_hash_to_stored_contract() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3982,7 +3998,8 @@ mod payment { // Stored session + recursive subcall failure cases #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_versioned_payment_by_name_to_stored_versioned_contract_to_stored_versioned_session_should_fail( ) { for call_depth in DEPTHS { @@ -4013,7 +4030,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_versioned_payment_by_hash_to_stored_versioned_contract_to_stored_session_should_fail() { for call_depth in DEPTHS { @@ -4049,7 +4067,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_versioned_payment_by_name_to_stored_contract_to_stored_versioned_session_should_fail() { for call_depth in DEPTHS { @@ -4081,7 +4100,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_versioned_payment_by_hash_to_stored_contract_to_stored_session_should_fail() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -4115,7 +4135,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_payment_by_name_to_stored_versioned_contract_to_stored_versioned_session_should_fail() { for call_depth in DEPTHS { @@ -4146,7 +4167,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_session_by_hash_to_stored_versioned_contract_to_stored_session_should_fail() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -4181,7 +4203,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_payment_by_name_to_stored_contract_to_stored_versioned_session_should_fail() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -4212,7 +4235,8 @@ mod payment { } #[ignore] - #[test] + #[allow(unused)] + // #[test] fn stored_payment_by_name_to_stored_contract_to_stored_session_should_fail() { for call_depth in DEPTHS { let mut builder = super::setup(); diff --git a/execution_engine_testing/tests/src/test/contract_api/transfer.rs b/execution_engine_testing/tests/src/test/contract_api/transfer.rs index 4ed0068f96..443af358bd 100644 --- a/execution_engine_testing/tests/src/test/contract_api/transfer.rs +++ b/execution_engine_testing/tests/src/test/contract_api/transfer.rs @@ -469,7 +469,8 @@ fn should_fail_when_insufficient_funds() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_transfer_total_amount() { let mut builder = LmdbWasmTestBuilder::default(); diff --git a/execution_engine_testing/tests/src/test/contract_api/transfer_purse_to_account.rs b/execution_engine_testing/tests/src/test/contract_api/transfer_purse_to_account.rs index 7f056cde43..b41b0b72bf 100644 --- a/execution_engine_testing/tests/src/test/contract_api/transfer_purse_to_account.rs +++ b/execution_engine_testing/tests/src/test/contract_api/transfer_purse_to_account.rs @@ -56,7 +56,8 @@ fn should_run_purse_to_account_transfer() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_fail_when_sending_too_much_from_purse_to_account() { let account_1_key = ACCOUNT_1_ADDR; diff --git a/execution_engine_testing/tests/src/test/contract_api/transfer_purse_to_purse.rs b/execution_engine_testing/tests/src/test/contract_api/transfer_purse_to_purse.rs index db0c38f0de..3a686e321a 100644 --- a/execution_engine_testing/tests/src/test/contract_api/transfer_purse_to_purse.rs +++ b/execution_engine_testing/tests/src/test/contract_api/transfer_purse_to_purse.rs @@ -14,7 +14,8 @@ const ARG_TARGET: &str = "target"; const ARG_AMOUNT: &str = "amount"; #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_run_purse_to_purse_transfer() { let source = "purse:main".to_string(); let target = "purse:secondary".to_string(); @@ -89,7 +90,8 @@ fn should_run_purse_to_purse_transfer() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_run_purse_to_purse_transfer_with_error() { // This test runs a contract that's after every call extends the same key with // more data diff --git a/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs b/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs index cabb21db53..3c20a7dad9 100644 --- a/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs +++ b/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs @@ -15,7 +15,8 @@ const ARG_PURSE_NAME: &str = "purse_name"; const ARG_DESTINATION: &str = "destination"; #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_charge_non_main_purse() { // as account_1, create & fund a new purse and use that to pay for something // instead of account_1 main purse diff --git a/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs b/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs index 990214dec6..6de1dc7ff5 100644 --- a/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs +++ b/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs @@ -123,7 +123,8 @@ fn should_exec_non_stored_code() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_fail_if_calling_non_existent_entry_point() { let payment_purse_amount = *DEFAULT_PAYMENT; @@ -179,7 +180,8 @@ fn should_fail_if_calling_non_existent_entry_point() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_exec_stored_code_by_hash() { let default_payment = *DEFAULT_PAYMENT; @@ -235,7 +237,8 @@ fn should_exec_stored_code_by_hash() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_not_transfer_above_balance_using_stored_payment_code_by_hash() { let payment_purse_amount = *DEFAULT_PAYMENT; @@ -281,7 +284,8 @@ fn should_not_transfer_above_balance_using_stored_payment_code_by_hash() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_empty_account_using_stored_payment_code_by_hash() { let payment_purse_amount = *DEFAULT_PAYMENT; @@ -330,7 +334,8 @@ fn should_empty_account_using_stored_payment_code_by_hash() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_exec_stored_code_by_named_hash() { let payment_purse_amount = *DEFAULT_PAYMENT; @@ -553,7 +558,8 @@ fn should_fail_session_stored_at_named_key_with_incompatible_major_version() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_fail_session_stored_at_named_key_with_missing_new_major_version() { let payment_purse_amount = *DEFAULT_PAYMENT; @@ -724,7 +730,8 @@ fn should_fail_session_stored_at_hash_with_incompatible_major_version() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_execute_stored_payment_and_session_code_with_new_major_version() { let payment_purse_amount = *DEFAULT_PAYMENT; diff --git a/execution_engine_testing/tests/src/test/explorer/faucet.rs b/execution_engine_testing/tests/src/test/explorer/faucet.rs index 66e1580c86..b67a7abce1 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet.rs @@ -284,7 +284,8 @@ fn should_fund_new_account() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_fund_existing_account() { let user_account = AccountHash::new([7u8; 32]); @@ -357,7 +358,8 @@ fn should_fund_existing_account() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_not_fund_once_exhausted() { let installer_account = AccountHash::new([1u8; 32]); let user_account = AccountHash::new([2u8; 32]); @@ -855,7 +857,8 @@ fn should_allow_funding_by_an_authorized_account() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_refund_proper_amount() { let user_account = AccountHash::new([7u8; 32]); @@ -923,10 +926,10 @@ fn faucet_costs() { // This test will fail if execution costs vary. The expected costs should not be updated // without understanding why the cost has changed. If the costs do change, it should be // reflected in the "Costs by Entry Point" section of the faucet crate's README.md. - const EXPECTED_FAUCET_INSTALL_COST: u64 = 92_268_834_930; - const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_740_460; - const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_322_580; - const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_828_500; + const EXPECTED_FAUCET_INSTALL_COST: u64 = 91_842_307_540; + const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_733_980; + const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_317_720; + const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_815_540; let installer_account = AccountHash::new([1u8; 32]); let user_account: AccountHash = AccountHash::new([2u8; 32]); diff --git a/execution_engine_testing/tests/src/test/groups.rs b/execution_engine_testing/tests/src/test/groups.rs index fa8b200574..c77bb07e32 100644 --- a/execution_engine_testing/tests/src/test/groups.rs +++ b/execution_engine_testing/tests/src/test/groups.rs @@ -651,8 +651,9 @@ fn should_not_call_uncallable_session_from_deploy() { builder.assert_error(Error::Exec(ExecError::InvalidContext)) } -#[test] #[ignore] +#[allow(unused)] +// #[test] fn should_not_call_group_restricted_stored_payment_code_from_invalid_account() { // This test calls a stored payment code that is restricted with a group access using an account // that does not have any of the group urefs in context. @@ -716,8 +717,9 @@ fn should_not_call_group_restricted_stored_payment_code_from_invalid_account() { assert_matches!(error, Error::Exec(ExecError::InvalidContext)); } -#[test] #[ignore] +#[allow(unused)] +// #[test] fn should_call_group_restricted_stored_payment_code() { // This test calls a stored payment code that is restricted with a group access using an account // that contains urefs from the group. diff --git a/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs b/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs index d839cb0149..95cb758ab4 100644 --- a/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs +++ b/execution_engine_testing/tests/src/test/private_chain/burn_fees_and_refund.rs @@ -15,7 +15,8 @@ use crate::test::private_chain::{ }; #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_burn_the_fees_without_refund() { let zero_refund_handling = RefundHandling::Refund { refund_ratio: Ratio::zero(), @@ -26,7 +27,8 @@ fn should_burn_the_fees_without_refund() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_burn_the_fees_with_half_of_refund() { let half_refund_handling = RefundHandling::Refund { refund_ratio: Ratio::new(1, 2), @@ -38,7 +40,8 @@ fn should_burn_the_fees_with_half_of_refund() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_burn_the_fees_with_refund() { let full_refund_handling = RefundHandling::Refund { refund_ratio: Ratio::one(), @@ -49,7 +52,8 @@ fn should_burn_the_fees_with_refund() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_burn_full_refund_with_accumulating_fee() { let full_refund_handling = RefundHandling::Burn { refund_ratio: Ratio::one(), @@ -60,7 +64,8 @@ fn should_burn_full_refund_with_accumulating_fee() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_burn_zero_refund_with_accumulating_fee() { let full_refund_handling = RefundHandling::Burn { refund_ratio: Ratio::zero(), @@ -71,7 +76,8 @@ fn should_burn_zero_refund_with_accumulating_fee() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_burn_zero_refund_and_burn_fees() { let full_refund_handling = RefundHandling::Burn { refund_ratio: Ratio::zero(), @@ -82,7 +88,8 @@ fn should_burn_zero_refund_and_burn_fees() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_burn_full_refund_and_burn_fees() { let full_refund_handling = RefundHandling::Burn { refund_ratio: Ratio::one(), diff --git a/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs b/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs index 466de315e5..9a6dee61ad 100644 --- a/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs +++ b/execution_engine_testing/tests/src/test/private_chain/fees_accumulation.rs @@ -110,7 +110,8 @@ fn should_finalize_and_accumulate_rewards_purse() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_accumulate_deploy_fees() { let mut builder = super::private_chain_setup(); @@ -172,7 +173,8 @@ fn should_accumulate_deploy_fees() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_distribute_accumulated_fees_to_admins() { let mut builder = super::private_chain_setup(); @@ -232,7 +234,8 @@ fn should_distribute_accumulated_fees_to_admins() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_accumulate_fees_after_upgrade() { let (mut builder, _lmdb_fixture_state, _temp_dir) = lmdb_fixture::builder_from_global_state_fixture(lmdb_fixture::RELEASE_1_4_5); diff --git a/execution_engine_testing/tests/src/test/private_chain/unrestricted_transfers.rs b/execution_engine_testing/tests/src/test/private_chain/unrestricted_transfers.rs index 0a1c9f6176..08f2296a53 100644 --- a/execution_engine_testing/tests/src/test/private_chain/unrestricted_transfers.rs +++ b/execution_engine_testing/tests/src/test/private_chain/unrestricted_transfers.rs @@ -418,7 +418,8 @@ fn should_disallow_wasm_payment_to_purse() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_not_allow_payment_to_purse_in_stored_payment() { // This effectively disables any custom payment code let mut builder = super::private_chain_setup(); @@ -663,7 +664,8 @@ fn should_not_allow_direct_mint_transfer_without_to_field() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_allow_custom_payment_by_paying_to_system_account() { let mut builder = super::private_chain_setup(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1129.rs b/execution_engine_testing/tests/src/test/regression/ee_1129.rs index 5706e40a61..44e196bae9 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1129.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1129.rs @@ -40,7 +40,8 @@ static UNDERFUNDED_ADD_BID_AMOUNT: Lazy = Lazy::new(|| U512::from(1)); static CALL_STORED_CONTRACT_OVERHEAD: Lazy = Lazy::new(|| U512::from(10_001)); #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_run_ee_1129_underfunded_delegate_call() { assert!(U512::from(DEFAULT_DELEGATE_COST) > *UNDERFUNDED_DELEGATE_AMOUNT); @@ -105,7 +106,8 @@ fn should_run_ee_1129_underfunded_delegate_call() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_run_ee_1129_underfunded_add_bid_call() { let accounts = { let validator_1 = GenesisAccount::account( @@ -165,7 +167,8 @@ fn should_run_ee_1129_underfunded_add_bid_call() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_run_ee_1129_underfunded_mint_contract_call() { let mut builder = LmdbWasmTestBuilder::default(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1225.rs b/execution_engine_testing/tests/src/test/regression/ee_1225.rs index 57721fa098..aac90cd7a8 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1225.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1225.rs @@ -11,7 +11,8 @@ const DO_NOTHING_CONTRACT: &str = "do_nothing.wasm"; #[should_panic(expected = "Finalization")] #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_run_ee_1225_verify_finalize_payment_invariants() { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); diff --git a/execution_engine_testing/tests/src/test/regression/ee_532.rs b/execution_engine_testing/tests/src/test/regression/ee_532.rs index 0f4bb49170..6998c3425f 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_532.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_532.rs @@ -38,7 +38,7 @@ fn should_run_ee_532_non_existent_account_regression_test() { message, Some(format!( "{}", - Error::TrackingCopy(TrackingCopyError::AccountNotFound(UNKNOWN_ADDR.into())) + Error::TrackingCopy(TrackingCopyError::KeyNotFound(UNKNOWN_ADDR.into())) )), "expected Error::Authorization" ) diff --git a/execution_engine_testing/tests/src/test/regression/ee_584.rs b/execution_engine_testing/tests/src/test/regression/ee_584.rs index 325d19b791..f2d532e8d0 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_584.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_584.rs @@ -6,7 +6,8 @@ use casper_types::{execution::TransformKindV2, RuntimeArgs, StoredValue}; const CONTRACT_EE_584_REGRESSION: &str = "ee_584_regression.wasm"; #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_run_ee_584_no_errored_session_transforms() { let exec_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, diff --git a/execution_engine_testing/tests/src/test/regression/gh_1902.rs b/execution_engine_testing/tests/src/test/regression/gh_1902.rs index ae620241ae..e36f9186a9 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1902.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1902.rs @@ -89,7 +89,8 @@ fn exec_and_assert_costs( } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_not_charge_for_create_purse_in_first_time_bond() { let mut builder = setup(); diff --git a/execution_engine_testing/tests/src/test/regression/gov_42.rs b/execution_engine_testing/tests/src/test/regression/gov_42.rs index c201c6e198..2ecf7f8609 100644 --- a/execution_engine_testing/tests/src/test/regression/gov_42.rs +++ b/execution_engine_testing/tests/src/test/regression/gov_42.rs @@ -107,7 +107,8 @@ fn run_test_case(input_wasm_bytes: &[u8], expected_error: &str, execution_phase: } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_charge_payment_with_incorrect_wasm_file_invalid_magic_number() { const WASM_BYTES: &[u8] = &[1, 2, 3, 4, 5]; // Correct WASM magic bytes are: 0x00 0x61 0x73 0x6d ("\0asm") let execution_phase = ExecutionPhase::Payment; @@ -116,7 +117,8 @@ fn should_charge_payment_with_incorrect_wasm_file_invalid_magic_number() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_charge_session_with_incorrect_wasm_file_invalid_magic_number() { const WASM_BYTES: &[u8] = &[1, 2, 3, 4, 5]; // Correct WASM magic bytes are: 0x00 0x61 0x73 0x6d ("\0asm") let execution_phase = ExecutionPhase::Session; @@ -125,8 +127,9 @@ fn should_charge_session_with_incorrect_wasm_file_invalid_magic_number() { } #[ignore] -#[test] -fn should_charge_payment_with_incorrect_wasm_file_empty_bytes() { +#[allow(unused)] +// #[test] +fn should_fail_to_charge_payment_with_incorrect_wasm_file_empty_bytes() { const WASM_BYTES: &[u8] = &[]; let execution_phase = ExecutionPhase::Payment; let expected_error = "I/O Error: UnexpectedEof"; @@ -134,7 +137,8 @@ fn should_charge_payment_with_incorrect_wasm_file_empty_bytes() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_charge_session_with_incorrect_wasm_file_empty_bytes() { const WASM_BYTES: &[u8] = &[]; let execution_phase = ExecutionPhase::Session; @@ -143,7 +147,8 @@ fn should_charge_session_with_incorrect_wasm_file_empty_bytes() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_charge_payment_with_incorrect_wasm_correct_magic_number_incomplete_module() { const WASM_BYTES: &[u8] = &[ 0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x01, 0x35, 0x09, 0x60, 0x02, 0x7F, 0x7F, @@ -163,7 +168,8 @@ fn should_charge_payment_with_incorrect_wasm_correct_magic_number_incomplete_mod } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_charge_session_with_incorrect_wasm_correct_magic_number_incomplete_module() { const WASM_BYTES: &[u8] = &[ 0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x01, 0x35, 0x09, 0x60, 0x02, 0x7F, 0x7F, @@ -183,7 +189,8 @@ fn should_charge_session_with_incorrect_wasm_correct_magic_number_incomplete_mod } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_charge_payment_with_incorrect_wasm_gas_counter_overflow() { let wasm_bytes = make_gas_counter_overflow(); let execution_phase = ExecutionPhase::Payment; @@ -192,7 +199,8 @@ fn should_charge_payment_with_incorrect_wasm_gas_counter_overflow() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_charge_session_with_incorrect_wasm_gas_counter_overflow() { let wasm_bytes = make_gas_counter_overflow(); let execution_phase = ExecutionPhase::Session; @@ -201,7 +209,8 @@ fn should_charge_session_with_incorrect_wasm_gas_counter_overflow() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_charge_payment_with_incorrect_wasm_no_memory_section() { let wasm_bytes = make_module_without_memory_section(); let execution_phase = ExecutionPhase::Payment; @@ -210,7 +219,8 @@ fn should_charge_payment_with_incorrect_wasm_no_memory_section() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_charge_session_with_incorrect_wasm_no_memory_section() { let wasm_bytes = make_module_without_memory_section(); let execution_phase = ExecutionPhase::Session; @@ -219,7 +229,8 @@ fn should_charge_session_with_incorrect_wasm_no_memory_section() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_charge_payment_with_incorrect_wasm_start_section() { let wasm_bytes = make_module_with_start_section(); let execution_phase = ExecutionPhase::Payment; @@ -228,7 +239,8 @@ fn should_charge_payment_with_incorrect_wasm_start_section() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_charge_session_with_incorrect_wasm_start_section() { let wasm_bytes = make_module_with_start_section(); let execution_phase = ExecutionPhase::Session; diff --git a/execution_engine_testing/tests/src/test/regression/regression_20210707.rs b/execution_engine_testing/tests/src/test/regression/regression_20210707.rs index 3f061c664f..61b06555cb 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20210707.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20210707.rs @@ -342,7 +342,8 @@ fn should_not_transfer_from_hardcoded_purse() { } #[ignore] -#[test] +#[allow(unused)] +//#[test] fn should_not_refund_to_bob_and_charge_alice() { let mut builder = LmdbWasmTestBuilder::default(); @@ -381,7 +382,6 @@ fn should_not_refund_to_bob_and_charge_alice() { }; let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) - // Just do nothing if ever we'd get into session execution .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) .with_stored_payment_hash(contract_hash, METHOD_STORED_PAYMENT, args) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) @@ -398,7 +398,8 @@ fn should_not_refund_to_bob_and_charge_alice() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_not_charge_alice_for_execution() { let mut builder = LmdbWasmTestBuilder::default(); @@ -454,7 +455,8 @@ fn should_not_charge_alice_for_execution() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_not_charge_for_execution_from_hardcoded_purse() { let mut builder = LmdbWasmTestBuilder::default(); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20210924.rs b/execution_engine_testing/tests/src/test/regression/regression_20210924.rs index d901a87b54..cfb776d4d4 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20210924.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20210924.rs @@ -10,7 +10,8 @@ use crate::wasm_utils; const ARG_AMOUNT: &str = "amount"; #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_charge_minimum_for_do_nothing_session() { let minimum_deploy_payment = U512::from(0); @@ -65,7 +66,8 @@ fn should_charge_minimum_for_do_nothing_session() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_execute_do_minimum_session() { let minimum_deploy_payment = U512::from(DEFAULT_NOP_COST); @@ -116,7 +118,8 @@ fn should_execute_do_minimum_session() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_charge_minimum_for_do_nothing_payment() { let minimum_deploy_payment = U512::from(0); diff --git a/execution_engine_testing/tests/src/test/storage_costs.rs b/execution_engine_testing/tests/src/test/storage_costs.rs index fdd8ac6624..0006f6ae49 100644 --- a/execution_engine_testing/tests/src/test/storage_costs.rs +++ b/execution_engine_testing/tests/src/test/storage_costs.rs @@ -677,7 +677,8 @@ fn should_measure_unisolated_gas_cost_for_storage_usage_add() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_verify_new_uref_is_charging_for_storage() { let mut builder = initialize_isolated_storage_costs(); @@ -719,7 +720,8 @@ fn should_verify_new_uref_is_charging_for_storage() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_verify_put_key_is_charging_for_storage() { let mut builder = initialize_isolated_storage_costs(); @@ -761,7 +763,8 @@ fn should_verify_put_key_is_charging_for_storage() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_verify_remove_key_is_charging_for_storage() { let mut builder = initialize_isolated_storage_costs(); @@ -803,7 +806,8 @@ fn should_verify_remove_key_is_charging_for_storage() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_verify_create_contract_at_hash_is_charging_for_storage() { let mut builder = initialize_isolated_storage_costs(); @@ -845,7 +849,8 @@ fn should_verify_create_contract_at_hash_is_charging_for_storage() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_verify_create_contract_user_group_is_charging_for_storage() { let mut builder = initialize_isolated_storage_costs(); @@ -919,7 +924,8 @@ fn should_verify_create_contract_user_group_is_charging_for_storage() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_verify_subcall_new_uref_is_charging_for_storage() { let mut builder = initialize_isolated_storage_costs(); diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs b/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs index d050092b63..c55a9df9b7 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs @@ -731,7 +731,8 @@ fn should_withdraw_bids_after_distribute() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_distribute_rewards_after_restaking_delegated_funds() { const VALIDATOR_1_STAKE: u64 = 7_000_000_000_000_000; const DELEGATOR_1_STAKE: u64 = 5_000_000_000_000_000; diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs b/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs index 47440a51d3..e478a7736a 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction_bidding.rs @@ -241,7 +241,8 @@ fn should_fail_bonding_with_insufficient_funds_directly() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_fail_bonding_with_insufficient_funds() { let account_1_secret_key = SecretKey::ed25519_from_bytes([123; SecretKey::ED25519_LENGTH]).unwrap(); diff --git a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/finalize_payment.rs b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/finalize_payment.rs index ff2612421d..bee2c2a74d 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/finalize_payment.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/finalize_payment.rs @@ -79,7 +79,8 @@ fn finalize_payment_should_not_be_run_by_non_system_accounts() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn finalize_payment_should_refund_to_specified_purse() { let mut builder = LmdbWasmTestBuilder::default(); let payment_amount = *DEFAULT_PAYMENT; diff --git a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/get_payment_purse.rs b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/get_payment_purse.rs index 9f1bee804a..4b5219067b 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/handle_payment/get_payment_purse.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/handle_payment/get_payment_purse.rs @@ -12,7 +12,8 @@ const ARG_AMOUNT: &str = "amount"; const ARG_TARGET: &str = "target"; #[ignore] -#[test] +#[allow(unused)] +//#[test] fn should_run_get_payment_purse_contract_default_account() { let exec_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -30,7 +31,8 @@ fn should_run_get_payment_purse_contract_default_account() { } #[ignore] -#[test] +#[allow(unused)] +//#[test] fn should_run_get_payment_purse_contract_account_1() { let exec_request_1 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, diff --git a/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs b/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs index 3c7e5f454a..447919a402 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs @@ -25,7 +25,8 @@ const ARG_AMOUNT: &str = "amount"; const ARG_TARGET: &str = "target"; #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_raise_insufficient_payment_when_caller_lacks_minimum_balance() { let account_1_account_hash = ACCOUNT_1_ADDR; @@ -73,7 +74,8 @@ fn should_raise_insufficient_payment_when_caller_lacks_minimum_balance() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_forward_payment_execution_runtime_error() { let account_1_account_hash = ACCOUNT_1_ADDR; let transferred_amount = U512::from(1); @@ -136,7 +138,8 @@ fn should_forward_payment_execution_runtime_error() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_forward_payment_execution_gas_limit_error() { let account_1_account_hash = ACCOUNT_1_ADDR; let transferred_amount = U512::from(1); @@ -206,7 +209,8 @@ fn should_forward_payment_execution_gas_limit_error() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_run_out_of_gas_when_session_code_exceeds_gas_limit() { let account_1_account_hash = ACCOUNT_1_ADDR; let payment_purse_amount = *DEFAULT_PAYMENT; @@ -248,7 +252,8 @@ fn should_run_out_of_gas_when_session_code_exceeds_gas_limit() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_correctly_charge_when_session_code_runs_out_of_gas() { let payment_purse_amount = *DEFAULT_PAYMENT; @@ -306,7 +311,8 @@ fn should_correctly_charge_when_session_code_runs_out_of_gas() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_correctly_charge_when_session_code_fails() { let account_1_account_hash = ACCOUNT_1_ADDR; let payment_purse_amount = *DEFAULT_PAYMENT; @@ -354,7 +360,8 @@ fn should_correctly_charge_when_session_code_fails() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_correctly_charge_when_session_code_succeeds() { let account_1_account_hash = ACCOUNT_1_ADDR; let payment_purse_amount = *DEFAULT_PAYMENT; @@ -409,7 +416,8 @@ fn should_correctly_charge_when_session_code_succeeds() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn should_finalize_to_rewards_purse() { let account_1_account_hash = ACCOUNT_1_ADDR; let payment_purse_amount = *DEFAULT_PAYMENT; @@ -445,7 +453,8 @@ fn should_finalize_to_rewards_purse() { } #[ignore] -#[test] +#[allow(unused)] +// #[test] fn independent_standard_payments_should_not_write_the_same_keys() { let account_1_account_hash = ACCOUNT_1_ADDR; let payment_purse_amount = *DEFAULT_PAYMENT; diff --git a/execution_engine_testing/tests/src/test/system_contracts/upgrade.rs b/execution_engine_testing/tests/src/test/system_contracts/upgrade.rs index 59f116617e..1e4296a99c 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/upgrade.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/upgrade.rs @@ -25,55 +25,6 @@ use casper_types::{ const PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::V1_0_0; const DEFAULT_ACTIVATION_POINT: EraId = EraId::new(1); const ARG_ACCOUNT: &str = "account"; -// -// fn get_upgraded_wasm_config() -> WasmConfig { -// let opcode_cost = OpcodeCosts { -// bit: DEFAULT_BIT_COST + 1, -// add: DEFAULT_ADD_COST + 1, -// mul: DEFAULT_MUL_COST + 1, -// div: DEFAULT_DIV_COST + 1, -// load: DEFAULT_LOAD_COST + 1, -// store: DEFAULT_STORE_COST + 1, -// op_const: DEFAULT_CONST_COST + 1, -// local: DEFAULT_LOCAL_COST + 1, -// global: DEFAULT_GLOBAL_COST + 1, -// control_flow: ControlFlowCosts { -// block: DEFAULT_CONTROL_FLOW_BLOCK_OPCODE + 1, -// op_loop: DEFAULT_CONTROL_FLOW_LOOP_OPCODE + 1, -// op_if: DEFAULT_CONTROL_FLOW_IF_OPCODE + 1, -// op_else: DEFAULT_CONTROL_FLOW_ELSE_OPCODE + 1, -// end: DEFAULT_CONTROL_FLOW_END_OPCODE + 1, -// br: DEFAULT_CONTROL_FLOW_BR_OPCODE + 1, -// br_if: DEFAULT_CONTROL_FLOW_BR_IF_OPCODE + 1, -// br_table: BrTableCost { -// cost: DEFAULT_CONTROL_FLOW_BR_TABLE_OPCODE + 1, -// size_multiplier: DEFAULT_CONTROL_FLOW_BR_TABLE_MULTIPLIER + 1, -// }, -// op_return: DEFAULT_CONTROL_FLOW_RETURN_OPCODE + 1, -// call: DEFAULT_CONTROL_FLOW_CALL_OPCODE + 1, -// call_indirect: DEFAULT_CONTROL_FLOW_CALL_INDIRECT_OPCODE + 1, -// drop: DEFAULT_CONTROL_FLOW_DROP_OPCODE + 1, -// select: DEFAULT_CONTROL_FLOW_SELECT_OPCODE + 1, -// }, -// integer_comparison: DEFAULT_INTEGER_COMPARISON_COST + 1, -// conversion: DEFAULT_CONVERSION_COST + 1, -// unreachable: DEFAULT_UNREACHABLE_COST + 1, -// nop: DEFAULT_NOP_COST + 1, -// current_memory: DEFAULT_CURRENT_MEMORY_COST + 1, -// grow_memory: DEFAULT_GROW_MEMORY_COST + 1, -// }; -// let storage_costs = StorageCosts::default(); -// let host_function_costs = HostFunctionCosts::default(); -// let messages_limits = MessageLimits::default(); -// WasmConfig::new( -// DEFAULT_WASM_MAX_MEMORY, -// DEFAULT_MAX_STACK_HEIGHT * 2, -// opcode_cost, -// storage_costs, -// host_function_costs, -// messages_limits, -// ) -// } #[ignore] #[test] diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 86eb178600..2ca87cc107 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -156,8 +156,7 @@ pub fn execute_finalized_block( // load contract & check entry point, if it pays use contract main purse // if custom payment, attempt execute custom payment // if custom payment fails, take remaining balance up to amount - // currently contracts cannot provide custom payment, but considering adding it in - // future + // currently contracts cannot provide custom payment, but possible future use match (is_account_session, is_standard_payment) { (ACCOUNT_SESSION, STANDARD_PAYMENT) => { // this is the typical scenario; the initiating account pays using its main diff --git a/node/src/components/transaction_acceptor.rs b/node/src/components/transaction_acceptor.rs index f3f16a1017..88bf938eb9 100644 --- a/node/src/components/transaction_acceptor.rs +++ b/node/src/components/transaction_acceptor.rs @@ -530,14 +530,14 @@ impl TransactionAcceptor { } Transaction::V1(txn) => match txn.target() { TransactionTarget::Stored { id, .. } => match id { - TransactionInvocationTarget::InvocableEntity(entity_addr) => { + TransactionInvocationTarget::ByHash(entity_addr) => { NextStep::GetContract(EntityAddr::SmartContract(*entity_addr)) } - TransactionInvocationTarget::Package { addr, version } => { + TransactionInvocationTarget::ByPackageHash { addr, version } => { NextStep::GetPackage(*addr, *version) } - TransactionInvocationTarget::InvocableEntityAlias(_) - | TransactionInvocationTarget::PackageAlias { .. } => { + TransactionInvocationTarget::ByName(_) + | TransactionInvocationTarget::ByPackageName { .. } => { NextStep::CryptoValidation } }, diff --git a/types/src/cl_value.rs b/types/src/cl_value.rs index c1735bdfc9..9d7fa8302e 100644 --- a/types/src/cl_value.rs +++ b/types/src/cl_value.rs @@ -425,8 +425,7 @@ mod tests { r#"{"cl_type":"Key","parsed":"uref-0303030303030303030303030303030303030303030303030303030303030303-001"}"#, ); - let key_transfer = - Key::LegacyTransfer(TransferV1Addr::new([4; TRANSFER_V1_ADDR_LENGTH])); + let key_transfer = Key::Transfer(TransferV1Addr::new([4; TRANSFER_V1_ADDR_LENGTH])); check_to_json( key_transfer, r#"{"cl_type":"Key","parsed":"transfer-0404040404040404040404040404040404040404040404040404040404040404"}"#, @@ -648,8 +647,7 @@ mod tests { r#"{"cl_type":{"Option":"Key"},"parsed":"uref-0303030303030303030303030303030303030303030303030303030303030303-001"}"#, ); - let key_transfer = - Key::LegacyTransfer(TransferV1Addr::new([4; TRANSFER_V1_ADDR_LENGTH])); + let key_transfer = Key::Transfer(TransferV1Addr::new([4; TRANSFER_V1_ADDR_LENGTH])); check_to_json( Some(key_transfer), r#"{"cl_type":{"Option":"Key"},"parsed":"transfer-0404040404040404040404040404040404040404040404040404040404040404"}"#, diff --git a/types/src/gens.rs b/types/src/gens.rs index 6d67bdcc6a..f5bb41d999 100644 --- a/types/src/gens.rs +++ b/types/src/gens.rs @@ -110,7 +110,7 @@ pub fn key_arb() -> impl Strategy { account_hash_arb().prop_map(Key::Account), u8_slice_32().prop_map(Key::Hash), uref_arb().prop_map(Key::URef), - transfer_v1_addr_arb().prop_map(Key::LegacyTransfer), + transfer_v1_addr_arb().prop_map(Key::Transfer), deploy_hash_arb().prop_map(Key::DeployInfo), era_id_arb().prop_map(Key::EraInfo), uref_arb().prop_map(|uref| Key::Balance(uref.addr())), @@ -128,7 +128,7 @@ pub fn colliding_key_arb() -> impl Strategy { u2_slice_32().prop_map(|bytes| Key::Account(AccountHash::new(bytes))), u2_slice_32().prop_map(Key::Hash), u2_slice_32().prop_map(|bytes| Key::URef(URef::new(bytes, AccessRights::NONE))), - u2_slice_32().prop_map(|bytes| Key::LegacyTransfer(TransferV1Addr::new(bytes))), + u2_slice_32().prop_map(|bytes| Key::Transfer(TransferV1Addr::new(bytes))), u2_slice_32().prop_map(Key::Dictionary), ] } diff --git a/types/src/key.rs b/types/src/key.rs index 2c9a7e0211..0065ae8857 100644 --- a/types/src/key.rs +++ b/types/src/key.rs @@ -78,7 +78,7 @@ const BLOCK_MESSAGE_COUNT_PREFIX: &str = "block-message-count-"; pub const BLAKE2B_DIGEST_LENGTH: usize = 32; /// The number of bytes in a [`Key::Hash`]. pub const KEY_HASH_LENGTH: usize = 32; -/// The number of bytes in a [`Key::LegacyTransfer`]. +/// The number of bytes in a [`Key::Transfer`]. pub const KEY_LEGACY_TRANSFER_LENGTH: usize = TRANSFER_V1_ADDR_LENGTH; /// The number of bytes in a [`Key::DeployInfo`]. pub const KEY_DEPLOY_INFO_LENGTH: usize = DeployHash::LENGTH; @@ -284,8 +284,8 @@ pub enum Key { Hash(HashAddr), /// A `Key` which is a [`URef`], under which most types of data can be stored. URef(URef), - /// A `Key` under which a version 1 (legacy) transfer is stored. - LegacyTransfer(TransferV1Addr), + /// A `Key` under which a (legacy) transfer is stored. + Transfer(TransferV1Addr), /// A `Key` under which a deploy info is stored. DeployInfo(DeployHash), /// A `Key` under which an era info is stored. @@ -488,7 +488,7 @@ impl Key { Key::Account(_) => String::from("Key::Account"), Key::Hash(_) => String::from("Key::Hash"), Key::URef(_) => String::from("Key::URef"), - Key::LegacyTransfer(_) => String::from("Key::LegacyTransfer"), + Key::Transfer(_) => String::from("Key::LegacyTransfer"), Key::DeployInfo(_) => String::from("Key::DeployInfo"), Key::EraInfo(_) => String::from("Key::EraInfo"), Key::Balance(_) => String::from("Key::Balance"), @@ -533,7 +533,7 @@ impl Key { Key::Account(account_hash) => account_hash.to_formatted_string(), Key::Hash(addr) => format!("{}{}", HASH_PREFIX, base16::encode_lower(&addr)), Key::URef(uref) => uref.to_formatted_string(), - Key::LegacyTransfer(transfer_v1_addr) => { + Key::Transfer(transfer_v1_addr) => { format!( "{}{}", LEGACY_TRANSFER_PREFIX, @@ -656,7 +656,7 @@ impl Key { .map_err(|error| FromStrError::LegacyTransfer(TransferFromStrError::from(error)))?; let addr_array = <[u8; TRANSFER_V1_ADDR_LENGTH]>::try_from(v1_addr.as_ref()) .map_err(|error| FromStrError::LegacyTransfer(TransferFromStrError::from(error)))?; - return Ok(Key::LegacyTransfer(TransferV1Addr::new(addr_array))); + return Ok(Key::Transfer(TransferV1Addr::new(addr_array))); } match URef::from_formatted_str(input) { @@ -1223,7 +1223,7 @@ impl Display for Key { Key::Account(account_hash) => write!(f, "Key::Account({})", account_hash), Key::Hash(addr) => write!(f, "Key::Hash({})", base16::encode_lower(&addr)), Key::URef(uref) => write!(f, "Key::{}", uref), /* Display impl for URef will append */ - Key::LegacyTransfer(transfer_v1_addr) => { + Key::Transfer(transfer_v1_addr) => { write!(f, "Key::LegacyTransfer({})", transfer_v1_addr) } Key::DeployInfo(addr) => write!( @@ -1308,7 +1308,7 @@ impl Tagged for Key { Key::Account(_) => KeyTag::Account, Key::Hash(_) => KeyTag::Hash, Key::URef(_) => KeyTag::URef, - Key::LegacyTransfer(_) => KeyTag::LegacyTransfer, + Key::Transfer(_) => KeyTag::LegacyTransfer, Key::DeployInfo(_) => KeyTag::DeployInfo, Key::EraInfo(_) => KeyTag::EraInfo, Key::Balance(_) => KeyTag::Balance, @@ -1407,7 +1407,7 @@ impl ToBytes for Key { } Key::Hash(_) => KEY_HASH_SERIALIZED_LENGTH, Key::URef(_) => KEY_UREF_SERIALIZED_LENGTH, - Key::LegacyTransfer(_) => KEY_LEGACY_TRANSFER_SERIALIZED_LENGTH, + Key::Transfer(_) => KEY_LEGACY_TRANSFER_SERIALIZED_LENGTH, Key::DeployInfo(_) => KEY_DEPLOY_INFO_SERIALIZED_LENGTH, Key::EraInfo(_) => KEY_ERA_INFO_SERIALIZED_LENGTH, Key::Balance(_) => KEY_BALANCE_SERIALIZED_LENGTH, @@ -1419,12 +1419,7 @@ impl ToBytes for Key { Key::Unbond(_) => KEY_UNBOND_SERIALIZED_LENGTH, Key::ChainspecRegistry => KEY_CHAINSPEC_REGISTRY_SERIALIZED_LENGTH, Key::ChecksumRegistry => KEY_CHECKSUM_REGISTRY_SERIALIZED_LENGTH, - Key::BidAddr(bid_addr) => match bid_addr.tag() { - BidAddrTag::Unified => KEY_ID_SERIALIZED_LENGTH + bid_addr.serialized_length() - 1, - BidAddrTag::Validator | BidAddrTag::Delegator => { - KEY_ID_SERIALIZED_LENGTH + bid_addr.serialized_length() - } - }, + Key::BidAddr(bid_addr) => KEY_ID_SERIALIZED_LENGTH + bid_addr.serialized_length(), Key::Package(_) => KEY_PACKAGE_SERIALIZED_LENGTH, Key::AddressableEntity(entity_addr) => { KEY_ID_SERIALIZED_LENGTH + entity_addr.serialized_length() @@ -1451,7 +1446,7 @@ impl ToBytes for Key { Key::Account(account_hash) => account_hash.write_bytes(writer), Key::Hash(hash) => hash.write_bytes(writer), Key::URef(uref) => uref.write_bytes(writer), - Key::LegacyTransfer(addr) => addr.write_bytes(writer), + Key::Transfer(addr) => addr.write_bytes(writer), Key::DeployInfo(deploy_hash) => deploy_hash.write_bytes(writer), Key::EraInfo(era_id) => era_id.write_bytes(writer), Key::Balance(uref_addr) => uref_addr.write_bytes(writer), @@ -1464,14 +1459,7 @@ impl ToBytes for Key { | Key::ChainspecRegistry | Key::ChecksumRegistry | Key::BlockMessageCount => PADDING_BYTES.write_bytes(writer), - Key::BidAddr(bid_addr) => match bid_addr.tag() { - BidAddrTag::Unified => { - let bytes = bid_addr.to_bytes()?; - writer.extend(&bytes[1..]); - Ok(()) - } - BidAddrTag::Validator | BidAddrTag::Delegator => bid_addr.write_bytes(writer), - }, + Key::BidAddr(bid_addr) => bid_addr.write_bytes(writer), Key::Package(package_addr) => package_addr.write_bytes(writer), Key::AddressableEntity(entity_addr) => entity_addr.write_bytes(writer), Key::ByteCode(byte_code_addr) => byte_code_addr.write_bytes(writer), @@ -1500,7 +1488,7 @@ impl FromBytes for Key { } KeyTag::LegacyTransfer => { let (transfer_v1_addr, rem) = TransferV1Addr::from_bytes(remainder)?; - Ok((Key::LegacyTransfer(transfer_v1_addr), rem)) + Ok((Key::Transfer(transfer_v1_addr), rem)) } KeyTag::DeployInfo => { let (deploy_hash, rem) = DeployHash::from_bytes(remainder)?; @@ -1590,7 +1578,7 @@ fn please_add_to_distribution_impl(key: Key) { Key::Account(_) => unimplemented!(), Key::Hash(_) => unimplemented!(), Key::URef(_) => unimplemented!(), - Key::LegacyTransfer(_) => unimplemented!(), + Key::Transfer(_) => unimplemented!(), Key::DeployInfo(_) => unimplemented!(), Key::EraInfo(_) => unimplemented!(), Key::Balance(_) => unimplemented!(), @@ -1620,7 +1608,7 @@ impl Distribution for Standard { 0 => Key::Account(rng.gen()), 1 => Key::Hash(rng.gen()), 2 => Key::URef(rng.gen()), - 3 => Key::LegacyTransfer(TransferV1Addr::new(rng.gen())), + 3 => Key::Transfer(TransferV1Addr::new(rng.gen())), 4 => Key::DeployInfo(DeployHash::from_raw(rng.gen())), 5 => Key::EraInfo(EraId::new(rng.gen())), 6 => Key::Balance(rng.gen()), @@ -1710,7 +1698,7 @@ mod serde_helpers { Key::Account(account_hash) => BinarySerHelper::Account(account_hash), Key::Hash(hash_addr) => BinarySerHelper::Hash(hash_addr), Key::URef(uref) => BinarySerHelper::URef(uref), - Key::LegacyTransfer(transfer_v1_addr) => { + Key::Transfer(transfer_v1_addr) => { BinarySerHelper::LegacyTransfer(transfer_v1_addr) } Key::DeployInfo(deploy_hash) => BinarySerHelper::DeployInfo(deploy_hash), @@ -1747,7 +1735,7 @@ mod serde_helpers { BinaryDeserHelper::Hash(hash_addr) => Key::Hash(hash_addr), BinaryDeserHelper::URef(uref) => Key::URef(uref), BinaryDeserHelper::LegacyTransfer(transfer_v1_addr) => { - Key::LegacyTransfer(transfer_v1_addr) + Key::Transfer(transfer_v1_addr) } BinaryDeserHelper::DeployInfo(deploy_hash) => Key::DeployInfo(deploy_hash), BinaryDeserHelper::EraInfo(era_id) => Key::EraInfo(era_id), @@ -1821,7 +1809,7 @@ mod tests { const ACCOUNT_KEY: Key = Key::Account(AccountHash::new([42; 32])); const HASH_KEY: Key = Key::Hash([42; 32]); const UREF_KEY: Key = Key::URef(URef::new([42; 32], AccessRights::READ)); - const LEGACY_TRANSFER_KEY: Key = Key::LegacyTransfer(TransferV1Addr::new([42; 32])); + const TRANSFER_KEY: Key = Key::Transfer(TransferV1Addr::new([42; 32])); const DEPLOY_INFO_KEY: Key = Key::DeployInfo(DeployHash::from_raw([42; 32])); const ERA_INFO_KEY: Key = Key::EraInfo(EraId::new(42)); const BALANCE_KEY: Key = Key::Balance([42; 32]); @@ -1865,7 +1853,7 @@ mod tests { ACCOUNT_KEY, HASH_KEY, UREF_KEY, - LEGACY_TRANSFER_KEY, + TRANSFER_KEY, DEPLOY_INFO_KEY, ERA_INFO_KEY, BALANCE_KEY, @@ -1963,7 +1951,7 @@ mod tests { format!("Key::URef({}, READ)", HEX_STRING) ); assert_eq!( - format!("{}", LEGACY_TRANSFER_KEY), + format!("{}", TRANSFER_KEY), format!("Key::LegacyTransfer({})", HEX_STRING) ); assert_eq!( @@ -2411,7 +2399,7 @@ mod tests { round_trip(&Key::Account(AccountHash::new(zeros))); round_trip(&Key::Hash(zeros)); round_trip(&Key::URef(URef::new(zeros, AccessRights::READ))); - round_trip(&Key::LegacyTransfer(TransferV1Addr::new(zeros))); + round_trip(&Key::Transfer(TransferV1Addr::new(zeros))); round_trip(&Key::DeployInfo(DeployHash::from_raw(zeros))); round_trip(&Key::EraInfo(EraId::from(0))); round_trip(&Key::Balance(URef::new(zeros, AccessRights::READ).addr())); @@ -2443,4 +2431,35 @@ mod tests { round_trip(&Key::BlockMessageCount); round_trip(&Key::BalanceHold(BalanceHoldAddr::default())); } + + #[test] + fn bytesrepr_serialization_roundtrip() { + bytesrepr::test_serialization_roundtrip(&ACCOUNT_KEY); + bytesrepr::test_serialization_roundtrip(&HASH_KEY); + bytesrepr::test_serialization_roundtrip(&UREF_KEY); + bytesrepr::test_serialization_roundtrip(&TRANSFER_KEY); + bytesrepr::test_serialization_roundtrip(&DEPLOY_INFO_KEY); + bytesrepr::test_serialization_roundtrip(&ERA_INFO_KEY); + bytesrepr::test_serialization_roundtrip(&BALANCE_KEY); + bytesrepr::test_serialization_roundtrip(&BID_KEY); + bytesrepr::test_serialization_roundtrip(&WITHDRAW_KEY); + bytesrepr::test_serialization_roundtrip(&DICTIONARY_KEY); + bytesrepr::test_serialization_roundtrip(&SYSTEM_ENTITY_REGISTRY_KEY); + bytesrepr::test_serialization_roundtrip(&ERA_SUMMARY_KEY); + bytesrepr::test_serialization_roundtrip(&UNBOND_KEY); + bytesrepr::test_serialization_roundtrip(&CHAINSPEC_REGISTRY_KEY); + bytesrepr::test_serialization_roundtrip(&CHECKSUM_REGISTRY_KEY); + bytesrepr::test_serialization_roundtrip(&UNIFIED_BID_KEY); + bytesrepr::test_serialization_roundtrip(&VALIDATOR_BID_KEY); + bytesrepr::test_serialization_roundtrip(&DELEGATOR_BID_KEY); + bytesrepr::test_serialization_roundtrip(&PACKAGE_KEY); + bytesrepr::test_serialization_roundtrip(&ADDRESSABLE_ENTITY_SYSTEM_KEY); + bytesrepr::test_serialization_roundtrip(&ADDRESSABLE_ENTITY_ACCOUNT_KEY); + bytesrepr::test_serialization_roundtrip(&ADDRESSABLE_ENTITY_SMART_CONTRACT_KEY); + bytesrepr::test_serialization_roundtrip(&BYTE_CODE_EMPTY_KEY); + bytesrepr::test_serialization_roundtrip(&BYTE_CODE_V1_WASM_KEY); + bytesrepr::test_serialization_roundtrip(&MESSAGE_TOPIC_KEY); + bytesrepr::test_serialization_roundtrip(&MESSAGE_KEY); + bytesrepr::test_serialization_roundtrip(&NAMED_KEY); + } } diff --git a/types/src/system/caller.rs b/types/src/system/caller.rs index 53f7b371b7..a5e9baf302 100644 --- a/types/src/system/caller.rs +++ b/types/src/system/caller.rs @@ -14,9 +14,9 @@ use crate::{ #[derive(FromPrimitive, ToPrimitive)] #[repr(u8)] pub enum CallerTag { - /// Session tag. + /// Initiator tag. Initiator = 0, - /// StoredContract tag. + /// Entity tag. Entity, } diff --git a/types/src/transaction/transaction_invocation_target.rs b/types/src/transaction/transaction_invocation_target.rs index 565680b661..e890802c7f 100644 --- a/types/src/transaction/transaction_invocation_target.rs +++ b/types/src/transaction/transaction_invocation_target.rs @@ -45,11 +45,11 @@ pub enum TransactionInvocationTarget { description = "Hex-encoded entity address identifying the invocable entity." ) )] - InvocableEntity(HashAddr), // currently needs to be of contract tag variant + ByHash(HashAddr), // currently needs to be of contract tag variant /// The alias identifying the invocable entity. - InvocableEntityAlias(String), + ByName(String), /// The address and optional version identifying the package. - Package { + ByPackageHash { /// The package address. #[serde(with = "serde_helpers::raw_32_byte_array")] #[cfg_attr( @@ -63,9 +63,9 @@ pub enum TransactionInvocationTarget { version: Option, }, /// The alias and optional version identifying the package. - PackageAlias { + ByPackageName { /// The package alias. - alias: String, + name: String, /// The package version. /// /// If `None`, the latest enabled version is implied. @@ -76,17 +76,17 @@ pub enum TransactionInvocationTarget { impl TransactionInvocationTarget { /// Returns a new `TransactionInvocationTarget::InvocableEntity`. pub fn new_invocable_entity(hash: AddressableEntityHash) -> Self { - TransactionInvocationTarget::InvocableEntity(hash.value()) + TransactionInvocationTarget::ByHash(hash.value()) } /// Returns a new `TransactionInvocationTarget::InvocableEntityAlias`. pub fn new_invocable_entity_alias(alias: String) -> Self { - TransactionInvocationTarget::InvocableEntityAlias(alias) + TransactionInvocationTarget::ByName(alias) } /// Returns a new `TransactionInvocationTarget::Package`. pub fn new_package(hash: PackageHash, version: Option) -> Self { - TransactionInvocationTarget::Package { + TransactionInvocationTarget::ByPackageHash { addr: hash.value(), version, } @@ -94,40 +94,43 @@ impl TransactionInvocationTarget { /// Returns a new `TransactionInvocationTarget::PackageAlias`. pub fn new_package_alias(alias: String, version: Option) -> Self { - TransactionInvocationTarget::PackageAlias { alias, version } + TransactionInvocationTarget::ByPackageName { + name: alias, + version, + } } /// Returns the identifier of the addressable entity, if present. pub fn addressable_entity_identifier(&self) -> Option { match self { - TransactionInvocationTarget::InvocableEntity(addr) => Some( - AddressableEntityIdentifier::Hash(AddressableEntityHash::new(*addr)), - ), - TransactionInvocationTarget::InvocableEntityAlias(alias) => { + TransactionInvocationTarget::ByHash(addr) => Some(AddressableEntityIdentifier::Hash( + AddressableEntityHash::new(*addr), + )), + TransactionInvocationTarget::ByName(alias) => { Some(AddressableEntityIdentifier::Name(alias.clone())) } - TransactionInvocationTarget::Package { .. } - | TransactionInvocationTarget::PackageAlias { .. } => None, + TransactionInvocationTarget::ByPackageHash { .. } + | TransactionInvocationTarget::ByPackageName { .. } => None, } } /// Returns the identifier of the contract package, if present. pub fn package_identifier(&self) -> Option { match self { - TransactionInvocationTarget::InvocableEntity(_) - | TransactionInvocationTarget::InvocableEntityAlias(_) => None, - TransactionInvocationTarget::Package { addr, version } => { + TransactionInvocationTarget::ByHash(_) | TransactionInvocationTarget::ByName(_) => None, + TransactionInvocationTarget::ByPackageHash { addr, version } => { Some(PackageIdentifier::Hash { package_hash: PackageHash::new(*addr), version: *version, }) } - TransactionInvocationTarget::PackageAlias { alias, version } => { - Some(PackageIdentifier::Name { - name: alias.clone(), - version: *version, - }) - } + TransactionInvocationTarget::ByPackageName { + name: alias, + version, + } => Some(PackageIdentifier::Name { + name: alias.clone(), + version: *version, + }), } } @@ -135,16 +138,16 @@ impl TransactionInvocationTarget { #[cfg(any(feature = "testing", test))] pub fn random(rng: &mut TestRng) -> Self { match rng.gen_range(0..4) { - INVOCABLE_ENTITY_TAG => TransactionInvocationTarget::InvocableEntity(rng.gen()), + INVOCABLE_ENTITY_TAG => TransactionInvocationTarget::ByHash(rng.gen()), INVOCABLE_ENTITY_ALIAS_TAG => { - TransactionInvocationTarget::InvocableEntityAlias(rng.random_string(1..21)) + TransactionInvocationTarget::ByName(rng.random_string(1..21)) } - PACKAGE_TAG => TransactionInvocationTarget::Package { + PACKAGE_TAG => TransactionInvocationTarget::ByPackageHash { addr: rng.gen(), version: rng.gen::().then(|| rng.gen::()), }, - PACKAGE_ALIAS_TAG => TransactionInvocationTarget::PackageAlias { - alias: rng.random_string(1..21), + PACKAGE_ALIAS_TAG => TransactionInvocationTarget::ByPackageName { + name: rng.random_string(1..21), version: rng.gen::().then(|| rng.gen::()), }, _ => unreachable!(), @@ -155,32 +158,32 @@ impl TransactionInvocationTarget { impl Display for TransactionInvocationTarget { fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { match self { - TransactionInvocationTarget::InvocableEntity(addr) => { + TransactionInvocationTarget::ByHash(addr) => { write!(formatter, "invocable-entity({:10})", HexFmt(addr)) } - TransactionInvocationTarget::InvocableEntityAlias(alias) => { + TransactionInvocationTarget::ByName(alias) => { write!(formatter, "invocable-entity({})", alias) } - TransactionInvocationTarget::Package { + TransactionInvocationTarget::ByPackageHash { addr, version: Some(ver), } => { write!(formatter, "package({:10}, version {})", HexFmt(addr), ver) } - TransactionInvocationTarget::Package { + TransactionInvocationTarget::ByPackageHash { addr, version: None, } => { write!(formatter, "package({:10}, latest)", HexFmt(addr)) } - TransactionInvocationTarget::PackageAlias { - alias, + TransactionInvocationTarget::ByPackageName { + name: alias, version: Some(ver), } => { write!(formatter, "package({}, version {})", alias, ver) } - TransactionInvocationTarget::PackageAlias { - alias, + TransactionInvocationTarget::ByPackageName { + name: alias, version: None, } => { write!(formatter, "package({}, latest)", alias) @@ -192,20 +195,23 @@ impl Display for TransactionInvocationTarget { impl Debug for TransactionInvocationTarget { fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { match self { - TransactionInvocationTarget::InvocableEntity(addr) => formatter + TransactionInvocationTarget::ByHash(addr) => formatter .debug_tuple("InvocableEntity") .field(&HexFmt(addr)) .finish(), - TransactionInvocationTarget::InvocableEntityAlias(alias) => formatter + TransactionInvocationTarget::ByName(alias) => formatter .debug_tuple("InvocableEntityAlias") .field(alias) .finish(), - TransactionInvocationTarget::Package { addr, version } => formatter + TransactionInvocationTarget::ByPackageHash { addr, version } => formatter .debug_struct("Package") .field("addr", &HexFmt(addr)) .field("version", version) .finish(), - TransactionInvocationTarget::PackageAlias { alias, version } => formatter + TransactionInvocationTarget::ByPackageName { + name: alias, + version, + } => formatter .debug_struct("PackageAlias") .field("alias", alias) .field("version", version) @@ -217,20 +223,23 @@ impl Debug for TransactionInvocationTarget { impl ToBytes for TransactionInvocationTarget { fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { match self { - TransactionInvocationTarget::InvocableEntity(addr) => { + TransactionInvocationTarget::ByHash(addr) => { INVOCABLE_ENTITY_TAG.write_bytes(writer)?; addr.write_bytes(writer) } - TransactionInvocationTarget::InvocableEntityAlias(alias) => { + TransactionInvocationTarget::ByName(alias) => { INVOCABLE_ENTITY_ALIAS_TAG.write_bytes(writer)?; alias.write_bytes(writer) } - TransactionInvocationTarget::Package { addr, version } => { + TransactionInvocationTarget::ByPackageHash { addr, version } => { PACKAGE_TAG.write_bytes(writer)?; addr.write_bytes(writer)?; version.write_bytes(writer) } - TransactionInvocationTarget::PackageAlias { alias, version } => { + TransactionInvocationTarget::ByPackageName { + name: alias, + version, + } => { PACKAGE_ALIAS_TAG.write_bytes(writer)?; alias.write_bytes(writer)?; version.write_bytes(writer) @@ -247,16 +256,15 @@ impl ToBytes for TransactionInvocationTarget { fn serialized_length(&self) -> usize { U8_SERIALIZED_LENGTH + match self { - TransactionInvocationTarget::InvocableEntity(addr) => addr.serialized_length(), - TransactionInvocationTarget::InvocableEntityAlias(alias) => { - alias.serialized_length() - } - TransactionInvocationTarget::Package { addr, version } => { + TransactionInvocationTarget::ByHash(addr) => addr.serialized_length(), + TransactionInvocationTarget::ByName(alias) => alias.serialized_length(), + TransactionInvocationTarget::ByPackageHash { addr, version } => { addr.serialized_length() + version.serialized_length() } - TransactionInvocationTarget::PackageAlias { alias, version } => { - alias.serialized_length() + version.serialized_length() - } + TransactionInvocationTarget::ByPackageName { + name: alias, + version, + } => alias.serialized_length() + version.serialized_length(), } } } @@ -267,24 +275,30 @@ impl FromBytes for TransactionInvocationTarget { match tag { INVOCABLE_ENTITY_TAG => { let (addr, remainder) = HashAddr::from_bytes(remainder)?; - let target = TransactionInvocationTarget::InvocableEntity(addr); + let target = TransactionInvocationTarget::ByHash(addr); Ok((target, remainder)) } INVOCABLE_ENTITY_ALIAS_TAG => { let (alias, remainder) = String::from_bytes(remainder)?; - let target = TransactionInvocationTarget::InvocableEntityAlias(alias); + let target = TransactionInvocationTarget::ByName(alias); Ok((target, remainder)) } PACKAGE_TAG => { let (addr, remainder) = PackageAddr::from_bytes(remainder)?; let (version, remainder) = Option::::from_bytes(remainder)?; - let target = TransactionInvocationTarget::Package { addr, version }; + let target = TransactionInvocationTarget::ByPackageHash { + addr: addr, + version, + }; Ok((target, remainder)) } PACKAGE_ALIAS_TAG => { let (alias, remainder) = String::from_bytes(remainder)?; let (version, remainder) = Option::::from_bytes(remainder)?; - let target = TransactionInvocationTarget::PackageAlias { alias, version }; + let target = TransactionInvocationTarget::ByPackageName { + name: alias, + version, + }; Ok((target, remainder)) } _ => Err(bytesrepr::Error::Formatting), diff --git a/types/src/transaction/transaction_v1/transaction_v1_body.rs b/types/src/transaction/transaction_v1/transaction_v1_body.rs index 4653ac417a..81295c4830 100644 --- a/types/src/transaction/transaction_v1/transaction_v1_body.rs +++ b/types/src/transaction/transaction_v1/transaction_v1_body.rs @@ -512,7 +512,7 @@ mod tests { let mut check = |entry_point: TransactionEntryPoint| { let stored_target = TransactionTarget::new_stored( - TransactionInvocationTarget::InvocableEntity([0; 32]), + TransactionInvocationTarget::ByHash([0; 32]), TransactionRuntime::VmCasperV1, ); let session_target = TransactionTarget::new_session( diff --git a/utils/validation/src/generators.rs b/utils/validation/src/generators.rs index 13a3f911ea..2f973d228d 100644 --- a/utils/validation/src/generators.rs +++ b/utils/validation/src/generators.rs @@ -205,7 +205,7 @@ pub fn make_abi_test_fixtures() -> Result { const ACCOUNT_KEY: Key = Key::Account(AccountHash::new([42; 32])); const HASH_KEY: Key = Key::Hash([42; 32]); const UREF_KEY: Key = Key::URef(URef::new([42; 32], AccessRights::READ)); - const LEGACY_TRANSFER_KEY: Key = Key::LegacyTransfer(TransferV1Addr::new([42; 32])); + const LEGACY_TRANSFER_KEY: Key = Key::Transfer(TransferV1Addr::new([42; 32])); const DEPLOY_INFO_KEY: Key = Key::DeployInfo(DeployHash::from_raw([42; 32])); const ERA_INFO_KEY: Key = Key::EraInfo(EraId::new(42)); const BALANCE_KEY: Key = Key::Balance([42; 32]); From 8a7fc2415558c4f1c5bd747e238e0f0f3250b1ff Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Mon, 25 Mar 2024 05:00:31 -0700 Subject: [PATCH 35/70] cleanup --- execution_engine/src/engine_state/wasm_v1.rs | 4 ++-- types/src/transaction/transaction_invocation_target.rs | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/execution_engine/src/engine_state/wasm_v1.rs b/execution_engine/src/engine_state/wasm_v1.rs index a5adc00a0a..4766c4873d 100644 --- a/execution_engine/src/engine_state/wasm_v1.rs +++ b/execution_engine/src/engine_state/wasm_v1.rs @@ -533,7 +533,7 @@ impl<'a> TryFrom<(&'a ExecutableDeployItem, &'a DeployHash)> for PaymentInfo<'a> } => Ok(PaymentInfo { payment: ExecutableItem::Stored(TransactionInvocationTarget::ByPackageHash { addr: hash.value(), - version: version.clone(), + version: *version, }), args: args.clone(), }), @@ -545,7 +545,7 @@ impl<'a> TryFrom<(&'a ExecutableDeployItem, &'a DeployHash)> for PaymentInfo<'a> } => Ok(PaymentInfo { payment: ExecutableItem::Stored(TransactionInvocationTarget::ByPackageName { name: name.clone(), - version: version.clone(), + version: *version, }), args: args.clone(), }), diff --git a/types/src/transaction/transaction_invocation_target.rs b/types/src/transaction/transaction_invocation_target.rs index e890802c7f..227b3dd1a7 100644 --- a/types/src/transaction/transaction_invocation_target.rs +++ b/types/src/transaction/transaction_invocation_target.rs @@ -286,10 +286,7 @@ impl FromBytes for TransactionInvocationTarget { PACKAGE_TAG => { let (addr, remainder) = PackageAddr::from_bytes(remainder)?; let (version, remainder) = Option::::from_bytes(remainder)?; - let target = TransactionInvocationTarget::ByPackageHash { - addr: addr, - version, - }; + let target = TransactionInvocationTarget::ByPackageHash { addr, version }; Ok((target, remainder)) } PACKAGE_ALIAS_TAG => { From 779801cd8355f566199573da6e77e8e6b17b17a1 Mon Sep 17 00:00:00 2001 From: Jacek Malec <145967538+jacek-casper@users.noreply.github.com> Date: Mon, 25 Mar 2024 15:34:40 +0000 Subject: [PATCH 36/70] Remove RawBytesSpec from binary port --- binary_port/src/binary_response.rs | 20 +++------ .../src/binary_response_and_request.rs | 10 ++--- binary_port/src/lib.rs | 2 - binary_port/src/payload_type.rs | 2 +- binary_port/src/raw_bytes_spec.rs | 44 ------------------- node/src/components/binary_port.rs | 18 +++++--- node/src/components/storage.rs | 5 +-- node/src/components/storage/utils.rs | 11 +---- node/src/effect.rs | 6 +-- node/src/effect/requests.rs | 6 +-- storage/src/block_store/mod.rs | 4 +- 11 files changed, 34 insertions(+), 94 deletions(-) delete mode 100644 binary_port/src/raw_bytes_spec.rs diff --git a/binary_port/src/binary_response.rs b/binary_port/src/binary_response.rs index 49d02cedad..6d1fddb51d 100644 --- a/binary_port/src/binary_response.rs +++ b/binary_port/src/binary_response.rs @@ -9,7 +9,6 @@ use crate::{ payload_type::{PayloadEntity, PayloadType}, }; -use crate::{raw_bytes_spec::RawBytesSpec, record_id::RecordId}; #[cfg(test)] use casper_types::testing::TestRng; @@ -41,22 +40,13 @@ impl BinaryResponse { /// Creates new binary response from raw bytes. pub fn from_raw_bytes( - record_id: RecordId, - spec: Option, + payload_type: PayloadType, + payload: Vec, protocol_version: ProtocolVersion, ) -> Self { - match spec { - Some(val) => BinaryResponse { - header: BinaryResponseHeader::new( - Some(PayloadType::new_from_record_id(record_id, val.is_legacy())), - protocol_version, - ), - payload: val.raw_bytes(), - }, - None => BinaryResponse { - header: BinaryResponseHeader::new_error(ErrorCode::NotFound, protocol_version), - payload: vec![], - }, + BinaryResponse { + header: BinaryResponseHeader::new(Some(payload_type), protocol_version), + payload, } } diff --git a/binary_port/src/binary_response_and_request.rs b/binary_port/src/binary_response_and_request.rs index f1c988bc9f..a6a25c36f0 100644 --- a/binary_port/src/binary_response_and_request.rs +++ b/binary_port/src/binary_response_and_request.rs @@ -3,7 +3,7 @@ use casper_types::{ ProtocolVersion, }; -use crate::{binary_response::BinaryResponse, payload_type::PayloadEntity, RawBytesSpec}; +use crate::{binary_response::BinaryResponse, payload_type::PayloadEntity, PayloadType}; use crate::record_id::RecordId; #[cfg(test)] @@ -34,8 +34,8 @@ impl BinaryResponseAndRequest { protocol_version: ProtocolVersion, ) -> BinaryResponseAndRequest { let response = BinaryResponse::from_raw_bytes( - record_id, - Some(RawBytesSpec::new_current(&data.to_bytes().unwrap())), + PayloadType::from_record_id(record_id, false), + data.to_bytes().unwrap(), protocol_version, ); Self::new(response, &[]) @@ -48,8 +48,8 @@ impl BinaryResponseAndRequest { protocol_version: ProtocolVersion, ) -> BinaryResponseAndRequest { let response = BinaryResponse::from_raw_bytes( - record_id, - Some(RawBytesSpec::new_legacy(&bincode::serialize(data).unwrap())), + PayloadType::from_record_id(record_id, true), + bincode::serialize(data).unwrap(), protocol_version, ); Self::new(response, &[]) diff --git a/binary_port/src/lib.rs b/binary_port/src/lib.rs index 0af78b33a2..7c90ed77b1 100644 --- a/binary_port/src/lib.rs +++ b/binary_port/src/lib.rs @@ -11,7 +11,6 @@ mod information_request; mod minimal_block_info; mod node_status; mod payload_type; -mod raw_bytes_spec; pub mod record_id; mod speculative_execution_result; mod state_request; @@ -28,7 +27,6 @@ pub use information_request::{InformationRequest, InformationRequestTag}; pub use minimal_block_info::MinimalBlockInfo; pub use node_status::NodeStatus; pub use payload_type::{PayloadEntity, PayloadType}; -pub use raw_bytes_spec::RawBytesSpec; pub use record_id::{RecordId, UnknownRecordId}; pub use speculative_execution_result::SpeculativeExecutionResult; pub use state_request::GlobalStateRequest; diff --git a/binary_port/src/payload_type.rs b/binary_port/src/payload_type.rs index 5dd993f07c..e967022edd 100644 --- a/binary_port/src/payload_type.rs +++ b/binary_port/src/payload_type.rs @@ -106,7 +106,7 @@ pub enum PayloadType { } impl PayloadType { - pub(crate) fn new_from_record_id(record_id: RecordId, is_legacy: bool) -> Self { + pub fn from_record_id(record_id: RecordId, is_legacy: bool) -> Self { match (is_legacy, record_id) { (true, RecordId::BlockHeader) => Self::BlockHeaderV1, (true, RecordId::BlockBody) => Self::BlockBodyV1, diff --git a/binary_port/src/raw_bytes_spec.rs b/binary_port/src/raw_bytes_spec.rs deleted file mode 100644 index 296a19f14b..0000000000 --- a/binary_port/src/raw_bytes_spec.rs +++ /dev/null @@ -1,44 +0,0 @@ -pub use crate::record_id::{RecordId, UnknownRecordId}; - -/// Stores raw bytes along with the flag indicating whether data is in a legacy format or not. -#[derive(Debug)] -pub struct RawBytesSpec { - is_legacy: bool, - raw_bytes: Vec, -} - -impl RawBytesSpec { - /// Creates an instance of the appropriate variant. - pub fn new(raw_bytes: &[u8], is_legacy: bool) -> Self { - Self { - is_legacy, - raw_bytes: raw_bytes.to_vec(), - } - } - - /// Creates a variant indicating that raw bytes are coming from a legacy source. - pub fn new_legacy(raw_bytes: &[u8]) -> Self { - Self { - is_legacy: true, - raw_bytes: raw_bytes.to_vec(), - } - } - - /// Creates a variant indicating that raw bytes are coming from the current database. - pub fn new_current(raw_bytes: &[u8]) -> Self { - Self { - is_legacy: false, - raw_bytes: raw_bytes.to_vec(), - } - } - - /// Is legacy? - pub fn is_legacy(&self) -> bool { - self.is_legacy - } - - /// Raw bytes. - pub fn raw_bytes(&self) -> Vec { - self.raw_bytes.clone() - } -} diff --git a/node/src/components/binary_port.rs b/node/src/components/binary_port.rs index c409e57f72..e3fbfde631 100644 --- a/node/src/components/binary_port.rs +++ b/node/src/components/binary_port.rs @@ -12,8 +12,8 @@ use bytes::Bytes; use casper_binary_port::{ BinaryRequest, BinaryRequestHeader, BinaryRequestTag, BinaryResponse, BinaryResponseAndRequest, ErrorCode, GetRequest, GetTrieFullResult, GlobalStateQueryResult, GlobalStateRequest, - InformationRequest, InformationRequestTag, NodeStatus, RawBytesSpec, ReactorStateName, - RecordId, TransactionWithExecutionInfo, + InformationRequest, InformationRequestTag, NodeStatus, PayloadType, ReactorStateName, RecordId, + TransactionWithExecutionInfo, }; use casper_storage::{ data_access_layer::{ @@ -187,8 +187,7 @@ where let Ok(serialized) = bincode::serialize(&transfers) else { return BinaryResponse::new_error(ErrorCode::InternalError, protocol_version); }; - let bytes = RawBytesSpec::new_current(&serialized); - BinaryResponse::from_raw_bytes(RecordId::Transfer, Some(bytes), protocol_version) + BinaryResponse::from_raw_bytes(PayloadType::Transfers, serialized, protocol_version) } GetRequest::Record { record_type_tag, @@ -197,8 +196,15 @@ where metrics.binary_port_get_record_count.inc(); match RecordId::try_from(record_type_tag) { Ok(record_id) => { - let maybe_raw_bytes = effect_builder.get_raw_data(record_id, key).await; - BinaryResponse::from_raw_bytes(record_id, maybe_raw_bytes, protocol_version) + let Some(db_bytes) = effect_builder.get_raw_data(record_id, key).await else { + return BinaryResponse::new_empty(protocol_version); + }; + let payload_type = PayloadType::from_record_id(record_id, db_bytes.is_legacy()); + BinaryResponse::from_raw_bytes( + payload_type, + db_bytes.into_raw_bytes(), + protocol_version, + ) } Err(_) => { BinaryResponse::new_error(ErrorCode::UnsupportedRequest, protocol_version) diff --git a/node/src/components/storage.rs b/node/src/components/storage.rs index 10aea2369d..018dd7b211 100644 --- a/node/src/components/storage.rs +++ b/node/src/components/storage.rs @@ -986,10 +986,7 @@ impl Storage { let maybe_data: Option = txn.read((db_table_id, key))?; match maybe_data { None => responder.respond(None).ignore(), - Some(db_raw) => { - let raw_bytes_spec = utils::raw_bytes_from_db_raw_bytes(db_raw); - responder.respond(Some(raw_bytes_spec)).ignore() - } + Some(db_raw) => responder.respond(Some(db_raw)).ignore(), } } }) diff --git a/node/src/components/storage/utils.rs b/node/src/components/storage/utils.rs index d46082ec62..0c16f942b7 100644 --- a/node/src/components/storage/utils.rs +++ b/node/src/components/storage/utils.rs @@ -1,5 +1,5 @@ -use casper_binary_port::{RawBytesSpec, RecordId}; -use casper_storage::{DbRawBytesSpec, DbTableId, UnknownDbTableId}; +use casper_binary_port::RecordId; +use casper_storage::{DbTableId, UnknownDbTableId}; use std::convert::TryFrom; pub(crate) fn db_table_id_from_record_id( @@ -7,10 +7,3 @@ pub(crate) fn db_table_id_from_record_id( ) -> Result { DbTableId::try_from(record_id as u16) } - -pub(crate) fn raw_bytes_from_db_raw_bytes(db_raw_bytes_spec: DbRawBytesSpec) -> RawBytesSpec { - RawBytesSpec::new( - &db_raw_bytes_spec.raw_bytes(), - db_raw_bytes_spec.is_legacy(), - ) -} diff --git a/node/src/effect.rs b/node/src/effect.rs index eeb8474e4f..6b66bf7237 100644 --- a/node/src/effect.rs +++ b/node/src/effect.rs @@ -115,8 +115,7 @@ use tokio::{sync::Semaphore, time}; use tracing::{debug, error, warn}; use casper_binary_port::{ - ConsensusStatus, ConsensusValidatorChanges, LastProgress, NetworkName, RawBytesSpec, RecordId, - Uptime, + ConsensusStatus, ConsensusValidatorChanges, LastProgress, NetworkName, RecordId, Uptime, }; use casper_storage::{ block_store::types::ApprovalsHashes, @@ -127,6 +126,7 @@ use casper_storage::{ QueryRequest, QueryResult, RoundSeigniorageRateRequest, RoundSeigniorageRateResult, TotalSupplyRequest, TotalSupplyResult, TrieRequest, TrieResult, }, + DbRawBytesSpec, }; use casper_types::{ execution::{Effects as ExecutionEffects, ExecutionResult}, @@ -1168,7 +1168,7 @@ impl EffectBuilder { self, record_id: RecordId, key: Vec, - ) -> Option + ) -> Option where REv: From, { diff --git a/node/src/effect/requests.rs b/node/src/effect/requests.rs index 8b170e0334..b1b8c5b967 100644 --- a/node/src/effect/requests.rs +++ b/node/src/effect/requests.rs @@ -16,8 +16,7 @@ use smallvec::SmallVec; use static_assertions::const_assert; use casper_binary_port::{ - ConsensusStatus, ConsensusValidatorChanges, LastProgress, NetworkName, RawBytesSpec, RecordId, - Uptime, + ConsensusStatus, ConsensusValidatorChanges, LastProgress, NetworkName, RecordId, Uptime, }; use casper_storage::{ block_store::types::ApprovalsHashes, @@ -28,6 +27,7 @@ use casper_storage::{ QueryRequest, QueryResult, RoundSeigniorageRateRequest, RoundSeigniorageRateResult, TotalSupplyRequest, TotalSupplyResult, TrieRequest, TrieResult, }, + DbRawBytesSpec, }; use casper_types::{ execution::ExecutionResult, Approval, AvailableBlockRange, Block, BlockHash, BlockHeader, @@ -340,7 +340,7 @@ pub(crate) enum StorageRequest { key: Vec, /// Responder to call with the result. Returns `None` if the data doesn't exist in /// local storage. - responder: Responder>, + responder: Responder>, }, GetBlockHeaderByHeight { /// Height of block to get header of. diff --git a/storage/src/block_store/mod.rs b/storage/src/block_store/mod.rs index 3c22de98a7..657f924aff 100644 --- a/storage/src/block_store/mod.rs +++ b/storage/src/block_store/mod.rs @@ -37,7 +37,7 @@ impl DbRawBytesSpec { } /// Raw bytes. - pub fn raw_bytes(&self) -> Vec { - self.raw_bytes.clone() + pub fn into_raw_bytes(self) -> Vec { + self.raw_bytes } } From e84b3023fff5ce9966b97fe4d45d0ad31c2b85a1 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Mon, 25 Mar 2024 11:46:59 -0700 Subject: [PATCH 37/70] cleanup / sse schema --- .../components/contract_runtime/operations.rs | 2 +- resources/test/sse_data_schema.json | 20 +++++------ storage/src/global_state/state/mod.rs | 6 ---- storage/src/system/transfer.rs | 35 +++++++++---------- 4 files changed, 28 insertions(+), 35 deletions(-) diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 2ca87cc107..14c933d1b6 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -199,7 +199,7 @@ pub fn execute_finalized_block( (DIRECT_CONTRACT, STANDARD_PAYMENT) => { // TODO: get the contract, check the entry point indicated in the transaction // if the contract pays for itself, use its main purse - // <-- contract paying for things wire up goes here --> + // <-- contracts paying for things wire up goes here --> // use scratch_state to read the contract & check it here // if the contract does not exist, the entrypoint does not exist, // the entrypoint does not pay for itself, and every other sad path diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index adf40d8793..42ff5a9a5e 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -1874,10 +1874,10 @@ "description": "Hex-encoded entity address identifying the invocable entity.", "type": "object", "required": [ - "InvocableEntity" + "ByHash" ], "properties": { - "InvocableEntity": { + "ByHash": { "type": "string" } }, @@ -1887,10 +1887,10 @@ "description": "The alias identifying the invocable entity.", "type": "object", "required": [ - "InvocableEntityAlias" + "ByName" ], "properties": { - "InvocableEntityAlias": { + "ByName": { "type": "string" } }, @@ -1900,10 +1900,10 @@ "description": "The address and optional version identifying the package.", "type": "object", "required": [ - "Package" + "ByPackageHash" ], "properties": { - "Package": { + "ByPackageHash": { "type": "object", "required": [ "addr" @@ -1932,16 +1932,16 @@ "description": "The alias and optional version identifying the package.", "type": "object", "required": [ - "PackageAlias" + "ByPackageName" ], "properties": { - "PackageAlias": { + "ByPackageName": { "type": "object", "required": [ - "alias" + "name" ], "properties": { - "alias": { + "name": { "description": "The package alias.", "type": "string" }, diff --git a/storage/src/global_state/state/mod.rs b/storage/src/global_state/state/mod.rs index 40534b8c22..408a026854 100644 --- a/storage/src/global_state/state/mod.rs +++ b/storage/src/global_state/state/mod.rs @@ -1030,12 +1030,6 @@ pub trait StateProvider { handle_payment_mode, }: HandlePaymentRequest, ) -> HandlePaymentResult { - // let mut tc = match self.tracking_copy(state_hash) { - // Ok(Some(tracking_copy)) => tracking_copy, - // Ok(None) => return HandlePaymentResult::RootNotFound, - // Err(err) => return HandlePaymentResult::Failure(TrackingCopyError::Storage(err)), - // }; - let tc = match self.tracking_copy(state_hash) { Ok(Some(tc)) => Rc::new(RefCell::new(tc)), Ok(None) => return HandlePaymentResult::RootNotFound, diff --git a/storage/src/system/transfer.rs b/storage/src/system/transfer.rs index 93b80985f1..a10db35d45 100644 --- a/storage/src/system/transfer.rs +++ b/storage/src/system/transfer.rs @@ -420,24 +420,23 @@ impl TransferRuntimeArgsBuilder { where R: StateReader, { - let (to, target) = match self - .resolve_transfer_target_mode(protocol_version, Rc::clone(&tracking_copy))? - { - NewTransferTargetMode::ExistingAccount { - main_purse: purse_uref, - target_account_hash: target_account, - } => (Some(target_account), purse_uref), - NewTransferTargetMode::PurseExists { - target_account_hash, - purse_uref, - } => (target_account_hash, purse_uref), - NewTransferTargetMode::CreateAccount(_) => { - // Method "build()" is called after `resolve_transfer_target_mode` is first called - // and handled by creating a new account. Calling `resolve_transfer_target_mode` - // for the second time should never return `CreateAccount` variant. - return Err(TransferError::InvalidOperation); - } - }; + let (to, target) = + match self.resolve_transfer_target_mode(protocol_version, Rc::clone(&tracking_copy))? { + NewTransferTargetMode::ExistingAccount { + main_purse: purse_uref, + target_account_hash: target_account, + } => (Some(target_account), purse_uref), + NewTransferTargetMode::PurseExists { + target_account_hash, + purse_uref, + } => (target_account_hash, purse_uref), + NewTransferTargetMode::CreateAccount(_) => { + // Method "build()" is called after `resolve_transfer_target_mode` is first called + // and handled by creating a new account. Calling `resolve_transfer_target_mode` + // for the second time should never return `CreateAccount` variant. + return Err(TransferError::InvalidOperation); + } + }; let source = self.resolve_source_uref(from, entity_named_keys, Rc::clone(&tracking_copy))?; From 4db887a98a84d6c4e42a25e7ddbb29668f6d8d04 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Mon, 25 Mar 2024 16:45:07 -0700 Subject: [PATCH 38/70] merge conflicts --- binary_port/src/dictionary_item_identifier.rs | 10 ++-- binary_port/src/error_code.rs | 2 +- binary_port/src/state_request.rs | 1 - .../src/engine_state/deploy_item.rs | 8 +-- .../src/engine_state/execution_result.rs | 2 +- execution_engine/src/engine_state/mod.rs | 2 +- .../test_support/src/deploy_item_builder.rs | 4 +- .../test_support/src/lib.rs | 2 +- .../tests/src/test/contract_messages.rs | 4 +- node/src/components/binary_port.rs | 59 ++++++++----------- node/src/components/binary_port/tests.rs | 1 + node/src/components/contract_runtime.rs | 4 +- .../components/contract_runtime/operations.rs | 26 ++++---- node/src/components/contract_runtime/utils.rs | 19 +----- node/src/components/transaction_buffer.rs | 2 +- .../reactor/main_reactor/tests/binary_port.rs | 9 ++- .../transaction/transaction_footprint.rs | 10 ++-- resources/test/sse_data_schema.json | 4 +- .../src/data_access_layer/handle_payment.rs | 4 +- storage/src/system/handle_payment.rs | 2 +- storage/src/system/handle_payment/internal.rs | 4 +- storage/src/system/transfer.rs | 35 +++++------ types/src/addressable_entity.rs | 35 +---------- types/src/contract_messages.rs | 4 +- types/src/contract_messages/messages.rs | 2 +- types/src/gas.rs | 2 +- types/src/key.rs | 10 ++-- types/src/lib.rs | 2 +- types/src/motes.rs | 2 +- types/src/transaction.rs | 16 ++++- types/src/transaction/deploy.rs | 12 +++- .../deploy/executable_deploy_item.rs | 2 +- types/src/transaction/pricing_mode.rs | 8 +-- types/src/transaction/transaction_v1.rs | 6 +- .../transaction/transaction_v1/errors_v1.rs | 2 +- .../transaction_v1/transaction_v1_header.rs | 6 +- 36 files changed, 153 insertions(+), 170 deletions(-) diff --git a/binary_port/src/dictionary_item_identifier.rs b/binary_port/src/dictionary_item_identifier.rs index 241c50e40a..44277b8ddb 100644 --- a/binary_port/src/dictionary_item_identifier.rs +++ b/binary_port/src/dictionary_item_identifier.rs @@ -1,11 +1,9 @@ -use alloc::{string::String, vec::Vec}; - +#[cfg(test)] +use casper_types::testing::TestRng; #[cfg(test)] use rand::Rng; -#[cfg(test)] -use crate::testing::TestRng; -use crate::{ +use casper_types::{ account::AccountHash, bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, DictionaryAddr, EntityAddr, HashAddr, URef, @@ -241,7 +239,7 @@ impl FromBytes for DictionaryItemIdentifier { #[cfg(test)] mod tests { use super::*; - use crate::testing::TestRng; + use casper_types::testing::TestRng; #[test] fn bytesrepr_roundtrip() { diff --git a/binary_port/src/error_code.rs b/binary_port/src/error_code.rs index e2f2474350..0460806adb 100644 --- a/binary_port/src/error_code.rs +++ b/binary_port/src/error_code.rs @@ -43,7 +43,7 @@ pub enum ErrorCode { #[error("unsupported request")] UnsupportedRequest = 11, /// Dictionary URef not found. - #[cfg_attr(feature = "std", error("dictionary URef not found"))] + #[error("dictionary URef not found")] DictionaryURefNotFound = 12, /// This node has no complete blocks. #[error("no complete blocks")] diff --git a/binary_port/src/state_request.rs b/binary_port/src/state_request.rs index 4bd0a0c809..b7981c9ada 100644 --- a/binary_port/src/state_request.rs +++ b/binary_port/src/state_request.rs @@ -10,7 +10,6 @@ use casper_types::{ use super::dictionary_item_identifier::DictionaryItemIdentifier; - const ITEM_TAG: u8 = 0; const ALL_ITEMS_TAG: u8 = 1; const TRIE_TAG: u8 = 2; diff --git a/execution_engine/src/engine_state/deploy_item.rs b/execution_engine/src/engine_state/deploy_item.rs index de3b71673e..749771b60a 100644 --- a/execution_engine/src/engine_state/deploy_item.rs +++ b/execution_engine/src/engine_state/deploy_item.rs @@ -4,8 +4,6 @@ use std::collections::BTreeSet; use casper_types::{account::AccountHash, Deploy, DeployHash, ExecutableDeployItem}; -type GasPrice = u64; - /// Definition of a deploy with all the details that make it possible to execute it. /// Corresponds to the similarly-named IPC protobuf message. #[derive(Clone, PartialEq, Eq, Debug)] @@ -18,7 +16,7 @@ pub struct DeployItem { /// Payment code. pub payment: ExecutableDeployItem, /// Gas price specified for this deploy by the user. - pub gas_price: GasPrice, + pub gas_price: u8, /// List of accounts that signed this deploy. pub authorization_keys: BTreeSet, /// A unique identifier of the deploy. @@ -32,7 +30,7 @@ impl DeployItem { address: AccountHash, session: ExecutableDeployItem, payment: ExecutableDeployItem, - gas_price: GasPrice, + gas_price: u8, authorization_keys: BTreeSet, deploy_hash: DeployHash, ) -> Self { @@ -65,7 +63,7 @@ impl From for DeployItem { address, deploy.session().clone(), deploy.payment().clone(), - deploy.header().gas_price(), + deploy.header().gas_price() as u8, authorization_keys, DeployHash::new(*deploy.hash().inner()), ) diff --git a/execution_engine/src/engine_state/execution_result.rs b/execution_engine/src/engine_state/execution_result.rs index cf78c3e2c7..cbc6bd5111 100644 --- a/execution_engine/src/engine_state/execution_result.rs +++ b/execution_engine/src/engine_state/execution_result.rs @@ -240,7 +240,7 @@ impl ExecutionResult { pub fn check_forced_transfer( &self, payment_purse_balance: Motes, - gas_price: u64, + gas_price: u8, ) -> Option { let payment_result_cost = match Motes::from_gas(self.gas(), gas_price) { Some(cost) => cost, diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index 494dff622d..b09938807c 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -38,7 +38,7 @@ pub static MAX_PAYMENT: Lazy = Lazy::new(|| U512::from(MAX_PAYMENT_AMOUNT) /// Gas/motes conversion rate of wasmless transfer cost is always 1 regardless of what user wants to /// pay. -pub const WASMLESS_TRANSFER_FIXED_GAS_PRICE: u64 = 1; +pub const WASMLESS_TRANSFER_FIXED_GAS_PRICE: u8 = 1; /// The public api of the v1 execution engine, as of protocol version 2.0.0 #[derive(Debug, Clone, Default)] diff --git a/execution_engine_testing/test_support/src/deploy_item_builder.rs b/execution_engine_testing/test_support/src/deploy_item_builder.rs index 48b6fba79e..05c4303ea7 100644 --- a/execution_engine_testing/test_support/src/deploy_item_builder.rs +++ b/execution_engine_testing/test_support/src/deploy_item_builder.rs @@ -15,7 +15,7 @@ struct DeployItemData { pub address: Option, pub payment_code: Option, pub session_code: Option, - pub gas_price: u64, + pub gas_price: u8, pub authorization_keys: BTreeSet, pub deploy_hash: Option, } @@ -255,7 +255,7 @@ impl DeployItemBuilder { } /// Sets the gas price for the deploy. - pub fn with_gas_price(mut self, gas_price: u64) -> Self { + pub fn with_gas_price(mut self, gas_price: u8) -> Self { self.deploy_item.gas_price = gas_price; self } diff --git a/execution_engine_testing/test_support/src/lib.rs b/execution_engine_testing/test_support/src/lib.rs index b3e7707ad0..dd2e443fd4 100644 --- a/execution_engine_testing/test_support/src/lib.rs +++ b/execution_engine_testing/test_support/src/lib.rs @@ -65,7 +65,7 @@ pub const DEFAULT_GENESIS_TIMESTAMP_MILLIS: u64 = 0; /// Default block time. pub const DEFAULT_BLOCK_TIME: u64 = 0; /// Default gas price. -pub const DEFAULT_GAS_PRICE: u64 = 1; +pub const DEFAULT_GAS_PRICE: u8 = 1; /// Amount named argument. pub const ARG_AMOUNT: &str = "amount"; /// Timestamp increment in milliseconds. diff --git a/execution_engine_testing/tests/src/test/contract_messages.rs b/execution_engine_testing/tests/src/test/contract_messages.rs index dc0974805c..36d99c017e 100644 --- a/execution_engine_testing/tests/src/test/contract_messages.rs +++ b/execution_engine_testing/tests/src/test/contract_messages.rs @@ -200,7 +200,7 @@ impl<'a> ContractQueryView<'a> { .query( None, Key::message_topic( - EntityAddr::new_contract_entity_addr(self.contract_hash.value()), + EntityAddr::new_smart_contract(self.contract_hash.value()), topic_name_hash, ), &[], @@ -227,7 +227,7 @@ impl<'a> ContractQueryView<'a> { let query_result = self.builder.borrow_mut().query( state_hash, Key::message( - EntityAddr::new_contract_entity_addr(self.contract_hash.value()), + EntityAddr::new_smart_contract(self.contract_hash.value()), topic_name_hash, message_index, ), diff --git a/node/src/components/binary_port.rs b/node/src/components/binary_port.rs index 1a5ef13bf4..7f085e5642 100644 --- a/node/src/components/binary_port.rs +++ b/node/src/components/binary_port.rs @@ -11,9 +11,9 @@ use std::{convert::TryFrom, net::SocketAddr, sync::Arc}; use bytes::Bytes; use casper_binary_port::{ BinaryRequest, BinaryRequestHeader, BinaryRequestTag, BinaryResponse, BinaryResponseAndRequest, - ErrorCode, GetRequest, GetTrieFullResult, GlobalStateQueryResult, GlobalStateRequest, - InformationRequest, InformationRequestTag, NodeStatus, PayloadType, ReactorStateName, RecordId, - TransactionWithExecutionInfo, + DictionaryItemIdentifier, ErrorCode, GetRequest, GetTrieFullResult, GlobalStateQueryResult, + GlobalStateRequest, InformationRequest, InformationRequestTag, NodeStatus, PayloadType, + ReactorStateName, RecordId, TransactionWithExecutionInfo, }; use casper_storage::{ data_access_layer::{ @@ -23,10 +23,12 @@ use casper_storage::{ global_state::trie::TrieRaw, }; use casper_types::{ + addressable_entity::NamedKeyAddr, bytesrepr::{self, FromBytes, ToBytes}, - BlockIdentifier, Digest, EntityAddr, GlobalStateIdentifier, Key,Peers, ProtocolVersion, SignedBlock, StoredValue,TimeDiff, - Transaction, + BlockIdentifier, Digest, EntityAddr, GlobalStateIdentifier, Key, Peers, ProtocolVersion, + SignedBlock, StoredValue, TimeDiff, Transaction, }; + use datasize::DataSize; use futures::{future::BoxFuture, FutureExt}; use juliet::{ @@ -46,6 +48,7 @@ use tokio::{ use tracing::{debug, error, info, warn}; use crate::{ + contract_runtime::SpeculativeExecutionResult, effect::{ requests::{ AcceptTransactionRequest, BlockSynchronizerRequest, ChainspecRawBytesRequest, @@ -62,7 +65,7 @@ use crate::{ use self::{error::Error, metrics::Metrics}; use super::{Component, ComponentState, InitializedComponent, PortBoundComponent}; -use crate::contract_runtime::SpeculativeExecutionResult; + pub(crate) use config::Config; pub(crate) use event::Event; @@ -393,7 +396,7 @@ async fn get_dictionary_item_by_legacy_named_key( entity_key: Key, dictionary_name: String, dictionary_item_key: String, -) -> Result, binary_port::ErrorCode> +) -> Result, ErrorCode> where REv: From + From + From, { @@ -405,18 +408,18 @@ where let named_keys = match &*value { StoredValue::Account(account) => account.named_keys(), StoredValue::Contract(contract) => contract.named_keys(), - _ => return Err(binary_port::ErrorCode::DictionaryURefNotFound), + _ => return Err(ErrorCode::DictionaryURefNotFound), }; let Some(uref) = named_keys.get(&dictionary_name).and_then(Key::as_uref) else { - return Err(binary_port::ErrorCode::DictionaryURefNotFound); + return Err(ErrorCode::DictionaryURefNotFound); }; let dictionary_key = Key::dictionary(*uref, dictionary_item_key.as_bytes()); get_global_state_item(effect_builder, state_root_hash, dictionary_key, vec![]).await } QueryResult::RootNotFound | QueryResult::ValueNotFound(_) => { - Err(binary_port::ErrorCode::DictionaryURefNotFound) + Err(ErrorCode::DictionaryURefNotFound) } - QueryResult::Failure(_) => Err(binary_port::ErrorCode::QueryFailedToExecute), + QueryResult::Failure(_) => Err(ErrorCode::FailedQuery), } } @@ -426,29 +429,29 @@ async fn get_dictionary_item_by_named_key( entity_addr: EntityAddr, dictionary_name: String, dictionary_item_key: String, -) -> Result, binary_port::ErrorCode> +) -> Result, ErrorCode> where REv: From + From + From, { let Ok(key_addr) = NamedKeyAddr::new_from_string(entity_addr, dictionary_name) else { - return Err(binary_port::ErrorCode::InternalError); + return Err(ErrorCode::InternalError); }; let req = QueryRequest::new(state_root_hash, Key::NamedKey(key_addr), vec![]); match effect_builder.query_global_state(req).await { QueryResult::Success { value, .. } => { let StoredValue::NamedKey(key_val) = &*value else { - return Err(binary_port::ErrorCode::DictionaryURefNotFound); + return Err(ErrorCode::DictionaryURefNotFound); }; let Ok(Key::URef(uref)) = key_val.get_key() else { - return Err(binary_port::ErrorCode::DictionaryURefNotFound); + return Err(ErrorCode::DictionaryURefNotFound); }; let dictionary_key = Key::dictionary(uref, dictionary_item_key.as_bytes()); get_global_state_item(effect_builder, state_root_hash, dictionary_key, vec![]).await } QueryResult::RootNotFound | QueryResult::ValueNotFound(_) => { - Err(binary_port::ErrorCode::DictionaryURefNotFound) + Err(ErrorCode::DictionaryURefNotFound) } - QueryResult::Failure(_) => Err(binary_port::ErrorCode::QueryFailedToExecute), + QueryResult::Failure(_) => Err(ErrorCode::FailedQuery), } } @@ -457,7 +460,7 @@ async fn get_global_state_item( state_root_hash: Digest, base_key: Key, path: Vec, -) -> Result, binary_port::ErrorCode> +) -> Result, ErrorCode> where REv: From + From + From, { @@ -465,22 +468,12 @@ where .query_global_state(QueryRequest::new(state_root_hash, base_key, path)) .await { - QueryResult::Success { value, proofs } => BinaryResponse::from_value( - GlobalStateQueryResult::new(*value, proofs), - protocol_version, - ), - QueryResult::RootNotFound => { - let error_code = ErrorCode::RootNotFound; - BinaryResponse::new_error(error_code, protocol_version) - } - QueryResult::ValueNotFound(_) => { - let error_code = ErrorCode::NotFound; - BinaryResponse::new_error(error_code, protocol_version) - } - QueryResult::Failure(_) => { - let error_code = ErrorCode::FailedQuery; - BinaryResponse::new_error(error_code, protocol_version) + QueryResult::Success { value, proofs } => { + Ok(Some(GlobalStateQueryResult::new(*value, proofs))) } + QueryResult::RootNotFound => Err(ErrorCode::RootNotFound), + QueryResult::ValueNotFound(_) => Err(ErrorCode::NotFound), + QueryResult::Failure(_) => Err(ErrorCode::FailedQuery), } } diff --git a/node/src/components/binary_port/tests.rs b/node/src/components/binary_port/tests.rs index de46072c9d..3c82cf34a7 100644 --- a/node/src/components/binary_port/tests.rs +++ b/node/src/components/binary_port/tests.rs @@ -274,6 +274,7 @@ impl Reactor for MockReactor { Default::default(), Default::default(), Default::default(), + Default::default(), ); responder .respond(Some(BlockHeader::V2(block_header_v2))) diff --git a/node/src/components/contract_runtime.rs b/node/src/components/contract_runtime.rs index 17a55cee2f..3e42e71215 100644 --- a/node/src/components/contract_runtime.rs +++ b/node/src/components/contract_runtime.rs @@ -41,7 +41,9 @@ use casper_storage::{ system::{genesis::GenesisError, protocol_upgrade::ProtocolUpgradeError}, tracking_copy::TrackingCopyError, }; -use casper_types::{ActivationPoint, Chainspec, ChainspecRawBytes, ChainspecRegistry, EraId, ProtocolUpgradeConfig}; +use casper_types::{ + ActivationPoint, Chainspec, ChainspecRawBytes, ChainspecRegistry, EraId, ProtocolUpgradeConfig, +}; use crate::{ components::{fetcher::FetchResponse, Component, ComponentState}, diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 974bbc216e..8c84cdf5a5 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -102,7 +102,7 @@ pub fn execute_finalized_block( .collect_vec(); let system_costs = chainspec.system_costs_config; let insufficient_balance_handling = InsufficientBalanceHandling::HoldRemaining; - let gas_price = Some(1); // < --TODO: this is where Karan's calculated gas price needs to be used + let gas_price = Some(current_gas_price); for transaction in executable_block.transactions { let mut artifact_builder = ExecutionArtifactBuilder::new(&transaction); @@ -621,15 +621,21 @@ pub fn execute_finalized_block( } // the rest of this is post process, picking out data bits to return to caller - let maybe_next_era_validator_weights: Option> = { - let next_era_id = executable_block.era_id.successor(); - step_outcome.as_ref().and_then( - |StepOutcome { - upcoming_era_validators, - .. - }| upcoming_era_validators.get(&next_era_id).cloned(), - ) - }; + let next_era_id = executable_block.era_id.successor(); + let maybe_next_era_validator_weights: Option<(BTreeMap, u8)> = + match step_outcome.as_ref() { + None => None, + Some(effects_and_validators) => { + match effects_and_validators + .upcoming_era_validators + .get(&next_era_id) + .cloned() + { + Some(validators) => next_era_gas_price.map(|gas_price| (validators, gas_price)), + None => None, + } + } + }; let era_end = match ( executable_block.era_report, diff --git a/node/src/components/contract_runtime/utils.rs b/node/src/components/contract_runtime/utils.rs index 724a7c233d..9d7c038c5e 100644 --- a/node/src/components/contract_runtime/utils.rs +++ b/node/src/components/contract_runtime/utils.rs @@ -1,26 +1,11 @@ use num_rational::Ratio; -use once_cell::sync::Lazy; -use std::{ - cmp, - collections::{BTreeMap, HashMap}, - ops::Range, - sync::{Arc, Mutex}, -}; -use tracing::{debug, error, info}; - -use casper_execution_engine::engine_state::ExecutionEngineV1; -use casper_storage::{ - data_access_layer::DataAccessLayer, global_state::state::lmdb::LmdbGlobalState, -}; -use casper_types::{Chainspec, EraId, Key}; use crate::{ contract_runtime::{ exec_queue::{ExecQueue, QueueItem}, execute_finalized_block, metrics::Metrics, - rewards, BlockAndExecutionArtifacts, BlockExecutionError, ExecutionPreState, - StepOutcome, + rewards, BlockAndExecutionArtifacts, BlockExecutionError, ExecutionPreState, StepOutcome, }, effect::{ announcements::{ContractRuntimeAnnouncement, FatalAnnouncement, MetaBlockAnnouncement}, @@ -45,7 +30,7 @@ use std::{ ops::Range, sync::{Arc, Mutex}, }; -use tracing::{debug, error}; +use tracing::{debug, error, info}; /// Maximum number of resource intensive tasks that can be run in parallel. /// diff --git a/node/src/components/transaction_buffer.rs b/node/src/components/transaction_buffer.rs index 72df6250d8..b4e0b48d3e 100644 --- a/node/src/components/transaction_buffer.rs +++ b/node/src/components/transaction_buffer.rs @@ -391,7 +391,7 @@ impl TransactionBuffer { .filter(|(th, _)| !self.dead.contains(th)) .filter(|(_, (_, maybe_data))| match maybe_data { None => false, - Some(footprint) => footprint.gas_tolerance() >= (current_era_gas_price as u64), + Some(footprint) => footprint.gas_price_tolerance() >= (current_era_gas_price), }) .filter_map(|(th, (_, maybe_data))| { maybe_data diff --git a/node/src/reactor/main_reactor/tests/binary_port.rs b/node/src/reactor/main_reactor/tests/binary_port.rs index c2968c5a8d..54335a9c24 100644 --- a/node/src/reactor/main_reactor/tests/binary_port.rs +++ b/node/src/reactor/main_reactor/tests/binary_port.rs @@ -8,11 +8,14 @@ use std::{ use casper_binary_port::{ BinaryRequest, BinaryRequestHeader, BinaryResponse, BinaryResponseAndRequest, ConsensusStatus, - ConsensusValidatorChanges, ErrorCode, GetRequest, GetTrieFullResult, GlobalStateQueryResult, - GlobalStateRequest, InformationRequest, InformationRequestTag, LastProgress, NetworkName, - NodeStatus, PayloadType, ReactorStateName, RecordId, Uptime, + ConsensusValidatorChanges, DictionaryItemIdentifier, ErrorCode, GetRequest, GetTrieFullResult, + GlobalStateQueryResult, GlobalStateRequest, InformationRequest, InformationRequestTag, + LastProgress, NetworkName, NodeStatus, PayloadType, ReactorStateName, RecordId, Uptime, }; +use casper_storage::global_state::state::CommitProvider; use casper_types::{ + account::{AccountHash, ActionThresholds, AssociatedKeys}, + addressable_entity::{NamedKeyAddr, NamedKeyValue}, bytesrepr::{FromBytes, ToBytes}, execution::{Effects, TransformKindV2, TransformV2}, testing::TestRng, diff --git a/node/src/types/transaction/transaction_footprint.rs b/node/src/types/transaction/transaction_footprint.rs index 49e70ba9ae..5c0b4b5765 100644 --- a/node/src/types/transaction/transaction_footprint.rs +++ b/node/src/types/transaction/transaction_footprint.rs @@ -17,7 +17,7 @@ pub(crate) struct TransactionFootprint { /// The estimated gas consumption. pub(crate) gas_limit: Gas, /// The gas tolerance. - pub(crate) gas_tolerance: u64, + pub(crate) gas_price_tolerance: u8, /// The bytesrepr serialized length. pub(crate) size_estimate: usize, /// The transaction category. @@ -38,7 +38,8 @@ impl TransactionFootprint { let cost_table = &chainspec.system_costs_config; // IMPORTANT: block inclusion is always calculated based upon gas price multiple = 1 // Do not confuse actual cost with retail cost. - let gas_price: Option = None; + let gas_price: Option = None; + let gas_price_tolerance = transaction.gas_price_tolerance()?; let gas_limit = transaction.gas_limit(cost_table, gas_price)?; let category = transaction.category(); let transaction_hash = transaction.hash(); @@ -51,6 +52,7 @@ impl TransactionFootprint { transaction_hash, body_hash, gas_limit, + gas_price_tolerance, size_estimate, category, timestamp, @@ -90,7 +92,7 @@ impl TransactionFootprint { matches!(self.category, TransactionCategory::InstallUpgrade) } - pub(crate) fn gas_tolerance(&self) -> u64 { - self.gas_tolerance + pub(crate) fn gas_price_tolerance(&self) -> u8 { + self.gas_price_tolerance } } diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index 53275b43b5..64a6af4ccb 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -1651,7 +1651,7 @@ "gas_price": { "description": "User-specified gas_price (minimum 1).", "type": "integer", - "format": "uint64", + "format": "uint8", "minimum": 0.0 }, "standard_payment": { @@ -1680,7 +1680,7 @@ "gas_price_tolerance": { "description": "User-specified gas_price tolerance (minimum 1). This is interpreted to mean \"do not include this transaction in a block if the current gas price is greater than this number\"", "type": "integer", - "format": "uint64", + "format": "uint8", "minimum": 0.0 } }, diff --git a/storage/src/data_access_layer/handle_payment.rs b/storage/src/data_access_layer/handle_payment.rs index fedaf2580a..ca42c2cb58 100644 --- a/storage/src/data_access_layer/handle_payment.rs +++ b/storage/src/data_access_layer/handle_payment.rs @@ -8,7 +8,7 @@ use casper_types::{execution::Effects, Digest, Gas, ProtocolVersion, Transaction pub enum HandlePaymentMode { Finalize { limit: Gas, - gas_price: Option, + gas_price: Option, cost: U512, consumed: Gas, source: Box, @@ -28,7 +28,7 @@ pub enum HandlePaymentMode { impl HandlePaymentMode { pub fn finalize( limit: Gas, - gas_price: Option, + gas_price: Option, cost: U512, consumed: Gas, source: BalanceIdentifier, diff --git a/storage/src/system/handle_payment.rs b/storage/src/system/handle_payment.rs index 97e1600562..0d672f4551 100644 --- a/storage/src/system/handle_payment.rs +++ b/storage/src/system/handle_payment.rs @@ -39,7 +39,7 @@ pub trait HandlePayment: MintProvider + RuntimeProvider + StorageProvider + Size fn finalize_payment( &mut self, limit: Gas, - gas_price: Option, + gas_price: Option, cost: U512, consumed: Gas, source_purse: URef, diff --git a/storage/src/system/handle_payment/internal.rs b/storage/src/system/handle_payment/internal.rs index ce02fe4112..5f98460a1a 100644 --- a/storage/src/system/handle_payment/internal.rs +++ b/storage/src/system/handle_payment/internal.rs @@ -51,7 +51,7 @@ pub fn get_refund_purse( /// Any dust amounts are added to the fee. fn calculate_overpayment_and_fee( limit: Gas, - gas_price: Option, + gas_price: Option, cost: U512, consumed: Gas, available_balance: U512, @@ -136,7 +136,7 @@ fn calculate_overpayment_and_fee( pub fn finalize_payment( provider: &mut P, limit: Gas, - gas_price: Option, + gas_price: Option, cost: U512, consumed: Gas, source_purse: URef, diff --git a/storage/src/system/transfer.rs b/storage/src/system/transfer.rs index a10db35d45..93b80985f1 100644 --- a/storage/src/system/transfer.rs +++ b/storage/src/system/transfer.rs @@ -420,23 +420,24 @@ impl TransferRuntimeArgsBuilder { where R: StateReader, { - let (to, target) = - match self.resolve_transfer_target_mode(protocol_version, Rc::clone(&tracking_copy))? { - NewTransferTargetMode::ExistingAccount { - main_purse: purse_uref, - target_account_hash: target_account, - } => (Some(target_account), purse_uref), - NewTransferTargetMode::PurseExists { - target_account_hash, - purse_uref, - } => (target_account_hash, purse_uref), - NewTransferTargetMode::CreateAccount(_) => { - // Method "build()" is called after `resolve_transfer_target_mode` is first called - // and handled by creating a new account. Calling `resolve_transfer_target_mode` - // for the second time should never return `CreateAccount` variant. - return Err(TransferError::InvalidOperation); - } - }; + let (to, target) = match self + .resolve_transfer_target_mode(protocol_version, Rc::clone(&tracking_copy))? + { + NewTransferTargetMode::ExistingAccount { + main_purse: purse_uref, + target_account_hash: target_account, + } => (Some(target_account), purse_uref), + NewTransferTargetMode::PurseExists { + target_account_hash, + purse_uref, + } => (target_account_hash, purse_uref), + NewTransferTargetMode::CreateAccount(_) => { + // Method "build()" is called after `resolve_transfer_target_mode` is first called + // and handled by creating a new account. Calling `resolve_transfer_target_mode` + // for the second time should never return `CreateAccount` variant. + return Err(TransferError::InvalidOperation); + } + }; let source = self.resolve_source_uref(from, entity_named_keys, Rc::clone(&tracking_copy))?; diff --git a/types/src/addressable_entity.rs b/types/src/addressable_entity.rs index 3d9f4a0a8e..c3879a96b5 100644 --- a/types/src/addressable_entity.rs +++ b/types/src/addressable_entity.rs @@ -64,7 +64,6 @@ use crate::{ checksummed_hex, contract_messages::TopicNameHash, contracts::{Contract, ContractHash}, - serde_helpers, system::SystemEntityType, uref::{self, URef}, AccessRights, ApiError, CLType, CLTyped, CLValue, CLValueError, ContextAccessRights, Group, @@ -909,44 +908,16 @@ impl Distribution for Standard { } } -/// The address of an [`AddressableEntity`] which contains the 32 bytes and tagging information. +/// The address for an AddressableEntity which contains the 32 bytes and tagging information. #[derive(PartialOrd, Ord, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize)] #[cfg_attr(feature = "datasize", derive(DataSize))] -#[cfg_attr( - feature = "json-schema", - derive(JsonSchema), - schemars(description = "The hex-encoded address and kind of the addressable entity.") -)] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] pub enum EntityAddr { /// The address for a system entity account or contract. - #[serde(with = "serde_helpers::raw_32_byte_array")] - #[cfg_attr( - feature = "json-schema", - schemars( - with = "String", - description = "Hex-encoded entity address identifying a system contract." - ) - )] System(#[cfg_attr(feature = "json-schema", schemars(skip, with = "String"))] HashAddr), /// The address of an entity that corresponds to an Account. - #[serde(with = "serde_helpers::raw_32_byte_array")] - #[cfg_attr( - feature = "json-schema", - schemars( - with = "String", - description = "Hex-encoded entity address identifying an account." - ) - )] Account(#[cfg_attr(feature = "json-schema", schemars(skip, with = "String"))] HashAddr), - /// The address of an entity that corresponds to a smart contract. - #[serde(with = "serde_helpers::raw_32_byte_array")] - #[cfg_attr( - feature = "json-schema", - schemars( - with = "String", - description = "Hex-encoded entity address identifying a smart contract." - ) - )] + /// The address of an entity that corresponds to a Userland smart contract. SmartContract(#[cfg_attr(feature = "json-schema", schemars(skip, with = "String"))] HashAddr), } diff --git a/types/src/contract_messages.rs b/types/src/contract_messages.rs index a999bd9013..f6822ca09b 100644 --- a/types/src/contract_messages.rs +++ b/types/src/contract_messages.rs @@ -202,13 +202,13 @@ mod tests { #[test] fn serialization_roundtrip() { let topic_addr = MessageAddr::new_topic_addr( - EntityAddr::new_contract_entity_addr([1; KEY_HASH_LENGTH]), + EntityAddr::new_smart_contract([1; KEY_HASH_LENGTH]), [2; TOPIC_NAME_HASH_LENGTH].into(), ); bytesrepr::test_serialization_roundtrip(&topic_addr); let message_addr = MessageAddr::new_message_addr( - EntityAddr::new_contract_entity_addr([1; KEY_HASH_LENGTH]), + EntityAddr::new_smart_contract([1; KEY_HASH_LENGTH]), [2; TOPIC_NAME_HASH_LENGTH].into(), 3, ); diff --git a/types/src/contract_messages/messages.rs b/types/src/contract_messages/messages.rs index 42b8303988..7bbd4f86a9 100644 --- a/types/src/contract_messages/messages.rs +++ b/types/src/contract_messages/messages.rs @@ -356,7 +356,7 @@ mod tests { bytesrepr::test_serialization_roundtrip(&message_payload); let message = Message::new( - EntityAddr::new_contract_entity_addr([1; KEY_HASH_LENGTH]), + EntityAddr::new_smart_contract([1; KEY_HASH_LENGTH]), message_payload, "test_topic".to_string(), TopicNameHash::new([0x4du8; TOPIC_NAME_HASH_LENGTH]), diff --git a/types/src/gas.rs b/types/src/gas.rs index f42b3ea9d7..7224addd3e 100644 --- a/types/src/gas.rs +++ b/types/src/gas.rs @@ -46,7 +46,7 @@ impl Gas { /// Converts the given `motes` to `Gas` by dividing them by `conv_rate`. /// /// Returns `None` if `motes_per_unit_of_gas == 0`. - pub fn from_motes(motes: Motes, motes_per_unit_of_gas: u64) -> Option { + pub fn from_motes(motes: Motes, motes_per_unit_of_gas: u8) -> Option { motes .value() .checked_div(U512::from(motes_per_unit_of_gas)) diff --git a/types/src/key.rs b/types/src/key.rs index 5c9fecd6a5..b22bf623f4 100644 --- a/types/src/key.rs +++ b/types/src/key.rs @@ -113,7 +113,7 @@ const KEY_CHECKSUM_REGISTRY_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + PADDING_BYTES.len(); const KEY_PACKAGE_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + 32; const KEY_MESSAGE_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH - + EntityAddr::ENTITY_ADDR_LENGTH + + EntityAddr::LENGTH + TOPIC_NAME_HASH_LENGTH + U8_SERIALIZED_LENGTH + U32_SERIALIZED_LENGTH; @@ -1827,11 +1827,11 @@ mod tests { const BYTE_CODE_EMPTY_KEY: Key = Key::ByteCode(ByteCodeAddr::Empty); const BYTE_CODE_V1_WASM_KEY: Key = Key::ByteCode(ByteCodeAddr::V1CasperWasm([42; 32])); const MESSAGE_TOPIC_KEY: Key = Key::Message(MessageAddr::new_topic_addr( - EntityAddr::new_contract_entity_addr([42; 32]), + EntityAddr::new_smart_contract([42; 32]), TopicNameHash::new([42; 32]), )); const MESSAGE_KEY: Key = Key::Message(MessageAddr::new_message_addr( - EntityAddr::new_contract_entity_addr([42u8; 32]), + EntityAddr::new_smart_contract([42u8; 32]), TopicNameHash::new([2; 32]), 15, )); @@ -2415,11 +2415,11 @@ mod tests { round_trip(&Key::ByteCode(ByteCodeAddr::Empty)); round_trip(&Key::ByteCode(ByteCodeAddr::V1CasperWasm(zeros))); round_trip(&Key::Message(MessageAddr::new_topic_addr( - EntityAddr::new_contract_entity_addr(zeros), + EntityAddr::new_smart_contract(zeros), nines.into(), ))); round_trip(&Key::Message(MessageAddr::new_message_addr( - EntityAddr::new_contract_entity_addr(zeros), + EntityAddr::new_smart_contract(zeros), nines.into(), 1, ))); diff --git a/types/src/lib.rs b/types/src/lib.rs index 4b6f646b97..28a74b03a9 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -119,7 +119,7 @@ pub use chainspec::{ HostFunction, HostFunctionCost, HostFunctionCosts, LegacyRequiredFinality, MessageLimits, MintCosts, NetworkConfig, NextUpgrade, OpcodeCosts, ProtocolConfig, ProtocolUpgradeConfig, RefundHandling, StandardPaymentCosts, StorageCosts, SystemConfig, TransactionConfig, - TransactionV1Config, VacancyConfig,ValidatorConfig, WasmConfig, DEFAULT_BALANCE_HOLD_INTERVAL, + TransactionV1Config, VacancyConfig, ValidatorConfig, WasmConfig, DEFAULT_BALANCE_HOLD_INTERVAL, DEFAULT_HOST_FUNCTION_NEW_DICTIONARY, DEFAULT_REFUND_HANDLING, }; #[cfg(any(all(feature = "std", feature = "testing"), test))] diff --git a/types/src/motes.rs b/types/src/motes.rs index 0a70d10668..2361f9b867 100644 --- a/types/src/motes.rs +++ b/types/src/motes.rs @@ -51,7 +51,7 @@ impl Motes { /// Converts the given `gas` to `Motes` by multiplying them by `conv_rate`. /// /// Returns `None` if an arithmetic overflow occurred. - pub fn from_gas(gas: Gas, conv_rate: u64) -> Option { + pub fn from_gas(gas: Gas, conv_rate: u8) -> Option { gas.value() .checked_mul(U512::from(conv_rate)) .map(Self::new) diff --git a/types/src/transaction.rs b/types/src/transaction.rs index c509f0baa0..fa54cc66c9 100644 --- a/types/src/transaction.rs +++ b/types/src/transaction.rs @@ -419,8 +419,11 @@ pub trait GasLimited { fn gas_limit( &self, system_costs: &SystemConfig, - gas_price: Option, + gas_price: Option, ) -> Result; + + /// Returns the gas tolerance of transaction sender. + fn gas_price_tolerance(&self) -> Result; } #[cfg(any(feature = "std", test))] @@ -430,7 +433,7 @@ impl GasLimited for Transaction { fn gas_limit( &self, system_costs: &SystemConfig, - gas_price: Option, + gas_price: Option, ) -> Result { match self { Transaction::Deploy(deploy) => deploy @@ -441,6 +444,15 @@ impl GasLimited for Transaction { .map_err(InvalidTransaction::from), } } + + fn gas_price_tolerance(&self) -> Result { + match self { + Transaction::Deploy(deploy) => deploy + .gas_price_tolerance() + .map_err(InvalidTransaction::from), + Transaction::V1(v1) => v1.gas_price_tolerance().map_err(InvalidTransaction::from), + } + } } impl From for Transaction { diff --git a/types/src/transaction/deploy.rs b/types/src/transaction/deploy.rs index 9ec9d69fd6..147258d1b4 100644 --- a/types/src/transaction/deploy.rs +++ b/types/src/transaction/deploy.rs @@ -14,6 +14,9 @@ use core::{ hash, }; +#[cfg(any(feature = "std", test))] +use std::convert::TryFrom; + #[cfg(feature = "datasize")] use datasize::DataSize; #[cfg(any(feature = "std", test))] @@ -1159,9 +1162,10 @@ impl GasLimited for Deploy { fn gas_limit( &self, system_costs: &SystemConfig, - gas_price: Option, + gas_price: Option, ) -> Result { - let user_specified_price = self.gas_price(); + let user_specified_price = + u8::try_from(self.gas_price()).map_err(|_| Self::Error::UnableToCalculateGasLimit)?; let actual_price = match gas_price { Some(price) => price.max(user_specified_price), None => user_specified_price, @@ -1187,6 +1191,10 @@ impl GasLimited for Deploy { None => Err(InvalidDeploy::MissingPaymentAmount), } } + + fn gas_price_tolerance(&self) -> Result { + u8::try_from(self.gas_price()).map_err(|_| Self::Error::UnableToCalculateGasLimit) + } } impl hash::Hash for Deploy { diff --git a/types/src/transaction/deploy/executable_deploy_item.rs b/types/src/transaction/deploy/executable_deploy_item.rs index 283c2ad45e..42417734b8 100644 --- a/types/src/transaction/deploy/executable_deploy_item.rs +++ b/types/src/transaction/deploy/executable_deploy_item.rs @@ -345,7 +345,7 @@ impl ExecutableDeployItem { } /// Returns the payment amount from args (if any) as Gas. - pub fn payment_amount(&self, conv_rate: u64) -> Option { + pub fn payment_amount(&self, conv_rate: u8) -> Option { let cl_value = self.args().get(ARG_AMOUNT)?; let motes = cl_value.clone().into_t::().ok()?; Gas::from_motes(Motes::new(motes), conv_rate) diff --git a/types/src/transaction/pricing_mode.rs b/types/src/transaction/pricing_mode.rs index eb82d9ec0c..9e8ce03523 100644 --- a/types/src/transaction/pricing_mode.rs +++ b/types/src/transaction/pricing_mode.rs @@ -38,7 +38,7 @@ pub enum PricingMode { /// User-specified payment amount. payment_amount: u64, /// User-specified gas_price (minimum 1). - gas_price: u64, + gas_price: u8, /// Standard payment. standard_payment: bool, }, @@ -48,7 +48,7 @@ pub enum PricingMode { /// User-specified gas_price tolerance (minimum 1). /// This is interpreted to mean "do not include this transaction in a block /// if the current gas price is greater than this number" - gas_price_tolerance: u64, + gas_price_tolerance: u8, }, /// The payment for this transaction was previously reserved, as proven by /// the receipt hash (this is for future use, not currently implemented). @@ -177,7 +177,7 @@ impl FromBytes for PricingMode { match tag { CLASSIC_TAG => { let (payment_amount, remainder) = u64::from_bytes(remainder)?; - let (gas_price, remainder) = u64::from_bytes(remainder)?; + let (gas_price, remainder) = u8::from_bytes(remainder)?; let (standard_payment, remainder) = bool::from_bytes(remainder)?; Ok(( PricingMode::Classic { @@ -189,7 +189,7 @@ impl FromBytes for PricingMode { )) } FIXED_TAG => { - let (gas_price_tolerance, remainder) = u64::from_bytes(remainder)?; + let (gas_price_tolerance, remainder) = u8::from_bytes(remainder)?; Ok(( PricingMode::Fixed { gas_price_tolerance, diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index 31e4dedc0d..56330508d4 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -581,7 +581,7 @@ impl Categorized for TransactionV1 { impl GasLimited for TransactionV1 { type Error = InvalidTransactionV1; - fn gas_limit(&self, costs: &SystemConfig, gas_price: Option) -> Result { + fn gas_limit(&self, costs: &SystemConfig, gas_price: Option) -> Result { let gas = match self.header().pricing_mode() { PricingMode::Classic { payment_amount, @@ -660,6 +660,10 @@ impl GasLimited for TransactionV1 { }; Ok(gas) } + + fn gas_price_tolerance(&self) -> Result { + Ok(self.header.gas_price_tolerance()) + } } impl hash::Hash for TransactionV1 { diff --git a/types/src/transaction/transaction_v1/errors_v1.rs b/types/src/transaction/transaction_v1/errors_v1.rs index e9df2c0065..5d5124964b 100644 --- a/types/src/transaction/transaction_v1/errors_v1.rs +++ b/types/src/transaction/transaction_v1/errors_v1.rs @@ -141,7 +141,7 @@ pub enum InvalidTransaction { /// The base amount. amount: u64, /// The attempted gas price. - gas_price: u64, + gas_price: u8, }, /// Unable to calculate gas limit. UnableToCalculateGasLimit, diff --git a/types/src/transaction/transaction_v1/transaction_v1_header.rs b/types/src/transaction/transaction_v1/transaction_v1_header.rs index 09750c4924..8b1e4ecd01 100644 --- a/types/src/transaction/transaction_v1/transaction_v1_header.rs +++ b/types/src/transaction/transaction_v1/transaction_v1_header.rs @@ -151,8 +151,8 @@ impl TransactionV1Header { self.timestamp.saturating_add(self.ttl) } - /// Returns the gas tolerance for the given transaction. - pub fn gas_tolerance(&self) -> u64 { + /// Returns the gas price tolerance for the given transaction. + pub fn gas_price_tolerance(&self) -> u8 { match self.pricing_mode { PricingMode::Classic { gas_price, .. } => gas_price, PricingMode::Fixed { @@ -161,7 +161,7 @@ impl TransactionV1Header { } => gas_price_tolerance, PricingMode::Reserved { .. } => { // TODO: Change this when reserve gets implemented. - 0u64 + 0u8 } } } From 5df77f7a93be272b7f5eb5ca8964892d63c48659 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Tue, 26 Mar 2024 14:30:49 -0700 Subject: [PATCH 39/70] restoring Transfer nomenclature --- Makefile | 4 +- .../block/block_execution_results_or_chunk.rs | 4 +- types/benches/bytesrepr_bench.rs | 6 +- types/src/addressable_entity.rs | 2 +- types/src/cl_value.rs | 8 +- types/src/deploy_info.rs | 8 +- types/src/execution/execution_result_v1.rs | 12 +-- types/src/gens.rs | 4 +- types/src/key.rs | 81 ++++++++--------- types/src/lib.rs | 2 +- types/src/transfer.rs | 6 +- types/src/transfer/transfer_v1.rs | 2 +- .../transfer/transfer_v1/transfer_v1_addr.rs | 91 +++++++++---------- utils/validation/src/generators.rs | 10 +- 14 files changed, 115 insertions(+), 125 deletions(-) diff --git a/Makefile b/Makefile index 30abce3cf5..e15f0f483a 100644 --- a/Makefile +++ b/Makefile @@ -76,8 +76,8 @@ resources/local/chainspec.toml: generate-chainspec.sh resources/local/chainspec. @./$< .PHONY: test-rs -test-rs: resources/local/chainspec.toml - $(LEGACY) $(DISABLE_LOGGING) $(CARGO) test --all-features $(CARGO_FLAGS) -- --nocapture +-k test-rs: resources/local/chainspec.toml + $(LEGACY) $(DISABLE_LOGGING) $(CARGO) test --all-features --no-fail-fast $(CARGO_FLAGS) -- --nocapture .PHONY: resources/local/chainspec.toml test-rs-no-default-features: diff --git a/node/src/types/block/block_execution_results_or_chunk.rs b/node/src/types/block/block_execution_results_or_chunk.rs index de95bb9037..6d8114a79c 100644 --- a/node/src/types/block/block_execution_results_or_chunk.rs +++ b/node/src/types/block/block_execution_results_or_chunk.rs @@ -291,7 +291,7 @@ mod tests { use casper_types::{ execution::{execution_result_v1::ExecutionEffect, ExecutionResultV1}, testing::TestRng, - ChunkWithProof, TransferV1Addr, + ChunkWithProof, TransferAddr, }; use super::*; @@ -313,7 +313,7 @@ mod tests { // The serialized_length() of this should be equal to `ChunkWithProof::CHUNK_SIZE_BYTES` let execution_results_v1 = vec![ExecutionResultV1::Failure { effect: ExecutionEffect::default(), - transfers: vec![TransferV1Addr::new([1; 32]); 262143], + transfers: vec![TransferAddr::new([1; 32]); 262143], cost: 2_u64.into(), error_message: "ninebytes".to_string(), }]; diff --git a/types/benches/bytesrepr_bench.rs b/types/benches/bytesrepr_bench.rs index 2c7291146f..35a074a5dd 100644 --- a/types/benches/bytesrepr_bench.rs +++ b/types/benches/bytesrepr_bench.rs @@ -16,7 +16,7 @@ use casper_types::{ DeployInfo, EntityVersionKey, EntityVersions, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Gas, Group, Groups, InitiatorAddr, Key, Package, PackageHash, PackageStatus, Parameter, ProtocolVersion, PublicKey, SecretKey, TransactionHash, TransactionV1Hash, - TransferV1Addr, TransferV2, URef, KEY_HASH_LENGTH, TRANSFER_V1_ADDR_LENGTH, U128, U256, U512, + TransferAddr, TransferV2, URef, KEY_HASH_LENGTH, TRANSFER_ADDR_LENGTH, U128, U256, U512, UREF_ADDR_LENGTH, }; @@ -647,9 +647,9 @@ fn deserialize_transfer(b: &mut Bencher) { fn sample_deploy_info(transfer_len: u16) -> DeployInfo { let transfers = (0..transfer_len) .map(|i| { - let mut tmp = [0u8; TRANSFER_V1_ADDR_LENGTH]; + let mut tmp = [0u8; TRANSFER_ADDR_LENGTH]; U256::from(i).to_little_endian(&mut tmp); - TransferV1Addr::new(tmp) + TransferAddr::new(tmp) }) .collect::>(); DeployInfo::new( diff --git a/types/src/addressable_entity.rs b/types/src/addressable_entity.rs index c3879a96b5..a5d49c45c7 100644 --- a/types/src/addressable_entity.rs +++ b/types/src/addressable_entity.rs @@ -78,7 +78,7 @@ pub const MAX_TOTAL_UREFS: usize = 100; const ADDRESSABLE_ENTITY_STRING_PREFIX: &str = "addressable-entity-"; -const ENTITY_PREFIX: &str = "entity-addr-"; +const ENTITY_PREFIX: &str = "entity-"; const ACCOUNT_ENTITY_PREFIX: &str = "account-"; const CONTRACT_ENTITY_PREFIX: &str = "contract-"; const SYSTEM_ENTITY_PREFIX: &str = "system-"; diff --git a/types/src/cl_value.rs b/types/src/cl_value.rs index 9d7fa8302e..5d0e10ec73 100644 --- a/types/src/cl_value.rs +++ b/types/src/cl_value.rs @@ -262,8 +262,8 @@ mod tests { use crate::{ account::{AccountHash, ACCOUNT_HASH_LENGTH}, key::KEY_HASH_LENGTH, - AccessRights, DeployHash, Digest, Key, PublicKey, TransferV1Addr, URef, - TRANSFER_V1_ADDR_LENGTH, U128, U256, U512, UREF_ADDR_LENGTH, + AccessRights, DeployHash, Digest, Key, PublicKey, TransferAddr, URef, TRANSFER_ADDR_LENGTH, + U128, U256, U512, UREF_ADDR_LENGTH, }; #[cfg(feature = "json-schema")] @@ -425,7 +425,7 @@ mod tests { r#"{"cl_type":"Key","parsed":"uref-0303030303030303030303030303030303030303030303030303030303030303-001"}"#, ); - let key_transfer = Key::Transfer(TransferV1Addr::new([4; TRANSFER_V1_ADDR_LENGTH])); + let key_transfer = Key::Transfer(TransferAddr::new([4; TRANSFER_ADDR_LENGTH])); check_to_json( key_transfer, r#"{"cl_type":"Key","parsed":"transfer-0404040404040404040404040404040404040404040404040404040404040404"}"#, @@ -647,7 +647,7 @@ mod tests { r#"{"cl_type":{"Option":"Key"},"parsed":"uref-0303030303030303030303030303030303030303030303030303030303030303-001"}"#, ); - let key_transfer = Key::Transfer(TransferV1Addr::new([4; TRANSFER_V1_ADDR_LENGTH])); + let key_transfer = Key::Transfer(TransferAddr::new([4; TRANSFER_ADDR_LENGTH])); check_to_json( Some(key_transfer), r#"{"cl_type":{"Option":"Key"},"parsed":"transfer-0404040404040404040404040404040404040404040404040404040404040404"}"#, diff --git a/types/src/deploy_info.rs b/types/src/deploy_info.rs index d98c3b14b9..a741cf96fd 100644 --- a/types/src/deploy_info.rs +++ b/types/src/deploy_info.rs @@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize}; use crate::{ account::AccountHash, bytesrepr::{self, FromBytes, ToBytes}, - serde_helpers, DeployHash, TransferV1Addr, URef, U512, + serde_helpers, DeployHash, TransferAddr, URef, U512, }; /// Information relating to the given Deploy. @@ -26,7 +26,7 @@ pub struct DeployInfo { )] pub deploy_hash: DeployHash, /// Version 1 transfers performed by the Deploy. - pub transfers: Vec, + pub transfers: Vec, /// Account identifier of the creator of the Deploy. pub from: AccountHash, /// Source purse used for payment of the Deploy. @@ -39,7 +39,7 @@ impl DeployInfo { /// Creates a [`DeployInfo`]. pub fn new( deploy_hash: DeployHash, - transfers: &[TransferV1Addr], + transfers: &[TransferAddr], from: AccountHash, source: URef, gas: U512, @@ -58,7 +58,7 @@ impl DeployInfo { impl FromBytes for DeployInfo { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { let (deploy_hash, rem) = DeployHash::from_bytes(bytes)?; - let (transfers, rem) = Vec::::from_bytes(rem)?; + let (transfers, rem) = Vec::::from_bytes(rem)?; let (from, rem) = AccountHash::from_bytes(rem)?; let (source, rem) = URef::from_bytes(rem)?; let (gas, rem) = U512::from_bytes(rem)?; diff --git a/types/src/execution/execution_result_v1.rs b/types/src/execution/execution_result_v1.rs index 19800fcf07..febfe874db 100644 --- a/types/src/execution/execution_result_v1.rs +++ b/types/src/execution/execution_result_v1.rs @@ -22,7 +22,7 @@ use crate::{ account::AccountHash, bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, system::auction::{Bid, BidKind, EraInfo, UnbondingPurse, WithdrawPurse}, - CLValue, DeployInfo, Key, TransferV1, TransferV1Addr, U128, U256, U512, + CLValue, DeployInfo, Key, TransferAddr, TransferV1, U128, U256, U512, }; #[derive(FromPrimitive, ToPrimitive, Debug)] @@ -104,7 +104,7 @@ pub enum ExecutionResultV1 { /// The effect of executing the deploy. effect: ExecutionEffect, /// A record of version 1 Transfers performed while executing the deploy. - transfers: Vec, + transfers: Vec, /// The cost of executing the deploy. cost: U512, /// The error message associated with executing the deploy. @@ -115,7 +115,7 @@ pub enum ExecutionResultV1 { /// The effect of executing the deploy. effect: ExecutionEffect, /// A record of Transfers performed while executing the deploy. - transfers: Vec, + transfers: Vec, /// The cost of executing the deploy. cost: U512, }, @@ -153,7 +153,7 @@ impl Distribution for Standard { let transfer_count = rng.gen_range(0..6); let mut transfers = Vec::new(); for _ in 0..transfer_count { - transfers.push(TransferV1Addr::new(rng.gen())) + transfers.push(TransferAddr::new(rng.gen())) } if rng.gen() { @@ -240,7 +240,7 @@ impl FromBytes for ExecutionResultV1 { match TryFrom::try_from(tag)? { ExecutionResultTag::Failure => { let (effect, remainder) = ExecutionEffect::from_bytes(remainder)?; - let (transfers, remainder) = Vec::::from_bytes(remainder)?; + let (transfers, remainder) = Vec::::from_bytes(remainder)?; let (cost, remainder) = U512::from_bytes(remainder)?; let (error_message, remainder) = String::from_bytes(remainder)?; let execution_result = ExecutionResultV1::Failure { @@ -253,7 +253,7 @@ impl FromBytes for ExecutionResultV1 { } ExecutionResultTag::Success => { let (execution_effect, remainder) = ExecutionEffect::from_bytes(remainder)?; - let (transfers, remainder) = Vec::::from_bytes(remainder)?; + let (transfers, remainder) = Vec::::from_bytes(remainder)?; let (cost, remainder) = U512::from_bytes(remainder)?; let execution_result = ExecutionResultV1::Success { effect: execution_effect, diff --git a/types/src/gens.rs b/types/src/gens.rs index f5bb41d999..6c1572961b 100644 --- a/types/src/gens.rs +++ b/types/src/gens.rs @@ -46,7 +46,7 @@ use crate::{ transaction::gens::deploy_hash_arb, transfer::{ gens::{transfer_v1_addr_arb, transfer_v1_arb}, - TransferV1Addr, + TransferAddr, }, AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, ByteCode, CLType, CLValue, Digest, EntityKind, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, EraId, Group, @@ -128,7 +128,7 @@ pub fn colliding_key_arb() -> impl Strategy { u2_slice_32().prop_map(|bytes| Key::Account(AccountHash::new(bytes))), u2_slice_32().prop_map(Key::Hash), u2_slice_32().prop_map(|bytes| Key::URef(URef::new(bytes, AccessRights::NONE))), - u2_slice_32().prop_map(|bytes| Key::Transfer(TransferV1Addr::new(bytes))), + u2_slice_32().prop_map(|bytes| Key::Transfer(TransferAddr::new(bytes))), u2_slice_32().prop_map(Key::Dictionary), ] } diff --git a/types/src/key.rs b/types/src/key.rs index b22bf623f4..03fcb44503 100644 --- a/types/src/key.rs +++ b/types/src/key.rs @@ -52,13 +52,13 @@ use crate::{ mint::BalanceHoldAddr, }, uref::{self, URef, URefAddr, UREF_SERIALIZED_LENGTH}, - ByteCodeAddr, DeployHash, Digest, EraId, Tagged, TransferFromStrError, TransferV1Addr, - TRANSFER_V1_ADDR_LENGTH, UREF_ADDR_LENGTH, + ByteCodeAddr, DeployHash, Digest, EraId, Tagged, TransferAddr, TransferFromStrError, + TRANSFER_ADDR_LENGTH, UREF_ADDR_LENGTH, }; const HASH_PREFIX: &str = "hash-"; const DEPLOY_INFO_PREFIX: &str = "deploy-"; -const LEGACY_TRANSFER_PREFIX: &str = "transfer-"; +const TRANSFER_PREFIX: &str = "transfer-"; const ERA_INFO_PREFIX: &str = "era-"; const BALANCE_PREFIX: &str = "balance-"; const BALANCE_HOLD_PREFIX: &str = "balance-hold-"; @@ -79,7 +79,7 @@ pub const BLAKE2B_DIGEST_LENGTH: usize = 32; /// The number of bytes in a [`Key::Hash`]. pub const KEY_HASH_LENGTH: usize = 32; /// The number of bytes in a [`Key::Transfer`]. -pub const KEY_LEGACY_TRANSFER_LENGTH: usize = TRANSFER_V1_ADDR_LENGTH; +pub const KEY_TRANSFER_LENGTH: usize = TRANSFER_ADDR_LENGTH; /// The number of bytes in a [`Key::DeployInfo`]. pub const KEY_DEPLOY_INFO_LENGTH: usize = DeployHash::LENGTH; /// The number of bytes in a [`Key::Dictionary`]. @@ -93,8 +93,7 @@ const KEY_ID_SERIALIZED_LENGTH: usize = 1; // u8 used to determine the ID const KEY_HASH_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_HASH_LENGTH; const KEY_UREF_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + UREF_SERIALIZED_LENGTH; -const KEY_LEGACY_TRANSFER_SERIALIZED_LENGTH: usize = - KEY_ID_SERIALIZED_LENGTH + KEY_LEGACY_TRANSFER_LENGTH; +const KEY_TRANSFER_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_TRANSFER_LENGTH; const KEY_DEPLOY_INFO_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_DEPLOY_INFO_LENGTH; const KEY_ERA_INFO_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + U64_SERIALIZED_LENGTH; const KEY_BALANCE_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + UREF_ADDR_LENGTH; @@ -136,7 +135,7 @@ pub enum KeyTag { Account = 0, Hash = 1, URef = 2, - LegacyTransfer = 3, + Transfer = 3, DeployInfo = 4, EraInfo = 5, Balance = 6, @@ -166,7 +165,7 @@ impl KeyTag { 0 => KeyTag::Account, 1 => KeyTag::Hash, 2 => KeyTag::URef, - 3 => KeyTag::LegacyTransfer, + 3 => KeyTag::Transfer, 4 => KeyTag::DeployInfo, 5 => KeyTag::EraInfo, 6 => KeyTag::Balance, @@ -197,7 +196,7 @@ impl Display for KeyTag { KeyTag::Account => write!(f, "Account"), KeyTag::Hash => write!(f, "Hash"), KeyTag::URef => write!(f, "URef"), - KeyTag::LegacyTransfer => write!(f, "LegacyTransfer"), + KeyTag::Transfer => write!(f, "Transfer"), KeyTag::DeployInfo => write!(f, "DeployInfo"), KeyTag::EraInfo => write!(f, "EraInfo"), KeyTag::Balance => write!(f, "Balance"), @@ -245,7 +244,7 @@ impl FromBytes for KeyTag { tag if tag == KeyTag::Account as u8 => KeyTag::Account, tag if tag == KeyTag::Hash as u8 => KeyTag::Hash, tag if tag == KeyTag::URef as u8 => KeyTag::URef, - tag if tag == KeyTag::LegacyTransfer as u8 => KeyTag::LegacyTransfer, + tag if tag == KeyTag::Transfer as u8 => KeyTag::Transfer, tag if tag == KeyTag::DeployInfo as u8 => KeyTag::DeployInfo, tag if tag == KeyTag::EraInfo as u8 => KeyTag::EraInfo, tag if tag == KeyTag::Balance as u8 => KeyTag::Balance, @@ -285,7 +284,7 @@ pub enum Key { /// A `Key` which is a [`URef`], under which most types of data can be stored. URef(URef), /// A `Key` under which a (legacy) transfer is stored. - Transfer(TransferV1Addr), + Transfer(TransferAddr), /// A `Key` under which a deploy info is stored. DeployInfo(DeployHash), /// A `Key` under which an era info is stored. @@ -356,7 +355,7 @@ pub enum FromStrError { /// URef parse error. URef(uref::FromStrError), /// Legacy Transfer parse error. - LegacyTransfer(TransferFromStrError), + Transfer(TransferFromStrError), /// DeployInfo parse error. DeployInfo(String), /// EraInfo parse error. @@ -423,7 +422,7 @@ impl Display for FromStrError { FromStrError::Account(error) => write!(f, "account-key from string error: {}", error), FromStrError::Hash(error) => write!(f, "hash-key from string error: {}", error), FromStrError::URef(error) => write!(f, "uref-key from string error: {}", error), - FromStrError::LegacyTransfer(error) => { + FromStrError::Transfer(error) => { write!(f, "legacy-transfer-key from string error: {}", error) } FromStrError::DeployInfo(error) => { @@ -488,7 +487,7 @@ impl Key { Key::Account(_) => String::from("Key::Account"), Key::Hash(_) => String::from("Key::Hash"), Key::URef(_) => String::from("Key::URef"), - Key::Transfer(_) => String::from("Key::LegacyTransfer"), + Key::Transfer(_) => String::from("Key::Transfer"), Key::DeployInfo(_) => String::from("Key::DeployInfo"), Key::EraInfo(_) => String::from("Key::EraInfo"), Key::Balance(_) => String::from("Key::Balance"), @@ -536,7 +535,7 @@ impl Key { Key::Transfer(transfer_v1_addr) => { format!( "{}{}", - LEGACY_TRANSFER_PREFIX, + TRANSFER_PREFIX, base16::encode_lower(&transfer_v1_addr.value()) ) } @@ -651,12 +650,12 @@ impl Key { return Ok(Key::DeployInfo(DeployHash::new(Digest::from(hash_array)))); } - if let Some(hex) = input.strip_prefix(LEGACY_TRANSFER_PREFIX) { - let v1_addr = checksummed_hex::decode(hex) - .map_err(|error| FromStrError::LegacyTransfer(TransferFromStrError::from(error)))?; - let addr_array = <[u8; TRANSFER_V1_ADDR_LENGTH]>::try_from(v1_addr.as_ref()) - .map_err(|error| FromStrError::LegacyTransfer(TransferFromStrError::from(error)))?; - return Ok(Key::Transfer(TransferV1Addr::new(addr_array))); + if let Some(hex) = input.strip_prefix(TRANSFER_PREFIX) { + let addr = checksummed_hex::decode(hex) + .map_err(|error| FromStrError::Transfer(TransferFromStrError::from(error)))?; + let addr_array = <[u8; TRANSFER_ADDR_LENGTH]>::try_from(addr.as_ref()) + .map_err(|error| FromStrError::Transfer(TransferFromStrError::from(error)))?; + return Ok(Key::Transfer(TransferAddr::new(addr_array))); } match URef::from_formatted_str(input) { @@ -806,7 +805,9 @@ impl Key { match EntityAddr::from_formatted_str(input) { Ok(entity_addr) => return Ok(Key::AddressableEntity(entity_addr)), Err(addressable_entity::FromStrError::InvalidPrefix) => {} - Err(error) => return Err(FromStrError::AddressableEntity(error.to_string())), + Err(error) => { + return Err(FromStrError::AddressableEntity(error.to_string())); + } } match ByteCodeAddr::from_formatted_string(input) { @@ -1217,7 +1218,7 @@ impl Display for Key { Key::Hash(addr) => write!(f, "Key::Hash({})", base16::encode_lower(&addr)), Key::URef(uref) => write!(f, "Key::{}", uref), /* Display impl for URef will append */ Key::Transfer(transfer_v1_addr) => { - write!(f, "Key::LegacyTransfer({})", transfer_v1_addr) + write!(f, "Key::Transfer({})", transfer_v1_addr) } Key::DeployInfo(addr) => write!( f, @@ -1301,7 +1302,7 @@ impl Tagged for Key { Key::Account(_) => KeyTag::Account, Key::Hash(_) => KeyTag::Hash, Key::URef(_) => KeyTag::URef, - Key::Transfer(_) => KeyTag::LegacyTransfer, + Key::Transfer(_) => KeyTag::Transfer, Key::DeployInfo(_) => KeyTag::DeployInfo, Key::EraInfo(_) => KeyTag::EraInfo, Key::Balance(_) => KeyTag::Balance, @@ -1400,7 +1401,7 @@ impl ToBytes for Key { } Key::Hash(_) => KEY_HASH_SERIALIZED_LENGTH, Key::URef(_) => KEY_UREF_SERIALIZED_LENGTH, - Key::Transfer(_) => KEY_LEGACY_TRANSFER_SERIALIZED_LENGTH, + Key::Transfer(_) => KEY_TRANSFER_SERIALIZED_LENGTH, Key::DeployInfo(_) => KEY_DEPLOY_INFO_SERIALIZED_LENGTH, Key::EraInfo(_) => KEY_ERA_INFO_SERIALIZED_LENGTH, Key::Balance(_) => KEY_BALANCE_SERIALIZED_LENGTH, @@ -1479,8 +1480,8 @@ impl FromBytes for Key { let (uref, rem) = URef::from_bytes(remainder)?; Ok((Key::URef(uref), rem)) } - KeyTag::LegacyTransfer => { - let (transfer_v1_addr, rem) = TransferV1Addr::from_bytes(remainder)?; + KeyTag::Transfer => { + let (transfer_v1_addr, rem) = TransferAddr::from_bytes(remainder)?; Ok((Key::Transfer(transfer_v1_addr), rem)) } KeyTag::DeployInfo => { @@ -1601,7 +1602,7 @@ impl Distribution for Standard { 0 => Key::Account(rng.gen()), 1 => Key::Hash(rng.gen()), 2 => Key::URef(rng.gen()), - 3 => Key::Transfer(TransferV1Addr::new(rng.gen())), + 3 => Key::Transfer(TransferAddr::new(rng.gen())), 4 => Key::DeployInfo(DeployHash::from_raw(rng.gen())), 5 => Key::EraInfo(EraId::new(rng.gen())), 6 => Key::Balance(rng.gen()), @@ -1634,7 +1635,7 @@ mod serde_helpers { Account(&'a AccountHash), Hash(&'a HashAddr), URef(&'a URef), - LegacyTransfer(&'a TransferV1Addr), + Transfer(&'a TransferAddr), #[serde(with = "crate::serde_helpers::deploy_hash_as_array")] DeployInfo(&'a DeployHash), EraInfo(&'a EraId), @@ -1662,7 +1663,7 @@ mod serde_helpers { Account(AccountHash), Hash(HashAddr), URef(URef), - LegacyTransfer(TransferV1Addr), + Transfer(TransferAddr), #[serde(with = "crate::serde_helpers::deploy_hash_as_array")] DeployInfo(DeployHash), EraInfo(EraId), @@ -1691,9 +1692,7 @@ mod serde_helpers { Key::Account(account_hash) => BinarySerHelper::Account(account_hash), Key::Hash(hash_addr) => BinarySerHelper::Hash(hash_addr), Key::URef(uref) => BinarySerHelper::URef(uref), - Key::Transfer(transfer_v1_addr) => { - BinarySerHelper::LegacyTransfer(transfer_v1_addr) - } + Key::Transfer(transfer_v1_addr) => BinarySerHelper::Transfer(transfer_v1_addr), Key::DeployInfo(deploy_hash) => BinarySerHelper::DeployInfo(deploy_hash), Key::EraInfo(era_id) => BinarySerHelper::EraInfo(era_id), Key::Balance(uref_addr) => BinarySerHelper::Balance(uref_addr), @@ -1727,9 +1726,7 @@ mod serde_helpers { BinaryDeserHelper::Account(account_hash) => Key::Account(account_hash), BinaryDeserHelper::Hash(hash_addr) => Key::Hash(hash_addr), BinaryDeserHelper::URef(uref) => Key::URef(uref), - BinaryDeserHelper::LegacyTransfer(transfer_v1_addr) => { - Key::Transfer(transfer_v1_addr) - } + BinaryDeserHelper::Transfer(transfer_v1_addr) => Key::Transfer(transfer_v1_addr), BinaryDeserHelper::DeployInfo(deploy_hash) => Key::DeployInfo(deploy_hash), BinaryDeserHelper::EraInfo(era_id) => Key::EraInfo(era_id), BinaryDeserHelper::Balance(uref_addr) => Key::Balance(uref_addr), @@ -1793,7 +1790,7 @@ mod tests { }; const TRANSFER_ADDR_FORMATTED_STRING_PREFIX: &str = "transfer-"; - const ENTITY_PREFIX: &str = "entity-addr-"; + const ENTITY_PREFIX: &str = "entity-"; const ACCOUNT_ENTITY_PREFIX: &str = "account-"; const BYTE_CODE_PREFIX: &str = "byte-code-"; @@ -1802,7 +1799,7 @@ mod tests { const ACCOUNT_KEY: Key = Key::Account(AccountHash::new([42; 32])); const HASH_KEY: Key = Key::Hash([42; 32]); const UREF_KEY: Key = Key::URef(URef::new([42; 32], AccessRights::READ)); - const TRANSFER_KEY: Key = Key::Transfer(TransferV1Addr::new([42; 32])); + const TRANSFER_KEY: Key = Key::Transfer(TransferAddr::new([42; 32])); const DEPLOY_INFO_KEY: Key = Key::DeployInfo(DeployHash::from_raw([42; 32])); const ERA_INFO_KEY: Key = Key::EraInfo(EraId::new(42)); const BALANCE_KEY: Key = Key::Balance([42; 32]); @@ -1945,7 +1942,7 @@ mod tests { ); assert_eq!( format!("{}", TRANSFER_KEY), - format!("Key::LegacyTransfer({})", HEX_STRING) + format!("Key::Transfer({})", HEX_STRING) ); assert_eq!( format!("{}", DEPLOY_INFO_KEY), @@ -2039,14 +2036,14 @@ mod tests { assert_eq!( format!("{}", MESSAGE_TOPIC_KEY), format!( - "Key::Message(addressable-entity-contract-{}-{})", + "Key::Message(entity-contract-{}-{})", HEX_STRING, HEX_STRING ) ); assert_eq!( format!("{}", MESSAGE_KEY), format!( - "Key::Message(addressable-entity-contract-{}-{}-{})", + "Key::Message(entity-contract-{}-{}-{})", HEX_STRING, TOPIC_NAME_HEX_STRING, MESSAGE_INDEX_HEX_STRING ) ); @@ -2395,7 +2392,7 @@ mod tests { round_trip(&Key::Account(AccountHash::new(zeros))); round_trip(&Key::Hash(zeros)); round_trip(&Key::URef(URef::new(zeros, AccessRights::READ))); - round_trip(&Key::Transfer(TransferV1Addr::new(zeros))); + round_trip(&Key::Transfer(TransferAddr::new(zeros))); round_trip(&Key::DeployInfo(DeployHash::from_raw(zeros))); round_trip(&Key::EraInfo(EraId::from(0))); round_trip(&Key::Balance(URef::new(zeros, AccessRights::READ).addr())); diff --git a/types/src/lib.rs b/types/src/lib.rs index 28a74b03a9..90066364ef 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -199,7 +199,7 @@ pub use transaction::{ DeployBuilder, DeployBuilderError, TransactionV1Builder, TransactionV1BuilderError, }; pub use transfer::{ - Transfer, TransferFromStrError, TransferV1, TransferV1Addr, TransferV2, TRANSFER_V1_ADDR_LENGTH, + Transfer, TransferAddr, TransferFromStrError, TransferV1, TransferV2, TRANSFER_ADDR_LENGTH, }; pub use transfer_result::{TransferResult, TransferredTo}; pub use uref::{ diff --git a/types/src/transfer.rs b/types/src/transfer.rs index 27e3358697..f6ae24a3ad 100644 --- a/types/src/transfer.rs +++ b/types/src/transfer.rs @@ -22,7 +22,7 @@ use crate::{account::AccountHash, TransactionV1Hash, URef, U512}; #[cfg(any(feature = "testing", feature = "json-schema", test))] use crate::{Gas, InitiatorAddr, TransactionHash}; pub use error::TransferFromStrError; -pub use transfer_v1::{TransferV1, TransferV1Addr, TRANSFER_V1_ADDR_LENGTH}; +pub use transfer_v1::{TransferAddr, TransferV1, TRANSFER_ADDR_LENGTH}; pub use transfer_v2::TransferV2; const V1_TAG: u8 = 0; @@ -180,8 +180,8 @@ pub mod gens { transaction::gens::deploy_hash_arb, }; - pub fn transfer_v1_addr_arb() -> impl Strategy { - array::uniform32(::arbitrary()).prop_map(TransferV1Addr::new) + pub fn transfer_v1_addr_arb() -> impl Strategy { + array::uniform32(::arbitrary()).prop_map(TransferAddr::new) } pub fn transfer_v1_arb() -> impl Strategy { diff --git a/types/src/transfer/transfer_v1.rs b/types/src/transfer/transfer_v1.rs index b1b00a9949..515b3c2db5 100644 --- a/types/src/transfer/transfer_v1.rs +++ b/types/src/transfer/transfer_v1.rs @@ -13,7 +13,7 @@ use crate::{ bytesrepr::{self, FromBytes, ToBytes}, serde_helpers, DeployHash, URef, U512, }; -pub use transfer_v1_addr::{TransferV1Addr, TRANSFER_V1_ADDR_LENGTH}; +pub use transfer_v1_addr::{TransferAddr, TRANSFER_ADDR_LENGTH}; /// Represents a version 1 transfer from one purse to another. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default, Debug)] diff --git a/types/src/transfer/transfer_v1/transfer_v1_addr.rs b/types/src/transfer/transfer_v1/transfer_v1_addr.rs index 981321c9ae..42381ac05e 100644 --- a/types/src/transfer/transfer_v1/transfer_v1_addr.rs +++ b/types/src/transfer/transfer_v1/transfer_v1_addr.rs @@ -22,10 +22,9 @@ use crate::{ }; /// The length of a version 1 transfer address. -pub const TRANSFER_V1_ADDR_LENGTH: usize = 32; -pub(in crate::transfer) const V1_PREFIX: &str = "v1-"; +pub const TRANSFER_ADDR_LENGTH: usize = 32; -/// A newtype wrapping a [u8; [TRANSFER_V1_ADDR_LENGTH]] which is the raw bytes of the +/// A newtype wrapping a [u8; [TRANSFER_ADDR_LENGTH]] which is the raw bytes of the /// transfer address. #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Default)] #[cfg_attr(feature = "datasize", derive(DataSize))] @@ -34,19 +33,19 @@ pub(in crate::transfer) const V1_PREFIX: &str = "v1-"; derive(JsonSchema), schemars(description = "Hex-encoded version 1 transfer address.") )] -pub struct TransferV1Addr( +pub struct TransferAddr( #[cfg_attr(feature = "json-schema", schemars(skip, with = "String"))] - [u8; TRANSFER_V1_ADDR_LENGTH], + [u8; TRANSFER_ADDR_LENGTH], ); -impl TransferV1Addr { +impl TransferAddr { /// Constructs a new `TransferV1Addr` instance from the raw bytes. - pub const fn new(value: [u8; TRANSFER_V1_ADDR_LENGTH]) -> TransferV1Addr { - TransferV1Addr(value) + pub const fn new(value: [u8; TRANSFER_ADDR_LENGTH]) -> TransferAddr { + TransferAddr(value) } /// Returns the raw bytes of the transfer address as an array. - pub fn value(&self) -> [u8; TRANSFER_V1_ADDR_LENGTH] { + pub fn value(&self) -> [u8; TRANSFER_ADDR_LENGTH] { self.0 } @@ -58,35 +57,30 @@ impl TransferV1Addr { /// Formats the `TransferV1Addr` as a prefixed, hex-encoded string. pub fn to_formatted_string(self) -> String { format!( - "{}{}{}", + "{}{}", TRANSFER_ADDR_FORMATTED_STRING_PREFIX, - V1_PREFIX, base16::encode_lower(&self.0), ) } /// Parses a string formatted as per `Self::to_formatted_string()` into a `TransferV1Addr`. pub fn from_formatted_str(input: &str) -> Result { - let v1_remainder = input + let remainder = input .strip_prefix(TRANSFER_ADDR_FORMATTED_STRING_PREFIX) .ok_or(TransferFromStrError::InvalidPrefix)?; - let remainder = v1_remainder - .strip_prefix(V1_PREFIX) - .ok_or(TransferFromStrError::InvalidPrefix)?; - let bytes = <[u8; TRANSFER_V1_ADDR_LENGTH]>::try_from( - checksummed_hex::decode(remainder)?.as_ref(), - )?; - Ok(TransferV1Addr(bytes)) + let bytes = + <[u8; TRANSFER_ADDR_LENGTH]>::try_from(checksummed_hex::decode(remainder)?.as_ref())?; + Ok(TransferAddr(bytes)) } /// Returns a random `TransferV1Addr`. #[cfg(any(feature = "testing", test))] pub fn random(rng: &mut TestRng) -> Self { - TransferV1Addr(rng.gen()) + TransferAddr(rng.gen()) } } -impl Serialize for TransferV1Addr { +impl Serialize for TransferAddr { fn serialize(&self, serializer: S) -> Result { if serializer.is_human_readable() { self.to_formatted_string().serialize(serializer) @@ -96,37 +90,37 @@ impl Serialize for TransferV1Addr { } } -impl<'de> Deserialize<'de> for TransferV1Addr { +impl<'de> Deserialize<'de> for TransferAddr { fn deserialize>(deserializer: D) -> Result { if deserializer.is_human_readable() { let formatted_string = String::deserialize(deserializer)?; - TransferV1Addr::from_formatted_str(&formatted_string).map_err(SerdeError::custom) + TransferAddr::from_formatted_str(&formatted_string).map_err(SerdeError::custom) } else { - let bytes = <[u8; TRANSFER_V1_ADDR_LENGTH]>::deserialize(deserializer)?; - Ok(TransferV1Addr(bytes)) + let bytes = <[u8; TRANSFER_ADDR_LENGTH]>::deserialize(deserializer)?; + Ok(TransferAddr(bytes)) } } } -impl Display for TransferV1Addr { +impl Display for TransferAddr { fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { write!(formatter, "{}", base16::encode_lower(&self.0)) } } -impl Debug for TransferV1Addr { +impl Debug for TransferAddr { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "TransferV1Addr({})", base16::encode_lower(&self.0)) } } -impl CLTyped for TransferV1Addr { +impl CLTyped for TransferAddr { fn cl_type() -> CLType { - CLType::ByteArray(TRANSFER_V1_ADDR_LENGTH as u32) + CLType::ByteArray(TRANSFER_ADDR_LENGTH as u32) } } -impl ToBytes for TransferV1Addr { +impl ToBytes for TransferAddr { #[inline(always)] fn to_bytes(&self) -> Result, bytesrepr::Error> { self.0.to_bytes() @@ -143,10 +137,10 @@ impl ToBytes for TransferV1Addr { } } -impl FromBytes for TransferV1Addr { +impl FromBytes for TransferAddr { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (bytes, remainder) = <[u8; TRANSFER_V1_ADDR_LENGTH]>::from_bytes(bytes)?; - Ok((TransferV1Addr(bytes), remainder)) + let (bytes, remainder) = <[u8; TRANSFER_ADDR_LENGTH]>::from_bytes(bytes)?; + Ok((TransferAddr(bytes), remainder)) } } @@ -158,43 +152,42 @@ mod tests { #[test] fn transfer_addr_from_str() { - let transfer_address = TransferV1Addr([4; 32]); + let transfer_address = TransferAddr([4; 32]); let encoded = transfer_address.to_formatted_string(); - let decoded = TransferV1Addr::from_formatted_str(&encoded).unwrap(); + let decoded = TransferAddr::from_formatted_str(&encoded).unwrap(); assert_eq!(transfer_address, decoded); let invalid_prefix = - "transfer-v-0000000000000000000000000000000000000000000000000000000000000000"; + "transferv-0000000000000000000000000000000000000000000000000000000000000000"; assert!(matches!( - TransferV1Addr::from_formatted_str(invalid_prefix), + TransferAddr::from_formatted_str(invalid_prefix), Err(TransferFromStrError::InvalidPrefix) )); let invalid_prefix = - "transfer-v10000000000000000000000000000000000000000000000000000000000000000"; + "transfer0000000000000000000000000000000000000000000000000000000000000000"; assert!(matches!( - TransferV1Addr::from_formatted_str(invalid_prefix), + TransferAddr::from_formatted_str(invalid_prefix), Err(TransferFromStrError::InvalidPrefix) )); - let short_addr = - "transfer-v1-00000000000000000000000000000000000000000000000000000000000000"; + let short_addr = "transfer-00000000000000000000000000000000000000000000000000000000000000"; assert!(matches!( - TransferV1Addr::from_formatted_str(short_addr), + TransferAddr::from_formatted_str(short_addr), Err(TransferFromStrError::Length(_)) )); let long_addr = - "transfer-v1-000000000000000000000000000000000000000000000000000000000000000000"; + "transfer-000000000000000000000000000000000000000000000000000000000000000000"; assert!(matches!( - TransferV1Addr::from_formatted_str(long_addr), + TransferAddr::from_formatted_str(long_addr), Err(TransferFromStrError::Length(_)) )); let invalid_hex = - "transfer-v1-000000000000000000000000000000000000000000000000000000000000000g"; + "transfer-000000000000000000000000000000000000000000000000000000000000000g"; assert!(matches!( - TransferV1Addr::from_formatted_str(invalid_hex), + TransferAddr::from_formatted_str(invalid_hex), Err(TransferFromStrError::Hex(_)) )); } @@ -202,14 +195,14 @@ mod tests { #[test] fn bytesrepr_roundtrip() { let rng = &mut TestRng::new(); - let transfer_address = TransferV1Addr::random(rng); + let transfer_address = TransferAddr::random(rng); bytesrepr::test_serialization_roundtrip(&transfer_address) } #[test] fn bincode_roundtrip() { let rng = &mut TestRng::new(); - let transfer_address = TransferV1Addr::random(rng); + let transfer_address = TransferAddr::random(rng); let serialized = bincode::serialize(&transfer_address).unwrap(); let decoded = bincode::deserialize(&serialized).unwrap(); assert_eq!(transfer_address, decoded); @@ -218,7 +211,7 @@ mod tests { #[test] fn json_roundtrip() { let rng = &mut TestRng::new(); - let transfer_address = TransferV1Addr::random(rng); + let transfer_address = TransferAddr::random(rng); let json_string = serde_json::to_string_pretty(&transfer_address).unwrap(); let decoded = serde_json::from_str(&json_string).unwrap(); assert_eq!(transfer_address, decoded); diff --git a/utils/validation/src/generators.rs b/utils/validation/src/generators.rs index 2f973d228d..5f4cbcc888 100644 --- a/utils/validation/src/generators.rs +++ b/utils/validation/src/generators.rs @@ -21,8 +21,8 @@ use casper_types::{ AccessRights, AddressableEntityHash, BlockTime, ByteCode, ByteCodeHash, ByteCodeKind, CLType, CLTyped, CLValue, DeployHash, DeployInfo, EntityVersionKey, EntityVersions, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, EraId, Group, Groups, Key, Package, PackageHash, - PackageStatus, Parameter, ProtocolVersion, PublicKey, SecretKey, StoredValue, TransferV1, - TransferV1Addr, URef, U512, + PackageStatus, Parameter, ProtocolVersion, PublicKey, SecretKey, StoredValue, TransferAddr, + TransferV1, URef, U512, }; use casper_validation::{ abi::{ABIFixture, ABITestCase}, @@ -81,7 +81,7 @@ pub fn make_abi_test_fixtures() -> Result { ); let deploy_info = DeployInfo::new( DeployHash::from_raw([55; 32]), - &[TransferV1Addr::new([1; 32]), TransferV1Addr::new([2; 32])], + &[TransferAddr::new([1; 32]), TransferAddr::new([2; 32])], AccountHash::new([100; 32]), URef::new([10; 32], AccessRights::READ_ADD_WRITE), U512::from(2_500_000_000u64), @@ -205,7 +205,7 @@ pub fn make_abi_test_fixtures() -> Result { const ACCOUNT_KEY: Key = Key::Account(AccountHash::new([42; 32])); const HASH_KEY: Key = Key::Hash([42; 32]); const UREF_KEY: Key = Key::URef(URef::new([42; 32], AccessRights::READ)); - const LEGACY_TRANSFER_KEY: Key = Key::Transfer(TransferV1Addr::new([42; 32])); + const TRANSFER_KEY: Key = Key::Transfer(TransferAddr::new([42; 32])); const DEPLOY_INFO_KEY: Key = Key::DeployInfo(DeployHash::from_raw([42; 32])); const ERA_INFO_KEY: Key = Key::EraInfo(EraId::new(42)); const BALANCE_KEY: Key = Key::Balance([42; 32]); @@ -236,7 +236,7 @@ pub fn make_abi_test_fixtures() -> Result { ); keys.insert( "LegacyTransfer".to_string(), - ABITestCase::from_inputs(vec![LEGACY_TRANSFER_KEY.into()])?, + ABITestCase::from_inputs(vec![TRANSFER_KEY.into()])?, ); keys.insert( "DeployInfo".to_string(), From 6cdc05618a98ef745e51d677bebb7baa702e2ae9 Mon Sep 17 00:00:00 2001 From: Karan Dhareshwar Date: Wed, 27 Mar 2024 09:31:05 -0500 Subject: [PATCH 40/70] Add pricing mode check to config compliance --- node/src/components/transaction_acceptor.rs | 34 ++--- .../components/transaction_acceptor/tests.rs | 4 +- node/src/reactor/main_reactor.rs | 2 +- types/src/chainspec/pricing_handling.rs | 14 ++ types/src/lib.rs | 1 - types/src/transaction/transaction_v1.rs | 124 ++++++++++++------ .../transaction/transaction_v1/errors_v1.rs | 16 ++- 7 files changed, 124 insertions(+), 71 deletions(-) diff --git a/node/src/components/transaction_acceptor.rs b/node/src/components/transaction_acceptor.rs index 88bf938eb9..fd78433adb 100644 --- a/node/src/components/transaction_acceptor.rs +++ b/node/src/components/transaction_acceptor.rs @@ -17,7 +17,7 @@ use casper_types::{ system::auction::ARG_AMOUNT, AddressableEntityHash, AddressableEntityIdentifier, BlockHeader, Chainspec, EntityAddr, EntityVersion, EntityVersionKey, ExecutableDeployItem, ExecutableDeployItemIdentifier, InitiatorAddr, Key, Package, PackageAddr, PackageHash, - PackageIdentifier, ProtocolVersion, SystemConfig, Transaction, TransactionConfig, + PackageIdentifier, Transaction, TransactionEntryPoint, TransactionInvocationTarget, TransactionTarget, U512, }; @@ -72,11 +72,7 @@ impl ReactorEventT for REv where #[derive(Debug, DataSize)] pub struct TransactionAcceptor { acceptor_config: Config, - chain_name: String, - protocol_version: ProtocolVersion, - cost_table: SystemConfig, - transaction_config: TransactionConfig, - max_associated_keys: u32, + chainspec: Arc, administrators: BTreeSet, #[data_size(skip)] metrics: metrics::Metrics, @@ -86,7 +82,7 @@ pub struct TransactionAcceptor { impl TransactionAcceptor { pub(crate) fn new( acceptor_config: Config, - chainspec: &Chainspec, + chainspec: Arc, registry: &Registry, ) -> Result { let administrators = chainspec @@ -95,16 +91,13 @@ impl TransactionAcceptor { .iter() .map(|public_key| public_key.to_account_hash()) .collect(); + let balance_hold_interval = chainspec.core_config.balance_hold_interval.millis(); Ok(TransactionAcceptor { acceptor_config, - chain_name: chainspec.network_config.name.clone(), - protocol_version: chainspec.protocol_version(), - cost_table: chainspec.system_costs_config, - transaction_config: chainspec.transaction_config, - max_associated_keys: chainspec.core_config.max_associated_keys, + chainspec, administrators, metrics: metrics::Metrics::new(registry)?, - balance_hold_interval: chainspec.core_config.balance_hold_interval.millis(), + balance_hold_interval, }) } @@ -122,20 +115,17 @@ impl TransactionAcceptor { let is_config_compliant = match &event_metadata.transaction { Transaction::Deploy(deploy) => deploy .is_config_compliant( - &self.chain_name, - &self.cost_table, - &self.transaction_config, - self.max_associated_keys, + &self.chainspec.network_config.name, + &self.chainspec.system_costs_config, + &self.chainspec.transaction_config, + self.chainspec.core_config.max_associated_keys, self.acceptor_config.timestamp_leeway, event_metadata.verification_start_timestamp, ) .map_err(|err| Error::InvalidTransaction(err.into())), Transaction::V1(txn) => txn .is_config_compliant( - &self.chain_name, - &self.cost_table, - &self.transaction_config, - self.max_associated_keys, + &self.chainspec, self.acceptor_config.timestamp_leeway, event_metadata.verification_start_timestamp, ) @@ -673,7 +663,7 @@ impl TransactionAcceptor { }; let entity_version_key = - EntityVersionKey::new(self.protocol_version.value().major, entity_version); + EntityVersionKey::new(self.chainspec.protocol_config.version.value().major, entity_version); if package.is_version_missing(entity_version_key) { let error = Error::parameter_failure( diff --git a/node/src/components/transaction_acceptor/tests.rs b/node/src/components/transaction_acceptor/tests.rs index 7310a0cf3e..9283000ad9 100644 --- a/node/src/components/transaction_acceptor/tests.rs +++ b/node/src/components/transaction_acceptor/tests.rs @@ -34,7 +34,7 @@ use casper_types::{ Block, BlockV2, CLValue, Chainspec, ChainspecRawBytes, Contract, Deploy, EraId, HashAddr, InvalidDeploy, InvalidTransaction, InvalidTransactionV1, Package, PublicKey, SecretKey, StoredValue, TestBlockBuilder, TimeDiff, Timestamp, Transaction, TransactionSessionKind, - TransactionV1, TransactionV1Builder, URef, U512, + TransactionV1, TransactionV1Builder, URef, U512, ProtocolVersion, }; use super::*; @@ -883,7 +883,7 @@ impl reactor::Reactor for Reactor { let storage_withdir = WithDir::new(storage_tempdir.path(), storage_config); let transaction_acceptor = - TransactionAcceptor::new(Config::default(), chainspec.as_ref(), registry).unwrap(); + TransactionAcceptor::new(Config::default(), Arc::clone(&chainspec), registry).unwrap(); let storage = Storage::new( &storage_withdir, diff --git a/node/src/reactor/main_reactor.rs b/node/src/reactor/main_reactor.rs index 526ef993be..6a9ba9674b 100644 --- a/node/src/reactor/main_reactor.rs +++ b/node/src/reactor/main_reactor.rs @@ -1206,7 +1206,7 @@ impl reactor::Reactor for MainReactor { let upgrade_watcher = UpgradeWatcher::new(chainspec.as_ref(), config.upgrade_watcher, &root_dir)?; let transaction_acceptor = - TransactionAcceptor::new(config.transaction_acceptor, chainspec.as_ref(), registry)?; + TransactionAcceptor::new(config.transaction_acceptor, Arc::clone(&chainspec), registry)?; let transaction_buffer = TransactionBuffer::new(Arc::clone(&chainspec), config.transaction_buffer, registry)?; diff --git a/types/src/chainspec/pricing_handling.rs b/types/src/chainspec/pricing_handling.rs index 4e42b60ae5..dda0e33320 100644 --- a/types/src/chainspec/pricing_handling.rs +++ b/types/src/chainspec/pricing_handling.rs @@ -1,3 +1,4 @@ +use core::fmt::{Display, Formatter}; use crate::{ bytesrepr, bytesrepr::{FromBytes, ToBytes}, @@ -24,6 +25,19 @@ pub enum PricingHandling { Fixed, } +impl Display for PricingHandling { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + match self { + PricingHandling::Classic => { + write!(f, "PricingHandling::Classic") + } + PricingHandling::Fixed => { + write!(f, "PricingHandling::Fixed") + } + } + } +} + impl ToBytes for PricingHandling { fn to_bytes(&self) -> Result, bytesrepr::Error> { let mut buffer = bytesrepr::allocate_buffer(self)?; diff --git a/types/src/lib.rs b/types/src/lib.rs index 28a74b03a9..1bc278fa08 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -22,7 +22,6 @@ extern crate alloc; extern crate core; - mod access_rights; pub mod account; pub mod addressable_entity; diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index 56330508d4..cdc7d785d7 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -35,8 +35,8 @@ use super::{GasLimited, InitiatorAddrAndSecretKey}; use crate::testing::TestRng; use crate::{ bytesrepr::{self, FromBytes, ToBytes}, - crypto, Digest, DisplayIter, RuntimeArgs, SecretKey, TimeDiff, Timestamp, TransactionRuntime, - TransactionSessionKind, + Chainspec, crypto, Digest, DisplayIter, RuntimeArgs, SecretKey, TimeDiff, Timestamp, TransactionRuntime, + TransactionSessionKind }; #[cfg(any(feature = "std", test))] use crate::{Gas, Motes, SystemConfig, TransactionConfig, U512}; @@ -51,6 +51,7 @@ pub use transaction_v1_builder::{TransactionV1Builder, TransactionV1BuilderError pub use transaction_v1_category::TransactionCategory; pub use transaction_v1_hash::TransactionV1Hash; pub use transaction_v1_header::TransactionV1Header; +use crate::chainspec::PricingHandling; /// A unit of work sent by a client to the network, which when executed can cause global state to /// be altered. @@ -350,17 +351,17 @@ impl TransactionV1 { #[cfg(any(feature = "std", test))] pub fn is_config_compliant( &self, - chain_name: &str, - cost_table: &SystemConfig, - transaction_config: &TransactionConfig, - max_associated_keys: u32, + chainspec: &Chainspec, timestamp_leeway: TimeDiff, at: Timestamp, ) -> Result<(), InvalidTransactionV1> { + let transaction_config = chainspec.transaction_config; self.is_valid_size(transaction_config.max_transaction_size)?; + let chain_name = chainspec.network_config.name.clone(); + let header = self.header(); - if header.chain_name() != chain_name { + if header.chain_name() != &chain_name { debug!( transaction_hash = %self.hash(), transaction_header = %header, @@ -373,7 +374,41 @@ impl TransactionV1 { }); } - header.is_valid(transaction_config, timestamp_leeway, at, &self.hash)?; + let price_handling = chainspec.core_config.pricing_handling; + let price_mode = header.pricing_mode(); + + match price_mode { + PricingMode::Classic { .. } => { + if let PricingHandling::Classic = price_handling { + } else { + return Err(InvalidTransactionV1::InvalidPricingMode { + price_handling, + price_mode: price_mode.clone(), + }) + } + } + PricingMode::Fixed { .. } => { + if let PricingHandling::Fixed = price_handling { + } else { + return Err(InvalidTransactionV1::InvalidPricingMode { + price_handling, + price_mode: price_mode.clone(), + }) + } + } + PricingMode::Reserved { .. } => { + // Currently Reserved isn't implemented and we should + // not be accepting transactions with this mode. + return Err(InvalidTransactionV1::InvalidPricingMode { + price_handling, + price_mode: price_mode.clone(), + }) + } + } + + header.is_valid(&transaction_config, timestamp_leeway, at, &self.hash)?; + + let max_associated_keys = chainspec.core_config.max_associated_keys; if self.approvals.len() > max_associated_keys as usize { debug!( @@ -388,7 +423,7 @@ impl TransactionV1 { }); } - let gas_limit = self.gas_limit(cost_table, None)?; + let gas_limit = self.gas_limit(&chainspec.system_costs_config, None)?; let block_gas_limit = Gas::new(U512::from(transaction_config.block_gas_limit)); if gas_limit > block_gas_limit { debug!( @@ -402,7 +437,7 @@ impl TransactionV1 { }); } - self.body.is_valid(transaction_config) + self.body.is_valid(&transaction_config) } // This method is not intended to be used by third party crates. @@ -926,15 +961,15 @@ mod tests { .with_chain_name(chain_name) .build() .unwrap(); - let cost_table = SystemConfig::default(); - let transaction_config = TransactionConfig::default(); let current_timestamp = transaction.timestamp(); + let chainspec = { + let mut ret = Chainspec::default(); + ret.network_config.name = chain_name.to_string(); + ret + }; transaction .is_config_compliant( - chain_name, - &cost_table, - &transaction_config, - MAX_ASSOCIATED_KEYS, + &chainspec, TimeDiff::default(), current_timestamp, ) @@ -946,9 +981,6 @@ mod tests { let rng = &mut TestRng::new(); let expected_chain_name = "net-1"; let wrong_chain_name = "net-2"; - let cost_table = SystemConfig::default(); - let transaction_config = TransactionConfig::default(); - let transaction = TransactionV1Builder::new_random(rng) .with_chain_name(wrong_chain_name) .build() @@ -960,14 +992,16 @@ mod tests { }; let current_timestamp = transaction.timestamp(); + let chainspec = { + let mut ret = Chainspec::default(); + ret.network_config.name = expected_chain_name.to_string(); + ret + }; assert_eq!( transaction.is_config_compliant( - expected_chain_name, - &cost_table, - &transaction_config, - MAX_ASSOCIATED_KEYS, + &chainspec, TimeDiff::default(), - current_timestamp + current_timestamp, ), Err(expected_error) ); @@ -981,7 +1015,6 @@ mod tests { fn not_acceptable_due_to_excessive_ttl() { let rng = &mut TestRng::new(); let chain_name = "net-1"; - let cost_table = SystemConfig::default(); let transaction_config = TransactionConfig::default(); let ttl = transaction_config.max_ttl + TimeDiff::from(Duration::from_secs(1)); let transaction = TransactionV1Builder::new_random(rng) @@ -996,14 +1029,16 @@ mod tests { }; let current_timestamp = transaction.timestamp(); + let chainspec = { + let mut ret = Chainspec::default(); + ret.network_config.name = chain_name.to_string(); + ret + }; assert_eq!( transaction.is_config_compliant( - chain_name, - &cost_table, - &transaction_config, - MAX_ASSOCIATED_KEYS, + &chainspec, TimeDiff::default(), - current_timestamp + current_timestamp, ), Err(expected_error) ); @@ -1017,8 +1052,6 @@ mod tests { fn not_acceptable_due_to_timestamp_in_future() { let rng = &mut TestRng::new(); let chain_name = "net-1"; - let cost_table = SystemConfig::default(); - let transaction_config = TransactionConfig::default(); let leeway = TimeDiff::from_seconds(2); let transaction = TransactionV1Builder::new_random(rng) @@ -1033,12 +1066,15 @@ mod tests { got: transaction.timestamp(), }; + let chainspec = { + let mut ret = Chainspec::default(); + ret.network_config.name = chain_name.to_string(); + ret + }; + assert_eq!( transaction.is_config_compliant( - chain_name, - &cost_table, - &transaction_config, - MAX_ASSOCIATED_KEYS, + &chainspec, leeway, current_timestamp ), @@ -1054,8 +1090,6 @@ mod tests { fn not_acceptable_due_to_excessive_approvals() { let rng = &mut TestRng::new(); let chain_name = "net-1"; - let cost_table = SystemConfig::default(); - let transaction_config = TransactionConfig::default(); let mut transaction = TransactionV1Builder::new_random(rng) .with_chain_name(chain_name) .build() @@ -1072,14 +1106,18 @@ mod tests { max_associated_keys: MAX_ASSOCIATED_KEYS, }; + let chainspec = { + let mut ret = Chainspec::default(); + ret.network_config.name = chain_name.to_string(); + ret.core_config.max_associated_keys = MAX_ASSOCIATED_KEYS; + ret + }; + assert_eq!( transaction.is_config_compliant( - chain_name, - &cost_table, - &transaction_config, - MAX_ASSOCIATED_KEYS, + &chainspec, TimeDiff::default(), - current_timestamp + current_timestamp, ), Err(expected_error) ); diff --git a/types/src/transaction/transaction_v1/errors_v1.rs b/types/src/transaction/transaction_v1/errors_v1.rs index 5d5124964b..050448930b 100644 --- a/types/src/transaction/transaction_v1/errors_v1.rs +++ b/types/src/transaction/transaction_v1/errors_v1.rs @@ -13,7 +13,8 @@ use serde::Serialize; use super::super::TransactionEntryPoint; #[cfg(doc)] use super::TransactionV1; -use crate::{bytesrepr, crypto, CLType, DisplayIter, TimeDiff, Timestamp, U512}; +use crate::{bytesrepr, crypto, CLType, DisplayIter, TimeDiff, Timestamp, U512, PricingMode}; +use crate::chainspec::PricingHandling; /// Returned when a [`TransactionV1`] fails validation. #[derive(Clone, Eq, PartialEq, Debug)] @@ -145,6 +146,13 @@ pub enum InvalidTransaction { }, /// Unable to calculate gas limit. UnableToCalculateGasLimit, + /// Invalid combination of pricing handling and pricing mode. + InvalidPricingMode { + /// The price handling as determined by the chainspec. + price_handling: PricingHandling, + /// The pricing mode as specified by the transaction. + price_mode: PricingMode, + } } impl Display for InvalidTransaction { @@ -265,6 +273,9 @@ impl Display for InvalidTransaction { InvalidTransaction::UnableToCalculateGasLimit => { write!(formatter, "unable to calculate gas limit",) } + InvalidTransaction::InvalidPricingMode { price_handling, price_mode} => { + write!(formatter, "received a transaction with mode {price_mode} with price handling {price_handling}") + } } } } @@ -298,7 +309,8 @@ impl StdError for InvalidTransaction { | InvalidTransaction::EntryPointMustBeCustom { .. } | InvalidTransaction::EmptyModuleBytes | InvalidTransaction::GasPriceConversion { .. } - | InvalidTransaction::UnableToCalculateGasLimit => None, + | InvalidTransaction::UnableToCalculateGasLimit + | InvalidTransaction::InvalidPricingMode { .. }=> None, } } } From 8f1b9044c97d547144935c802ecc6978498bc1ba Mon Sep 17 00:00:00 2001 From: Karan Dhareshwar Date: Wed, 27 Mar 2024 09:56:15 -0500 Subject: [PATCH 41/70] Add test for pricing mode check to config compliance --- types/src/transaction/transaction_v1.rs | 123 ++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index cdc7d785d7..033fb9f8ee 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -1126,4 +1126,127 @@ mod tests { "transaction should not have run expensive `is_verified` call" ); } + + #[test] + fn not_acceptable_due_to_invalid_pricing_modes() { + let rng = &mut TestRng::new(); + let chain_name = "net-1"; + + let reserved_mode = PricingMode::Reserved { + receipt: Default::default(), + paid_amount: Default::default(), + }; + + let reserved_transaction = TransactionV1Builder::new_random(rng) + .with_chain_name(chain_name) + .with_pricing_mode(reserved_mode.clone()) + .build() + .expect("must be able to create a reserved transaction"); + + let chainspec = { + let mut ret = Chainspec::default(); + ret.network_config.name = chain_name.to_string(); + ret + }; + + let expected_pricing_handling = chainspec.core_config.pricing_handling; + + let current_timestamp = reserved_transaction.timestamp(); + let expected_error = InvalidTransactionV1::InvalidPricingMode { + price_handling: expected_pricing_handling, + price_mode: reserved_mode, + }; + assert_eq!( + reserved_transaction.is_config_compliant( + &chainspec, + TimeDiff::default(), + current_timestamp, + ), + Err(expected_error) + ); + assert!( + reserved_transaction.is_verified.get().is_none(), + "transaction should not have run expensive `is_verified` call" + ); + + let fixed_mode_transaction = TransactionV1Builder::new_random(rng) + .with_chain_name(chain_name) + .with_pricing_mode(PricingMode::Fixed {gas_price_tolerance: 1u8}) + .build() + .expect("must create fixed mode transaction"); + + let fixed_handling_chainspec = { + let mut ret = Chainspec::default(); + ret.network_config.name = chain_name.to_string(); + ret.core_config.pricing_handling = PricingHandling::Fixed; + ret + }; + + let classic_handling_chainspec = { + let mut ret = Chainspec::default(); + ret.network_config.name = chain_name.to_string(); + ret.core_config.pricing_handling = PricingHandling::Classic; + ret + }; + + let current_timestamp = fixed_mode_transaction.timestamp(); + let expected_error = InvalidTransactionV1::InvalidPricingMode { + price_handling: PricingHandling::Classic, + price_mode: fixed_mode_transaction.pricing_mode().clone(), + }; + + assert_eq!( + fixed_mode_transaction.is_config_compliant( + &classic_handling_chainspec, + TimeDiff::default(), + current_timestamp, + ), + Err(expected_error) + ); + assert!( + fixed_mode_transaction.is_verified.get().is_none(), + "transaction should not have run expensive `is_verified` call" + ); + + assert!(fixed_mode_transaction.is_config_compliant( + &fixed_handling_chainspec, + TimeDiff::default(), + current_timestamp + ).is_ok()); + + let classic_mode_transaction = TransactionV1Builder::new_random(rng) + .with_chain_name(chain_name) + .with_pricing_mode(PricingMode::Classic { + payment_amount: 100000, + gas_price: 1, + standard_payment: true, + }) + .build() + .expect("must create classic transaction"); + + let current_timestamp = classic_mode_transaction.timestamp(); + let expected_error = InvalidTransactionV1::InvalidPricingMode { + price_handling: PricingHandling::Fixed, + price_mode: classic_mode_transaction.pricing_mode().clone() + }; + + assert_eq!( + classic_mode_transaction.is_config_compliant( + &fixed_handling_chainspec, + TimeDiff::default(), + current_timestamp, + ), + Err(expected_error) + ); + assert!( + classic_mode_transaction.is_verified.get().is_none(), + "transaction should not have run expensive `is_verified` call" + ); + + assert!(classic_mode_transaction.is_config_compliant( + &classic_handling_chainspec, + TimeDiff::default(), + current_timestamp + ).is_ok()); + } } From b73facf04fbe8c446f6f7fa8d37fef4ab476b093 Mon Sep 17 00:00:00 2001 From: Karan Dhareshwar Date: Wed, 27 Mar 2024 10:35:13 -0500 Subject: [PATCH 42/70] Run make format --- node/src/components/transaction_acceptor.rs | 12 ++-- .../components/transaction_acceptor/tests.rs | 6 +- node/src/reactor/main_reactor.rs | 7 +- types/src/chainspec/pricing_handling.rs | 2 +- types/src/transaction/transaction_v1.rs | 72 ++++++++----------- .../transaction/transaction_v1/errors_v1.rs | 15 ++-- 6 files changed, 55 insertions(+), 59 deletions(-) diff --git a/node/src/components/transaction_acceptor.rs b/node/src/components/transaction_acceptor.rs index fd78433adb..39739f8983 100644 --- a/node/src/components/transaction_acceptor.rs +++ b/node/src/components/transaction_acceptor.rs @@ -17,8 +17,8 @@ use casper_types::{ system::auction::ARG_AMOUNT, AddressableEntityHash, AddressableEntityIdentifier, BlockHeader, Chainspec, EntityAddr, EntityVersion, EntityVersionKey, ExecutableDeployItem, ExecutableDeployItemIdentifier, InitiatorAddr, Key, Package, PackageAddr, PackageHash, - PackageIdentifier, Transaction, - TransactionEntryPoint, TransactionInvocationTarget, TransactionTarget, U512, + PackageIdentifier, Transaction, TransactionEntryPoint, TransactionInvocationTarget, + TransactionTarget, U512, }; use crate::{ @@ -91,7 +91,7 @@ impl TransactionAcceptor { .iter() .map(|public_key| public_key.to_account_hash()) .collect(); - let balance_hold_interval = chainspec.core_config.balance_hold_interval.millis(); + let balance_hold_interval = chainspec.core_config.balance_hold_interval.millis(); Ok(TransactionAcceptor { acceptor_config, chainspec, @@ -662,8 +662,10 @@ impl TransactionAcceptor { } }; - let entity_version_key = - EntityVersionKey::new(self.chainspec.protocol_config.version.value().major, entity_version); + let entity_version_key = EntityVersionKey::new( + self.chainspec.protocol_config.version.value().major, + entity_version, + ); if package.is_version_missing(entity_version_key) { let error = Error::parameter_failure( diff --git a/node/src/components/transaction_acceptor/tests.rs b/node/src/components/transaction_acceptor/tests.rs index 9283000ad9..cfa585ad15 100644 --- a/node/src/components/transaction_acceptor/tests.rs +++ b/node/src/components/transaction_acceptor/tests.rs @@ -32,9 +32,9 @@ use casper_types::{ global_state::TrieMerkleProof, testing::TestRng, Block, BlockV2, CLValue, Chainspec, ChainspecRawBytes, Contract, Deploy, EraId, HashAddr, - InvalidDeploy, InvalidTransaction, InvalidTransactionV1, Package, PublicKey, SecretKey, - StoredValue, TestBlockBuilder, TimeDiff, Timestamp, Transaction, TransactionSessionKind, - TransactionV1, TransactionV1Builder, URef, U512, ProtocolVersion, + InvalidDeploy, InvalidTransaction, InvalidTransactionV1, Package, ProtocolVersion, PublicKey, + SecretKey, StoredValue, TestBlockBuilder, TimeDiff, Timestamp, Transaction, + TransactionSessionKind, TransactionV1, TransactionV1Builder, URef, U512, }; use super::*; diff --git a/node/src/reactor/main_reactor.rs b/node/src/reactor/main_reactor.rs index 6a9ba9674b..8159a2edcf 100644 --- a/node/src/reactor/main_reactor.rs +++ b/node/src/reactor/main_reactor.rs @@ -1205,8 +1205,11 @@ impl reactor::Reactor for MainReactor { ); let upgrade_watcher = UpgradeWatcher::new(chainspec.as_ref(), config.upgrade_watcher, &root_dir)?; - let transaction_acceptor = - TransactionAcceptor::new(config.transaction_acceptor, Arc::clone(&chainspec), registry)?; + let transaction_acceptor = TransactionAcceptor::new( + config.transaction_acceptor, + Arc::clone(&chainspec), + registry, + )?; let transaction_buffer = TransactionBuffer::new(Arc::clone(&chainspec), config.transaction_buffer, registry)?; diff --git a/types/src/chainspec/pricing_handling.rs b/types/src/chainspec/pricing_handling.rs index dda0e33320..f5548e513e 100644 --- a/types/src/chainspec/pricing_handling.rs +++ b/types/src/chainspec/pricing_handling.rs @@ -1,8 +1,8 @@ -use core::fmt::{Display, Formatter}; use crate::{ bytesrepr, bytesrepr::{FromBytes, ToBytes}, }; +use core::fmt::{Display, Formatter}; #[cfg(feature = "datasize")] use datasize::DataSize; use serde::{Deserialize, Serialize}; diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index 033fb9f8ee..83b65d5ba1 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -35,8 +35,9 @@ use super::{GasLimited, InitiatorAddrAndSecretKey}; use crate::testing::TestRng; use crate::{ bytesrepr::{self, FromBytes, ToBytes}, - Chainspec, crypto, Digest, DisplayIter, RuntimeArgs, SecretKey, TimeDiff, Timestamp, TransactionRuntime, - TransactionSessionKind + chainspec::PricingHandling, + crypto, Chainspec, Digest, DisplayIter, RuntimeArgs, SecretKey, TimeDiff, Timestamp, + TransactionRuntime, TransactionSessionKind, }; #[cfg(any(feature = "std", test))] use crate::{Gas, Motes, SystemConfig, TransactionConfig, U512}; @@ -51,7 +52,6 @@ pub use transaction_v1_builder::{TransactionV1Builder, TransactionV1BuilderError pub use transaction_v1_category::TransactionCategory; pub use transaction_v1_hash::TransactionV1Hash; pub use transaction_v1_header::TransactionV1Header; -use crate::chainspec::PricingHandling; /// A unit of work sent by a client to the network, which when executed can cause global state to /// be altered. @@ -384,7 +384,7 @@ impl TransactionV1 { return Err(InvalidTransactionV1::InvalidPricingMode { price_handling, price_mode: price_mode.clone(), - }) + }); } } PricingMode::Fixed { .. } => { @@ -393,7 +393,7 @@ impl TransactionV1 { return Err(InvalidTransactionV1::InvalidPricingMode { price_handling, price_mode: price_mode.clone(), - }) + }); } } PricingMode::Reserved { .. } => { @@ -402,7 +402,7 @@ impl TransactionV1 { return Err(InvalidTransactionV1::InvalidPricingMode { price_handling, price_mode: price_mode.clone(), - }) + }); } } @@ -968,11 +968,7 @@ mod tests { ret }; transaction - .is_config_compliant( - &chainspec, - TimeDiff::default(), - current_timestamp, - ) + .is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp) .expect("should be acceptable"); } @@ -998,11 +994,7 @@ mod tests { ret }; assert_eq!( - transaction.is_config_compliant( - &chainspec, - TimeDiff::default(), - current_timestamp, - ), + transaction.is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp,), Err(expected_error) ); assert!( @@ -1035,11 +1027,7 @@ mod tests { ret }; assert_eq!( - transaction.is_config_compliant( - &chainspec, - TimeDiff::default(), - current_timestamp, - ), + transaction.is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp,), Err(expected_error) ); assert!( @@ -1073,11 +1061,7 @@ mod tests { }; assert_eq!( - transaction.is_config_compliant( - &chainspec, - leeway, - current_timestamp - ), + transaction.is_config_compliant(&chainspec, leeway, current_timestamp), Err(expected_error) ); assert!( @@ -1114,11 +1098,7 @@ mod tests { }; assert_eq!( - transaction.is_config_compliant( - &chainspec, - TimeDiff::default(), - current_timestamp, - ), + transaction.is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp,), Err(expected_error) ); assert!( @@ -1171,7 +1151,9 @@ mod tests { let fixed_mode_transaction = TransactionV1Builder::new_random(rng) .with_chain_name(chain_name) - .with_pricing_mode(PricingMode::Fixed {gas_price_tolerance: 1u8}) + .with_pricing_mode(PricingMode::Fixed { + gas_price_tolerance: 1u8, + }) .build() .expect("must create fixed mode transaction"); @@ -1208,11 +1190,13 @@ mod tests { "transaction should not have run expensive `is_verified` call" ); - assert!(fixed_mode_transaction.is_config_compliant( - &fixed_handling_chainspec, - TimeDiff::default(), - current_timestamp - ).is_ok()); + assert!(fixed_mode_transaction + .is_config_compliant( + &fixed_handling_chainspec, + TimeDiff::default(), + current_timestamp + ) + .is_ok()); let classic_mode_transaction = TransactionV1Builder::new_random(rng) .with_chain_name(chain_name) @@ -1227,7 +1211,7 @@ mod tests { let current_timestamp = classic_mode_transaction.timestamp(); let expected_error = InvalidTransactionV1::InvalidPricingMode { price_handling: PricingHandling::Fixed, - price_mode: classic_mode_transaction.pricing_mode().clone() + price_mode: classic_mode_transaction.pricing_mode().clone(), }; assert_eq!( @@ -1243,10 +1227,12 @@ mod tests { "transaction should not have run expensive `is_verified` call" ); - assert!(classic_mode_transaction.is_config_compliant( - &classic_handling_chainspec, - TimeDiff::default(), - current_timestamp - ).is_ok()); + assert!(classic_mode_transaction + .is_config_compliant( + &classic_handling_chainspec, + TimeDiff::default(), + current_timestamp + ) + .is_ok()); } } diff --git a/types/src/transaction/transaction_v1/errors_v1.rs b/types/src/transaction/transaction_v1/errors_v1.rs index 050448930b..264159f73e 100644 --- a/types/src/transaction/transaction_v1/errors_v1.rs +++ b/types/src/transaction/transaction_v1/errors_v1.rs @@ -13,8 +13,10 @@ use serde::Serialize; use super::super::TransactionEntryPoint; #[cfg(doc)] use super::TransactionV1; -use crate::{bytesrepr, crypto, CLType, DisplayIter, TimeDiff, Timestamp, U512, PricingMode}; -use crate::chainspec::PricingHandling; +use crate::{ + bytesrepr, chainspec::PricingHandling, crypto, CLType, DisplayIter, PricingMode, TimeDiff, + Timestamp, U512, +}; /// Returned when a [`TransactionV1`] fails validation. #[derive(Clone, Eq, PartialEq, Debug)] @@ -152,7 +154,7 @@ pub enum InvalidTransaction { price_handling: PricingHandling, /// The pricing mode as specified by the transaction. price_mode: PricingMode, - } + }, } impl Display for InvalidTransaction { @@ -273,7 +275,10 @@ impl Display for InvalidTransaction { InvalidTransaction::UnableToCalculateGasLimit => { write!(formatter, "unable to calculate gas limit",) } - InvalidTransaction::InvalidPricingMode { price_handling, price_mode} => { + InvalidTransaction::InvalidPricingMode { + price_handling, + price_mode, + } => { write!(formatter, "received a transaction with mode {price_mode} with price handling {price_handling}") } } @@ -310,7 +315,7 @@ impl StdError for InvalidTransaction { | InvalidTransaction::EmptyModuleBytes | InvalidTransaction::GasPriceConversion { .. } | InvalidTransaction::UnableToCalculateGasLimit - | InvalidTransaction::InvalidPricingMode { .. }=> None, + | InvalidTransaction::InvalidPricingMode { .. } => None, } } } From 3717003954b8ab0648892681dcd99eaca4c3d6b9 Mon Sep 17 00:00:00 2001 From: Karan Dhareshwar Date: Wed, 27 Mar 2024 11:16:22 -0500 Subject: [PATCH 43/70] Add transaction acceptor level test --- node/src/components/transaction_acceptor.rs | 17 --------- .../components/transaction_acceptor/tests.rs | 37 +++++++++++++------ types/src/transaction/transaction_v1.rs | 6 +-- .../transaction/transaction_v1/errors_v1.rs | 6 ++- 4 files changed, 32 insertions(+), 34 deletions(-) diff --git a/node/src/components/transaction_acceptor.rs b/node/src/components/transaction_acceptor.rs index 39739f8983..8f5a7c59fc 100644 --- a/node/src/components/transaction_acceptor.rs +++ b/node/src/components/transaction_acceptor.rs @@ -152,23 +152,6 @@ impl TransactionAcceptor { ); } - // // If this has been received from the speculative exec server, use the block specified in - // // the request, otherwise use the highest complete block. - // if let Source::SpeculativeExec = &event_metadata.source { - // let account_key = match event_metadata.transaction.initiator_addr() { - // InitiatorAddr::PublicKey(public_key) => Key::from(public_key.to_account_hash()), - // InitiatorAddr::AccountHash(account_hash) => Key::from(account_hash), - // }; - // - // return effect_builder - // .get_addressable_entity(*block_header.state_root_hash(), account_key) - // .event(move |result| Event::GetAddressableEntityResult { - // event_metadata, - // maybe_entity: result.into_option(), - // block_header, - // }); - // } - effect_builder .get_highest_complete_block_header_from_storage() .event(move |maybe_block_header| Event::GetBlockHeaderResult { diff --git a/node/src/components/transaction_acceptor/tests.rs b/node/src/components/transaction_acceptor/tests.rs index cfa585ad15..9a593e90d1 100644 --- a/node/src/components/transaction_acceptor/tests.rs +++ b/node/src/components/transaction_acceptor/tests.rs @@ -25,17 +25,7 @@ use casper_storage::{ data_access_layer::{AddressableEntityResult, BalanceIdentifier, BalanceResult, QueryResult}, tracking_copy::TrackingCopyError, }; -use casper_types::{ - account::{Account, AccountHash, ActionThresholds, AssociatedKeys, Weight}, - addressable_entity::{AddressableEntity, NamedKeys}, - bytesrepr::Bytes, - global_state::TrieMerkleProof, - testing::TestRng, - Block, BlockV2, CLValue, Chainspec, ChainspecRawBytes, Contract, Deploy, EraId, HashAddr, - InvalidDeploy, InvalidTransaction, InvalidTransactionV1, Package, ProtocolVersion, PublicKey, - SecretKey, StoredValue, TestBlockBuilder, TimeDiff, Timestamp, Transaction, - TransactionSessionKind, TransactionV1, TransactionV1Builder, URef, U512, -}; +use casper_types::{account::{Account, AccountHash, ActionThresholds, AssociatedKeys, Weight}, addressable_entity::{AddressableEntity, NamedKeys}, bytesrepr::Bytes, global_state::TrieMerkleProof, testing::TestRng, Block, BlockV2, CLValue, Chainspec, ChainspecRawBytes, Contract, Deploy, EraId, HashAddr, InvalidDeploy, InvalidTransaction, InvalidTransactionV1, Package, ProtocolVersion, PublicKey, SecretKey, StoredValue, TestBlockBuilder, TimeDiff, Timestamp, Transaction, TransactionSessionKind, TransactionV1, TransactionV1Builder, URef, U512, PricingMode}; use super::*; use crate::{ @@ -207,6 +197,7 @@ enum TestScenario { DeployWithoutTransferTarget, DeployWithoutTransferAmount, BalanceCheckForDeploySentByPeer, + InvalidPricingModeForTransactionV1, } impl TestScenario { @@ -246,7 +237,8 @@ impl TestScenario { | TestScenario::FromClientSessionContractPackage(..) | TestScenario::FromClientSignedByAdmin(_) | TestScenario::DeployWithEmptySessionModuleBytes - | TestScenario::DeployWithNativeTransferInPayment => Source::Client, + | TestScenario::DeployWithNativeTransferInPayment + | TestScenario::InvalidPricingModeForTransactionV1 => Source::Client, } } @@ -553,6 +545,18 @@ impl TestScenario { } } } + TestScenario::InvalidPricingModeForTransactionV1 => { + let classic_mode_transaction = TransactionV1Builder::new_random(rng) + .with_pricing_mode(PricingMode::Classic { + payment_amount: 10000u64, + gas_price: 1u8, + standard_payment: true + }) + .with_chain_name("casper-example") + .build() + .expect("must create classic mode transaction"); + Transaction::from(classic_mode_transaction) + } } } @@ -606,6 +610,7 @@ impl TestScenario { | ContractPackageScenario::MissingContractVersion => false, } } + TestScenario::InvalidPricingModeForTransactionV1 => false, } } @@ -1093,6 +1098,7 @@ async fn run_transaction_acceptor_without_timeout( | TestScenario::DeployWithMangledTransferAmount | TestScenario::DeployWithoutTransferTarget | TestScenario::DeployWithoutTransferAmount + | TestScenario::InvalidPricingModeForTransactionV1 | TestScenario::FromClientExpired(_) => { matches!( event, @@ -2305,3 +2311,10 @@ async fn should_accept_transaction_v1_signed_by_admin_from_client() { let result = run_transaction_acceptor(test_scenario).await; assert!(result.is_ok()) } + +#[tokio::test] +async fn should_reject_transaction_v1_with_invalid_pricing_mode() { + let test_scenario = TestScenario::InvalidPricingModeForTransactionV1; + let result = run_transaction_acceptor(test_scenario).await; + assert!(matches!(result, Err(super::Error::InvalidTransaction(InvalidTransaction::V1(InvalidTransactionV1::InvalidPricingMode { .. }))))) +} diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index 83b65d5ba1..d9e5705c48 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -32,11 +32,11 @@ use super::{ #[cfg(any(feature = "std", test))] use super::{GasLimited, InitiatorAddrAndSecretKey}; #[cfg(any(all(feature = "std", feature = "testing"), test))] -use crate::testing::TestRng; +use crate::{testing::TestRng, Chainspec, + chainspec::PricingHandling}; use crate::{ bytesrepr::{self, FromBytes, ToBytes}, - chainspec::PricingHandling, - crypto, Chainspec, Digest, DisplayIter, RuntimeArgs, SecretKey, TimeDiff, Timestamp, + crypto, Digest, DisplayIter, RuntimeArgs, SecretKey, TimeDiff, Timestamp, TransactionRuntime, TransactionSessionKind, }; #[cfg(any(feature = "std", test))] diff --git a/types/src/transaction/transaction_v1/errors_v1.rs b/types/src/transaction/transaction_v1/errors_v1.rs index 264159f73e..0cd19ebfd4 100644 --- a/types/src/transaction/transaction_v1/errors_v1.rs +++ b/types/src/transaction/transaction_v1/errors_v1.rs @@ -13,9 +13,11 @@ use serde::Serialize; use super::super::TransactionEntryPoint; #[cfg(doc)] use super::TransactionV1; +#[cfg(feature = "std")] +use crate::{chainspec::PricingHandling}; use crate::{ - bytesrepr, chainspec::PricingHandling, crypto, CLType, DisplayIter, PricingMode, TimeDiff, - Timestamp, U512, + bytesrepr, crypto, CLType, DisplayIter, TimeDiff, + Timestamp, U512, PricingMode, }; /// Returned when a [`TransactionV1`] fails validation. From df6b61b645ece4f355e165ee6457ebc7600eaa49 Mon Sep 17 00:00:00 2001 From: Karan Dhareshwar Date: Wed, 27 Mar 2024 11:29:36 -0500 Subject: [PATCH 44/70] Fix issues for lints --- types/src/transaction/transaction_v1.rs | 6 ------ types/src/transaction/transaction_v1/errors_v1.rs | 7 +------ 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index d9e5705c48..b9c3885408 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -382,7 +382,6 @@ impl TransactionV1 { if let PricingHandling::Classic = price_handling { } else { return Err(InvalidTransactionV1::InvalidPricingMode { - price_handling, price_mode: price_mode.clone(), }); } @@ -391,7 +390,6 @@ impl TransactionV1 { if let PricingHandling::Fixed = price_handling { } else { return Err(InvalidTransactionV1::InvalidPricingMode { - price_handling, price_mode: price_mode.clone(), }); } @@ -400,7 +398,6 @@ impl TransactionV1 { // Currently Reserved isn't implemented and we should // not be accepting transactions with this mode. return Err(InvalidTransactionV1::InvalidPricingMode { - price_handling, price_mode: price_mode.clone(), }); } @@ -1133,7 +1130,6 @@ mod tests { let current_timestamp = reserved_transaction.timestamp(); let expected_error = InvalidTransactionV1::InvalidPricingMode { - price_handling: expected_pricing_handling, price_mode: reserved_mode, }; assert_eq!( @@ -1173,7 +1169,6 @@ mod tests { let current_timestamp = fixed_mode_transaction.timestamp(); let expected_error = InvalidTransactionV1::InvalidPricingMode { - price_handling: PricingHandling::Classic, price_mode: fixed_mode_transaction.pricing_mode().clone(), }; @@ -1210,7 +1205,6 @@ mod tests { let current_timestamp = classic_mode_transaction.timestamp(); let expected_error = InvalidTransactionV1::InvalidPricingMode { - price_handling: PricingHandling::Fixed, price_mode: classic_mode_transaction.pricing_mode().clone(), }; diff --git a/types/src/transaction/transaction_v1/errors_v1.rs b/types/src/transaction/transaction_v1/errors_v1.rs index 0cd19ebfd4..abe1f9d2fc 100644 --- a/types/src/transaction/transaction_v1/errors_v1.rs +++ b/types/src/transaction/transaction_v1/errors_v1.rs @@ -13,8 +13,6 @@ use serde::Serialize; use super::super::TransactionEntryPoint; #[cfg(doc)] use super::TransactionV1; -#[cfg(feature = "std")] -use crate::{chainspec::PricingHandling}; use crate::{ bytesrepr, crypto, CLType, DisplayIter, TimeDiff, Timestamp, U512, PricingMode, @@ -152,8 +150,6 @@ pub enum InvalidTransaction { UnableToCalculateGasLimit, /// Invalid combination of pricing handling and pricing mode. InvalidPricingMode { - /// The price handling as determined by the chainspec. - price_handling: PricingHandling, /// The pricing mode as specified by the transaction. price_mode: PricingMode, }, @@ -278,10 +274,9 @@ impl Display for InvalidTransaction { write!(formatter, "unable to calculate gas limit",) } InvalidTransaction::InvalidPricingMode { - price_handling, price_mode, } => { - write!(formatter, "received a transaction with mode {price_mode} with price handling {price_handling}") + write!(formatter, "received a transaction with an invalid mode {price_mode}") } } } From 0f94e5c84a2a09be4d23ff57ab2a3ed0d50dc887 Mon Sep 17 00:00:00 2001 From: Alexandru Sardan Date: Wed, 27 Mar 2024 13:14:29 +0000 Subject: [PATCH 45/70] Several small fixes Revert effects if hold failed. Set non-zero gas limits for install/upgrade and standard txn. Fix call to `BalanceHoldResult::success`. Add `strike_price` for Reserved pricing mode to track the price at the moment of the reservation. Signed-off-by: Alexandru Sardan --- node/src/components/contract_runtime/types.rs | 4 ++++ resources/local/chainspec.toml.in | 4 ++-- resources/test/sse_data_schema.json | 17 ++++++++++----- storage/src/global_state/state/mod.rs | 2 +- .../src/chainspec/vm_config/system_config.rs | 4 ++-- types/src/transaction/pricing_mode.rs | 21 +++++++++++++++---- types/src/transaction/transaction_v1.rs | 11 ++++++---- 7 files changed, 45 insertions(+), 18 deletions(-) diff --git a/node/src/components/contract_runtime/types.rs b/node/src/components/contract_runtime/types.rs index 86a5ce365b..3af31e5d14 100644 --- a/node/src/components/contract_runtime/types.rs +++ b/node/src/components/contract_runtime/types.rs @@ -160,6 +160,10 @@ impl ExecutionArtifactBuilder { } if let (None, BalanceHoldResult::Failure(err)) = (&self.error_message, hold_result) { self.error_message = Some(format!("{}", err)); + // NOTE: if holding balance fails, we revert any prior effects. + // and only commit effects produced by balance hold (if any). + self.effects = hold_result.effects(); + return Ok(self); } self.with_appended_effects(hold_result.effects()); Ok(self) diff --git a/resources/local/chainspec.toml.in b/resources/local/chainspec.toml.in index 8f45092d4f..4c3f296feb 100644 --- a/resources/local/chainspec.toml.in +++ b/resources/local/chainspec.toml.in @@ -290,8 +290,8 @@ max_topics_per_contract = 128 max_message_size = 1_024 [system_costs] -install_upgrade_gas_limit = 0 -standard_transaction_gas_limit = 0 +install_upgrade_gas_limit = 3_500_000_000 +standard_transaction_gas_limit = 350_000_000 [system_costs.auction_costs] get_era_validators = 10_000 diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index 64a6af4ccb..23a1d64251 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -1700,7 +1700,8 @@ "type": "object", "required": [ "paid_amount", - "receipt" + "receipt", + "strike_price" ], "properties": { "receipt": { @@ -1718,6 +1719,12 @@ "$ref": "#/definitions/U512" } ] + }, + "strike_price": { + "description": "The gas price at the time of reservation.", + "type": "integer", + "format": "uint8", + "minimum": 0.0 } }, "additionalProperties": false @@ -2187,7 +2194,7 @@ "description": "A record of version 1 Transfers performed while executing the deploy.", "type": "array", "items": { - "$ref": "#/definitions/TransferV1Addr" + "$ref": "#/definitions/TransferAddr" } }, "cost": { @@ -2235,7 +2242,7 @@ "description": "A record of Transfers performed while executing the deploy.", "type": "array", "items": { - "$ref": "#/definitions/TransferV1Addr" + "$ref": "#/definitions/TransferAddr" } }, "cost": { @@ -2661,7 +2668,7 @@ "description": "Version 1 transfers performed by the Deploy.", "type": "array", "items": { - "$ref": "#/definitions/TransferV1Addr" + "$ref": "#/definitions/TransferAddr" } }, "from": { @@ -2691,7 +2698,7 @@ }, "additionalProperties": false }, - "TransferV1Addr": { + "TransferAddr": { "description": "Hex-encoded version 1 transfer address.", "type": "string" }, diff --git a/storage/src/global_state/state/mod.rs b/storage/src/global_state/state/mod.rs index 408a026854..a7678ef141 100644 --- a/storage/src/global_state/state/mod.rs +++ b/storage/src/global_state/state/mod.rs @@ -794,8 +794,8 @@ pub trait StateProvider { BalanceHoldResult::success( total_balance, available_balance, - held_amount, request.hold_amount(), + held_amount, effects, ) } diff --git a/types/src/chainspec/vm_config/system_config.rs b/types/src/chainspec/vm_config/system_config.rs index 139d9f0a1c..ffed53d044 100644 --- a/types/src/chainspec/vm_config/system_config.rs +++ b/types/src/chainspec/vm_config/system_config.rs @@ -13,10 +13,10 @@ use crate::{ }; /// Default gas limit of install / upgrade contracts -pub const DEFAULT_INSTALL_UPGRADE_GAS_LIMIT: u32 = 0; // 100_000_000; TODO: reinstate when adding new payment logic +pub const DEFAULT_INSTALL_UPGRADE_GAS_LIMIT: u32 = 3_500_000_000; /// Default gas limit of standard transactions -pub const DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT: u32 = 0; // 100_000_000; TODO: reinstate when adding new payment logic +pub const DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT: u32 = 350_000_000; /// Definition of costs in the system. /// diff --git a/types/src/transaction/pricing_mode.rs b/types/src/transaction/pricing_mode.rs index 9e8ce03523..8ae5b0cc88 100644 --- a/types/src/transaction/pricing_mode.rs +++ b/types/src/transaction/pricing_mode.rs @@ -57,6 +57,8 @@ pub enum PricingMode { receipt: Digest, /// Price paid in the past to reserve space in a future block. paid_amount: U512, + /// The gas price at the time of reservation. + strike_price: u8, }, } @@ -76,6 +78,7 @@ impl PricingMode { 2 => PricingMode::Reserved { receipt: rng.gen(), paid_amount: rng.gen(), + strike_price: rng.gen(), }, _ => unreachable!(), } @@ -99,10 +102,11 @@ impl Display for PricingMode { PricingMode::Reserved { receipt, paid_amount, + strike_price, } => write!( formatter, - "reserved: {} paid_amount: {}", - receipt, paid_amount + "reserved: {} paid_amount: {} strike_price: {}", + receipt, paid_amount, strike_price ), PricingMode::Fixed { gas_price_tolerance, @@ -127,10 +131,12 @@ impl ToBytes for PricingMode { PricingMode::Reserved { receipt, paid_amount, + strike_price, } => { RESERVED_TAG.write_bytes(writer)?; receipt.write_bytes(writer)?; - paid_amount.write_bytes(writer) + paid_amount.write_bytes(writer)?; + strike_price.write_bytes(writer) } PricingMode::Fixed { gas_price_tolerance, @@ -162,7 +168,12 @@ impl ToBytes for PricingMode { PricingMode::Reserved { receipt, paid_amount, - } => receipt.serialized_length() + paid_amount.serialized_length(), + strike_price, + } => { + receipt.serialized_length() + + paid_amount.serialized_length() + + strike_price.serialized_length() + } PricingMode::Fixed { gas_price_tolerance, } => gas_price_tolerance.serialized_length(), @@ -200,10 +211,12 @@ impl FromBytes for PricingMode { RESERVED_TAG => { let (receipt, remainder) = Digest::from_bytes(remainder)?; let (paid_amount, remainder) = U512::from_bytes(remainder)?; + let (strike_price, remainder) = u8::from_bytes(remainder)?; Ok(( PricingMode::Reserved { receipt, paid_amount, + strike_price, }, remainder, )) diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index 56330508d4..2d487db018 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -647,13 +647,16 @@ impl GasLimited for TransactionV1 { }, )? } - PricingMode::Reserved { paid_amount, .. } => { - let actual_price = 1; + PricingMode::Reserved { + paid_amount, + strike_price, + .. + } => { // prepaid, if receipt is legit (future use, not currently implemented) - Gas::from_motes(Motes::new(*paid_amount), actual_price).ok_or( + Gas::from_motes(Motes::new(*paid_amount), *strike_price).ok_or( InvalidTransactionV1::GasPriceConversion { amount: paid_amount.as_u64(), - gas_price: actual_price, + gas_price: *strike_price, }, )? } From 825dbf5e2e4030b20d27a8dddb8d24d0efe48951 Mon Sep 17 00:00:00 2001 From: Alexandru Sardan Date: Wed, 27 Mar 2024 16:26:50 +0000 Subject: [PATCH 46/70] casper-storage: remove lifetime for transfers Signed-off-by: Alexandru Sardan --- node/src/components/storage.rs | 2 +- .../lmdb/indexed_lmdb_block_store.rs | 140 ++++++++---------- .../src/block_store/lmdb/lmdb_block_store.rs | 81 +++++----- .../block_store/lmdb/versioned_databases.rs | 2 +- storage/src/block_store/types/transfers.rs | 30 ++-- 5 files changed, 112 insertions(+), 143 deletions(-) diff --git a/node/src/components/storage.rs b/node/src/components/storage.rs index 572862c26e..5f95ffc7a2 100644 --- a/node/src/components/storage.rs +++ b/node/src/components/storage.rs @@ -126,7 +126,7 @@ pub struct Storage { /// Storage location. root: PathBuf, /// Block store - pub(crate) block_store: IndexedLmdbBlockStore<'static>, + pub(crate) block_store: IndexedLmdbBlockStore, /// Runs of completed blocks known in storage. completed_blocks: DisjointSequences, /// The activation point era of the current protocol version. diff --git a/storage/src/block_store/lmdb/indexed_lmdb_block_store.rs b/storage/src/block_store/lmdb/indexed_lmdb_block_store.rs index 8459c279a8..4cc4c73280 100644 --- a/storage/src/block_store/lmdb/indexed_lmdb_block_store.rs +++ b/storage/src/block_store/lmdb/indexed_lmdb_block_store.rs @@ -28,9 +28,9 @@ use casper_types::{ }; #[derive(DataSize, Debug)] -pub struct IndexedLmdbBlockStore<'s> { +pub struct IndexedLmdbBlockStore { /// Block store - block_store: LmdbBlockStore<'s>, + block_store: LmdbBlockStore, /// A map of block height to block ID. block_height_index: BTreeMap, /// A map of era ID to switch block ID. @@ -39,8 +39,8 @@ pub struct IndexedLmdbBlockStore<'s> { transaction_hash_index: BTreeMap, } -impl<'s> IndexedLmdbBlockStore<'s> { - fn get_reader(&self) -> Result, BlockStoreError> { +impl IndexedLmdbBlockStore { + fn get_reader(&self) -> Result, BlockStoreError> { let txn = self .block_store .env @@ -125,10 +125,10 @@ impl<'s> IndexedLmdbBlockStore<'s> { } pub fn new( - block_store: LmdbBlockStore<'s>, + block_store: LmdbBlockStore, hard_reset_to_start_of_era: Option, protocol_version: ProtocolVersion, - ) -> Result, BlockStoreError> { + ) -> Result { // We now need to restore the block-height index. Log messages allow timing here. info!("indexing block store"); let mut block_height_index = BTreeMap::new(); @@ -336,15 +336,15 @@ fn initialize_execution_result_dbs( info!("execution result databases initialized"); Ok(()) } -pub struct IndexedLmdbBlockStoreRWTransaction<'s, 't> { +pub struct IndexedLmdbBlockStoreRWTransaction<'t> { txn: RwTransaction<'t>, - block_store: &'t LmdbBlockStore<'s>, + block_store: &'t LmdbBlockStore, block_height_index: TempMap<'t, u64, BlockHash>, switch_block_era_id_index: TempMap<'t, EraId, BlockHash>, transaction_hash_index: TempMap<'t, TransactionHash, BlockHashHeightAndEra>, } -impl<'s, 't> IndexedLmdbBlockStoreRWTransaction<'s, 't> { +impl<'t> IndexedLmdbBlockStoreRWTransaction<'t> { /// Check if the block height index can be updated. fn should_update_block_height_index( &self, @@ -419,9 +419,9 @@ impl<'s, 't> IndexedLmdbBlockStoreRWTransaction<'s, 't> { } } -pub struct IndexedLmdbBlockStoreReadTransaction<'s, 't> { +pub struct IndexedLmdbBlockStoreReadTransaction<'t> { txn: RoTransaction<'t>, - block_store: &'t IndexedLmdbBlockStore<'s>, + block_store: &'t IndexedLmdbBlockStore, } enum LmdbBlockStoreIndex { @@ -441,7 +441,7 @@ enum DataType { BlockSignatures, } -impl<'s, 't> IndexedLmdbBlockStoreReadTransaction<'s, 't> { +impl<'t> IndexedLmdbBlockStoreReadTransaction<'t> { fn block_hash_from_index(&self, index: LmdbBlockStoreIndex) -> Option<&BlockHash> { match index { LmdbBlockStoreIndex::BlockHeight(position) => match position { @@ -540,7 +540,7 @@ impl<'s, 't> IndexedLmdbBlockStoreReadTransaction<'s, 't> { } } -impl<'s, 't> BlockStoreTransaction for IndexedLmdbBlockStoreReadTransaction<'s, 't> { +impl<'t> BlockStoreTransaction for IndexedLmdbBlockStoreReadTransaction<'t> { fn commit(self) -> Result<(), BlockStoreError> { Ok(()) } @@ -550,7 +550,7 @@ impl<'s, 't> BlockStoreTransaction for IndexedLmdbBlockStoreReadTransaction<'s, } } -impl<'s, 't> BlockStoreTransaction for IndexedLmdbBlockStoreRWTransaction<'s, 't> { +impl<'t> BlockStoreTransaction for IndexedLmdbBlockStoreRWTransaction<'t> { fn commit(self) -> Result<(), BlockStoreError> { self.txn .commit() @@ -567,9 +567,9 @@ impl<'s, 't> BlockStoreTransaction for IndexedLmdbBlockStoreRWTransaction<'s, 't } } -impl<'s> BlockStoreProvider for IndexedLmdbBlockStore<'s> { - type Reader<'t> = IndexedLmdbBlockStoreReadTransaction<'s, 't> where 's: 't; - type ReaderWriter<'t> = IndexedLmdbBlockStoreRWTransaction<'s, 't> where 's: 't; +impl BlockStoreProvider for IndexedLmdbBlockStore { + type Reader<'t> = IndexedLmdbBlockStoreReadTransaction<'t>; + type ReaderWriter<'t> = IndexedLmdbBlockStoreRWTransaction<'t>; fn checkout_ro(&self) -> Result, BlockStoreError> { self.get_reader() @@ -592,7 +592,7 @@ impl<'s> BlockStoreProvider for IndexedLmdbBlockStore<'s> { } } -impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTransaction<'s, 't> { +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, key: BlockHash) -> Result, BlockStoreError> { self.block_store .block_store @@ -604,7 +604,7 @@ impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTransacti } } -impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTransaction<'s, 't> { +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, key: BlockHash) -> Result, BlockStoreError> { self.block_store .block_store @@ -618,9 +618,7 @@ impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTra } } -impl<'s, 't> DataReader - for IndexedLmdbBlockStoreReadTransaction<'s, 't> -{ +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, key: BlockHash) -> Result, BlockStoreError> { self.block_store .block_store @@ -634,9 +632,7 @@ impl<'s, 't> DataReader } } -impl<'s, 't> DataReader - for IndexedLmdbBlockStoreReadTransaction<'s, 't> -{ +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, key: BlockHash) -> Result, BlockStoreError> { self.block_store .block_store @@ -650,7 +646,7 @@ impl<'s, 't> DataReader } } -impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTransaction<'s, 't> { +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, key: BlockHeight) -> Result, BlockStoreError> { self.read_block_indexed(LmdbBlockStoreIndex::BlockHeight(IndexPosition::Key(key))) } @@ -663,7 +659,7 @@ impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTransac } } -impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTransaction<'s, 't> { +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, key: BlockHeight) -> Result, BlockStoreError> { self.read_block_header_indexed(LmdbBlockStoreIndex::BlockHeight(IndexPosition::Key(key))) } @@ -676,9 +672,7 @@ impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadT } } -impl<'s, 't> DataReader - for IndexedLmdbBlockStoreReadTransaction<'s, 't> -{ +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, key: BlockHeight) -> Result, BlockStoreError> { self.read_approvals_hashes_indexed(LmdbBlockStoreIndex::BlockHeight(IndexPosition::Key( key, @@ -693,9 +687,7 @@ impl<'s, 't> DataReader } } -impl<'s, 't> DataReader - for IndexedLmdbBlockStoreReadTransaction<'s, 't> -{ +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, key: BlockHeight) -> Result, BlockStoreError> { self.read_block_signatures_indexed(LmdbBlockStoreIndex::BlockHeight(IndexPosition::Key( key, @@ -711,7 +703,7 @@ impl<'s, 't> DataReader } /// Retrieves single switch block by era ID by looking it up in the index and returning it. -impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTransaction<'s, 't> { +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, key: EraId) -> Result, BlockStoreError> { self.read_block_indexed(LmdbBlockStoreIndex::SwitchBlockEraId(IndexPosition::Key( key, @@ -728,7 +720,7 @@ impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTransaction<' /// Retrieves single switch block header by era ID by looking it up in the index and returning /// it. -impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTransaction<'s, 't> { +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, key: EraId) -> Result, BlockStoreError> { self.read_block_header_indexed(LmdbBlockStoreIndex::SwitchBlockEraId(IndexPosition::Key( key, @@ -743,7 +735,7 @@ impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTransac } } -impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTransaction<'s, 't> { +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, key: EraId) -> Result, BlockStoreError> { self.read_approvals_hashes_indexed(LmdbBlockStoreIndex::SwitchBlockEraId( IndexPosition::Key(key), @@ -758,7 +750,7 @@ impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTra } } -impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTransaction<'s, 't> { +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, key: EraId) -> Result, BlockStoreError> { self.read_block_signatures_indexed(LmdbBlockStoreIndex::SwitchBlockEraId( IndexPosition::Key(key), @@ -773,7 +765,7 @@ impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTra } } -impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTransaction<'s, 't> { +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, _key: Tip) -> Result, BlockStoreError> { self.read_block_header_indexed(LmdbBlockStoreIndex::BlockHeight(IndexPosition::Tip)) } @@ -786,7 +778,7 @@ impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTransacti } } -impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTransaction<'s, 't> { +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, _key: Tip) -> Result, BlockStoreError> { self.read_block_indexed(LmdbBlockStoreIndex::BlockHeight(IndexPosition::Tip)) } @@ -799,9 +791,7 @@ impl<'s, 't> DataReader for IndexedLmdbBlockStoreReadTransaction<'s, } } -impl<'s, 't> DataReader - for IndexedLmdbBlockStoreReadTransaction<'s, 't> -{ +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, _key: LatestSwitchBlock) -> Result, BlockStoreError> { self.read_block_header_indexed(LmdbBlockStoreIndex::SwitchBlockEraId(IndexPosition::Tip)) } @@ -814,8 +804,8 @@ impl<'s, 't> DataReader } } -impl<'s, 't> DataReader - for IndexedLmdbBlockStoreReadTransaction<'s, 't> +impl<'t> DataReader + for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, key: TransactionHash) -> Result, BlockStoreError> { Ok(self.block_store.transaction_hash_index.get(&key).copied()) @@ -826,9 +816,7 @@ impl<'s, 't> DataReader } } -impl<'s, 't> DataReader - for IndexedLmdbBlockStoreReadTransaction<'s, 't> -{ +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, key: TransactionHash) -> Result, BlockStoreError> { self.block_store .block_store @@ -844,8 +832,8 @@ impl<'s, 't> DataReader } } -impl<'s, 't> DataReader> - for IndexedLmdbBlockStoreReadTransaction<'s, 't> +impl<'t> DataReader> + for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, key: TransactionHash) -> Result>, BlockStoreError> { self.block_store @@ -864,9 +852,7 @@ impl<'s, 't> DataReader> } } -impl<'s, 't> DataReader - for IndexedLmdbBlockStoreReadTransaction<'s, 't> -{ +impl<'t> DataReader for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, key: TransactionHash) -> Result, BlockStoreError> { self.block_store .block_store @@ -884,7 +870,7 @@ impl<'s, 't> DataReader } } -impl<'s, 't> DataReader> for IndexedLmdbBlockStoreReadTransaction<'s, 't> { +impl<'t> DataReader> for IndexedLmdbBlockStoreReadTransaction<'t> { fn read(&self, StateStoreKey(key): StateStoreKey) -> Result>, BlockStoreError> { self.block_store .block_store @@ -898,8 +884,8 @@ impl<'s, 't> DataReader> for IndexedLmdbBlockStoreReadTra } } -impl<'s, 't> DataReader<(DbTableId, Vec), DbRawBytesSpec> - for IndexedLmdbBlockStoreReadTransaction<'s, 't> +impl<'t> DataReader<(DbTableId, Vec), DbRawBytesSpec> + for IndexedLmdbBlockStoreReadTransaction<'t> { fn read( &self, @@ -926,7 +912,7 @@ impl<'s, 't> DataReader<(DbTableId, Vec), DbRawBytesSpec> } } -impl<'s, 't> DataWriter for IndexedLmdbBlockStoreRWTransaction<'s, 't> { +impl<'t> DataWriter for IndexedLmdbBlockStoreRWTransaction<'t> { /// Writes a block to storage. /// /// Returns `Ok(true)` if the block has been successfully written, `Ok(false)` if a part of it @@ -1009,7 +995,7 @@ impl<'s, 't> DataWriter for IndexedLmdbBlockStoreRWTransaction } } -impl<'s, 't> DataWriter for IndexedLmdbBlockStoreRWTransaction<'s, 't> { +impl<'t> DataWriter for IndexedLmdbBlockStoreRWTransaction<'t> { fn write(&mut self, data: &ApprovalsHashes) -> Result { self.block_store.write_approvals_hashes(&mut self.txn, data) } @@ -1020,7 +1006,7 @@ impl<'s, 't> DataWriter for IndexedLmdbBlockStoreRWT } } -impl<'s, 't> DataWriter for IndexedLmdbBlockStoreRWTransaction<'s, 't> { +impl<'t> DataWriter for IndexedLmdbBlockStoreRWTransaction<'t> { fn write(&mut self, data: &BlockSignatures) -> Result { self.block_store .write_finality_signatures(&mut self.txn, data) @@ -1032,7 +1018,7 @@ impl<'s, 't> DataWriter for IndexedLmdbBlockStoreRWT } } -impl<'s, 't> DataWriter for IndexedLmdbBlockStoreRWTransaction<'s, 't> { +impl<'t> DataWriter for IndexedLmdbBlockStoreRWTransaction<'t> { fn write(&mut self, data: &BlockHeader) -> Result { let block_hash = data.block_hash(); let block_height = data.height(); @@ -1071,9 +1057,7 @@ impl<'s, 't> DataWriter for IndexedLmdbBlockStoreRWTrans } } -impl<'s, 't> DataWriter - for IndexedLmdbBlockStoreRWTransaction<'s, 't> -{ +impl<'t> DataWriter for IndexedLmdbBlockStoreRWTransaction<'t> { fn write(&mut self, data: &Transaction) -> Result { self.block_store.write_transaction(&mut self.txn, data) } @@ -1083,8 +1067,8 @@ impl<'s, 't> DataWriter } } -impl<'s, 't> DataWriter - for IndexedLmdbBlockStoreRWTransaction<'s, 't> +impl<'t> DataWriter + for IndexedLmdbBlockStoreRWTransaction<'t> { fn write( &mut self, @@ -1110,8 +1094,8 @@ impl<'s, 't> DataWriter } } -impl<'s, 't> DataWriter - for IndexedLmdbBlockStoreRWTransaction<'s, 't> +impl<'t> DataWriter + for IndexedLmdbBlockStoreRWTransaction<'t> { fn write( &mut self, @@ -1148,7 +1132,7 @@ impl<'s, 't> DataWriter } } -impl<'s, 't> DataWriter for IndexedLmdbBlockStoreRWTransaction<'s, 't> { +impl<'t> DataWriter for IndexedLmdbBlockStoreRWTransaction<'t> { fn write(&mut self, data: &BlockTransfers) -> Result { self.block_store .write_transfers(&mut self.txn, &data.block_hash, &data.transfers) @@ -1160,9 +1144,7 @@ impl<'s, 't> DataWriter for IndexedLmdbBlockStoreRWTr } } -impl<'s, 't> DataWriter, StateStore> - for IndexedLmdbBlockStoreRWTransaction<'s, 't> -{ +impl<'t> DataWriter, StateStore> for IndexedLmdbBlockStoreRWTransaction<'t> { fn write(&mut self, data: &StateStore) -> Result, BlockStoreError> { self.block_store .write_state_store(&mut self.txn, data.key.clone(), &data.value)?; @@ -1174,9 +1156,7 @@ impl<'s, 't> DataWriter, StateStore> } } -impl<'s, 't> DataReader - for IndexedLmdbBlockStoreRWTransaction<'s, 't> -{ +impl<'t> DataReader for IndexedLmdbBlockStoreRWTransaction<'t> { fn read(&self, query: TransactionHash) -> Result, BlockStoreError> { self.block_store .transaction_dbs @@ -1189,7 +1169,7 @@ impl<'s, 't> DataReader } } -impl<'s, 't> DataReader for IndexedLmdbBlockStoreRWTransaction<'s, 't> { +impl<'t> DataReader for IndexedLmdbBlockStoreRWTransaction<'t> { fn read(&self, key: BlockHash) -> Result, BlockStoreError> { self.block_store.get_block_signatures(&self.txn, &key) } @@ -1199,8 +1179,8 @@ impl<'s, 't> DataReader for IndexedLmdbBlockStoreRWT } } -impl<'s, 't> DataReader> - for IndexedLmdbBlockStoreRWTransaction<'s, 't> +impl<'t> DataReader> + for IndexedLmdbBlockStoreRWTransaction<'t> { fn read(&self, query: TransactionHash) -> Result>, BlockStoreError> { self.block_store @@ -1217,7 +1197,7 @@ impl<'s, 't> DataReader> } } -impl<'s, 't> DataReader for IndexedLmdbBlockStoreRWTransaction<'s, 't> { +impl<'t> DataReader for IndexedLmdbBlockStoreRWTransaction<'t> { fn read(&self, key: BlockHash) -> Result, BlockStoreError> { self.block_store.get_single_block(&self.txn, &key) } @@ -1227,9 +1207,7 @@ impl<'s, 't> DataReader for IndexedLmdbBlockStoreRWTransaction } } -impl<'s, 't> DataReader - for IndexedLmdbBlockStoreRWTransaction<'s, 't> -{ +impl<'t> DataReader for IndexedLmdbBlockStoreRWTransaction<'t> { fn read(&self, query: TransactionHash) -> Result, BlockStoreError> { self.block_store .execution_result_dbs @@ -1245,7 +1223,7 @@ impl<'s, 't> DataReader } } -impl<'s, 't> DataReader> for IndexedLmdbBlockStoreRWTransaction<'s, 't> { +impl<'t> DataReader> for IndexedLmdbBlockStoreRWTransaction<'t> { fn read(&self, key: BlockHash) -> Result>, BlockStoreError> { self.block_store.get_transfers(&self.txn, &key) } diff --git a/storage/src/block_store/lmdb/lmdb_block_store.rs b/storage/src/block_store/lmdb/lmdb_block_store.rs index e6fa881865..799ff71dce 100644 --- a/storage/src/block_store/lmdb/lmdb_block_store.rs +++ b/storage/src/block_store/lmdb/lmdb_block_store.rs @@ -52,7 +52,7 @@ const OS_FLAGS: EnvironmentFlags = EnvironmentFlags::WRITE_MAP; const OS_FLAGS: EnvironmentFlags = EnvironmentFlags::empty(); #[derive(DataSize, Debug)] -pub struct LmdbBlockStore<'s> { +pub struct LmdbBlockStore { /// Storage location. root: PathBuf, /// Environment holding LMDB databases. @@ -72,7 +72,7 @@ pub struct LmdbBlockStore<'s> { /// hash for legacy DB. pub(super) execution_result_dbs: VersionedDatabases, /// The transfer databases. - pub(super) transfer_dbs: VersionedDatabases>, + pub(super) transfer_dbs: VersionedDatabases, /// The state storage database. #[data_size(skip)] state_store_db: Database, @@ -81,7 +81,7 @@ pub struct LmdbBlockStore<'s> { VersionedDatabases>, } -impl<'s> LmdbBlockStore<'s> { +impl LmdbBlockStore { pub fn new(root_path: &Path, total_size: usize) -> Result { // Create the environment and databases. let env = new_environment(total_size, root_path)?; @@ -272,10 +272,15 @@ impl<'s> LmdbBlockStore<'s> { &self, txn: &mut RwTransaction, block_hash: &BlockHash, - transfers: &Vec, + transfers: &[Transfer], ) -> Result { self.transfer_dbs - .put(txn, block_hash, &Transfers::from(transfers), true) + .put( + txn, + block_hash, + &Transfers::from(transfers.to_owned()), + true, + ) .map_err(|err| BlockStoreError::InternalStorage(Box::new(err))) } @@ -572,9 +577,9 @@ fn successful_transfers(execution_result: &ExecutionResult) -> Vec { all_transfers } -impl<'s> BlockStoreProvider for LmdbBlockStore<'s> { - type Reader<'t> = LmdbBlockStoreTransaction<'s, 't, RoTransaction<'t>> where 's: 't; - type ReaderWriter<'t> = LmdbBlockStoreTransaction<'s, 't, RwTransaction<'t>> where 's: 't; +impl BlockStoreProvider for LmdbBlockStore { + type Reader<'t> = LmdbBlockStoreTransaction<'t, RoTransaction<'t>>; + type ReaderWriter<'t> = LmdbBlockStoreTransaction<'t, RwTransaction<'t>>; fn checkout_ro(&self) -> Result, BlockStoreError> { let txn = self @@ -600,15 +605,15 @@ impl<'s> BlockStoreProvider for LmdbBlockStore<'s> { } } -pub struct LmdbBlockStoreTransaction<'s, 't, T> +pub struct LmdbBlockStoreTransaction<'t, T> where T: LmdbTransaction, { txn: T, - block_store: &'t LmdbBlockStore<'s>, + block_store: &'t LmdbBlockStore, } -impl<'s, 't, T> BlockStoreTransaction for LmdbBlockStoreTransaction<'s, 't, T> +impl<'t, T> BlockStoreTransaction for LmdbBlockStoreTransaction<'t, T> where T: LmdbTransaction, { @@ -623,7 +628,7 @@ where } } -impl<'s, 't, T> DataReader for LmdbBlockStoreTransaction<'s, 't, T> +impl<'t, T> DataReader for LmdbBlockStoreTransaction<'t, T> where T: LmdbTransaction, { @@ -636,7 +641,7 @@ where } } -impl<'s, 't, T> DataReader for LmdbBlockStoreTransaction<'s, 't, T> +impl<'t, T> DataReader for LmdbBlockStoreTransaction<'t, T> where T: LmdbTransaction, { @@ -649,7 +654,7 @@ where } } -impl<'s, 't, T> DataReader for LmdbBlockStoreTransaction<'s, 't, T> +impl<'t, T> DataReader for LmdbBlockStoreTransaction<'t, T> where T: LmdbTransaction, { @@ -662,7 +667,7 @@ where } } -impl<'s, 't, T> DataReader for LmdbBlockStoreTransaction<'s, 't, T> +impl<'t, T> DataReader for LmdbBlockStoreTransaction<'t, T> where T: LmdbTransaction, { @@ -675,7 +680,7 @@ where } } -impl<'s, 't, T> DataReader for LmdbBlockStoreTransaction<'s, 't, T> +impl<'t, T> DataReader for LmdbBlockStoreTransaction<'t, T> where T: LmdbTransaction, { @@ -691,8 +696,7 @@ where } } -impl<'s, 't, T> DataReader> - for LmdbBlockStoreTransaction<'s, 't, T> +impl<'t, T> DataReader> for LmdbBlockStoreTransaction<'t, T> where T: LmdbTransaction, { @@ -711,8 +715,7 @@ where } } -impl<'s, 't, T> DataReader - for LmdbBlockStoreTransaction<'s, 't, T> +impl<'t, T> DataReader for LmdbBlockStoreTransaction<'t, T> where T: LmdbTransaction, { @@ -731,7 +734,7 @@ where } } -impl<'s, 't, T> DataReader> for LmdbBlockStoreTransaction<'s, 't, T> +impl<'t, T> DataReader> for LmdbBlockStoreTransaction<'t, T> where T: LmdbTransaction, { @@ -744,7 +747,7 @@ where } } -impl<'s, 't, T, K> DataReader> for LmdbBlockStoreTransaction<'s, 't, T> +impl<'t, T, K> DataReader> for LmdbBlockStoreTransaction<'t, T> where K: AsRef<[u8]>, T: LmdbTransaction, @@ -758,7 +761,7 @@ where } } -impl<'s, 't> DataWriter for LmdbBlockStoreTransaction<'s, 't, RwTransaction<'t>> { +impl<'t> DataWriter for LmdbBlockStoreTransaction<'t, RwTransaction<'t>> { /// Writes a block to storage. fn write(&mut self, data: &Block) -> Result { self.block_store.write_block(&mut self.txn, data) @@ -776,8 +779,8 @@ impl<'s, 't> DataWriter for LmdbBlockStoreTransaction<'s, 't, } } -impl<'s, 't> DataWriter - for LmdbBlockStoreTransaction<'s, 't, RwTransaction<'t>> +impl<'t> DataWriter + for LmdbBlockStoreTransaction<'t, RwTransaction<'t>> { fn write(&mut self, data: &ApprovalsHashes) -> Result { self.block_store.write_approvals_hashes(&mut self.txn, data) @@ -789,8 +792,8 @@ impl<'s, 't> DataWriter } } -impl<'s, 't> DataWriter - for LmdbBlockStoreTransaction<'s, 't, RwTransaction<'t>> +impl<'t> DataWriter + for LmdbBlockStoreTransaction<'t, RwTransaction<'t>> { fn write(&mut self, data: &BlockSignatures) -> Result { self.block_store @@ -803,9 +806,7 @@ impl<'s, 't> DataWriter } } -impl<'s, 't> DataWriter - for LmdbBlockStoreTransaction<'s, 't, RwTransaction<'t>> -{ +impl<'t> DataWriter for LmdbBlockStoreTransaction<'t, RwTransaction<'t>> { fn write(&mut self, data: &BlockHeader) -> Result { self.block_store.write_block_header(&mut self.txn, data) } @@ -815,8 +816,8 @@ impl<'s, 't> DataWriter } } -impl<'s, 't> DataWriter - for LmdbBlockStoreTransaction<'s, 't, RwTransaction<'t>> +impl<'t> DataWriter + for LmdbBlockStoreTransaction<'t, RwTransaction<'t>> { fn write(&mut self, data: &Transaction) -> Result { self.block_store.write_transaction(&mut self.txn, data) @@ -827,8 +828,8 @@ impl<'s, 't> DataWriter } } -impl<'s, 't> DataWriter - for LmdbBlockStoreTransaction<'s, 't, RwTransaction<'t>> +impl<'t> DataWriter + for LmdbBlockStoreTransaction<'t, RwTransaction<'t>> { fn write(&mut self, data: &BlockTransfers) -> Result { self.block_store @@ -841,8 +842,8 @@ impl<'s, 't> DataWriter } } -impl<'s, 't> DataWriter, StateStore> - for LmdbBlockStoreTransaction<'s, 't, RwTransaction<'t>> +impl<'t> DataWriter, StateStore> + for LmdbBlockStoreTransaction<'t, RwTransaction<'t>> { fn write(&mut self, data: &StateStore) -> Result, BlockStoreError> { self.block_store @@ -855,8 +856,8 @@ impl<'s, 't> DataWriter, StateStore> } } -impl<'s, 't> DataWriter - for LmdbBlockStoreTransaction<'s, 't, RwTransaction<'t>> +impl<'t> DataWriter + for LmdbBlockStoreTransaction<'t, RwTransaction<'t>> { fn write( &mut self, @@ -882,8 +883,8 @@ impl<'s, 't> DataWriter } } -impl<'s, 't> DataWriter - for LmdbBlockStoreTransaction<'s, 't, RwTransaction<'t>> +impl<'t> DataWriter + for LmdbBlockStoreTransaction<'t, RwTransaction<'t>> { fn write( &mut self, diff --git a/storage/src/block_store/lmdb/versioned_databases.rs b/storage/src/block_store/lmdb/versioned_databases.rs index 6f75be6cf9..b4d5fa2866 100644 --- a/storage/src/block_store/lmdb/versioned_databases.rs +++ b/storage/src/block_store/lmdb/versioned_databases.rs @@ -89,7 +89,7 @@ impl VersionedValue for BlockSignatures { type Legacy = BlockSignaturesV1; } -impl<'a> VersionedValue for Transfers<'a> { +impl VersionedValue for Transfers { type Legacy = Vec; } diff --git a/storage/src/block_store/types/transfers.rs b/storage/src/block_store/types/transfers.rs index 65d12fefe9..159146fa68 100644 --- a/storage/src/block_store/types/transfers.rs +++ b/storage/src/block_store/types/transfers.rs @@ -1,5 +1,3 @@ -use std::borrow::Cow; - use serde::{Deserialize, Serialize}; use casper_types::{ @@ -12,35 +10,27 @@ use casper_types::{ /// It exists to allow the `impl From>` to be written, making the type suitable for /// use as a parameter in a `VersionedDatabases`. #[derive(Clone, Serialize, Deserialize, Debug, Default, PartialEq, Eq)] -pub(in crate::block_store) struct Transfers<'a>(Cow<'a, Vec>); +pub(in crate::block_store) struct Transfers(Vec); -impl<'a> Transfers<'a> { +impl Transfers { pub(in crate::block_store) fn into_owned(self) -> Vec { - self.0.into_owned() + self.0 } } -impl<'a> From> for Transfers<'a> { +impl From> for Transfers { fn from(v1_transfers: Vec) -> Self { - Transfers(Cow::Owned( - v1_transfers.into_iter().map(Transfer::V1).collect(), - )) + Transfers(v1_transfers.into_iter().map(Transfer::V1).collect()) } } -impl<'a> From> for Transfers<'a> { +impl From> for Transfers { fn from(transfers: Vec) -> Self { - Transfers(Cow::Owned(transfers)) - } -} - -impl<'a> From<&'a Vec> for Transfers<'a> { - fn from(transfers: &'a Vec) -> Self { - Transfers(Cow::Borrowed(transfers)) + Transfers(transfers) } } -impl<'a> ToBytes for Transfers<'a> { +impl ToBytes for Transfers { fn to_bytes(&self) -> Result, bytesrepr::Error> { self.0.to_bytes() } @@ -54,9 +44,9 @@ impl<'a> ToBytes for Transfers<'a> { } } -impl<'a> FromBytes for Transfers<'a> { +impl FromBytes for Transfers { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { Vec::::from_bytes(bytes) - .map(|(transfers, remainder)| (Transfers(Cow::Owned(transfers)), remainder)) + .map(|(transfers, remainder)| (Transfers(transfers), remainder)) } } From 2b051b7e26fefc04591eb13b32d1f0ae8813c459 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Wed, 27 Mar 2024 10:07:19 -0700 Subject: [PATCH 47/70] tweaking reserved check --- types/src/transaction/transaction_v1.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index b49bb815c0..e604000b6d 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -31,14 +31,13 @@ use super::{ }; #[cfg(any(feature = "std", test))] use super::{GasLimited, InitiatorAddrAndSecretKey}; -#[cfg(any(all(feature = "std", feature = "testing"), test))] -use crate::{testing::TestRng, Chainspec, - chainspec::PricingHandling}; use crate::{ bytesrepr::{self, FromBytes, ToBytes}, - crypto, Digest, DisplayIter, RuntimeArgs, SecretKey, TimeDiff, Timestamp, - TransactionRuntime, TransactionSessionKind, + crypto, Digest, DisplayIter, RuntimeArgs, SecretKey, TimeDiff, Timestamp, TransactionRuntime, + TransactionSessionKind, }; +#[cfg(any(all(feature = "std", feature = "testing"), test))] +use crate::{chainspec::PricingHandling, testing::TestRng, Chainspec}; #[cfg(any(feature = "std", test))] use crate::{Gas, Motes, SystemConfig, TransactionConfig, U512}; pub use errors_v1::{ @@ -395,11 +394,13 @@ impl TransactionV1 { } } PricingMode::Reserved { .. } => { - // Currently Reserved isn't implemented and we should - // not be accepting transactions with this mode. - return Err(InvalidTransactionV1::InvalidPricingMode { - price_mode: price_mode.clone(), - }); + if !chainspec.core_config.allow_reservations { + // Currently Reserved isn't implemented and we should + // not be accepting transactions with this mode. + return Err(InvalidTransactionV1::InvalidPricingMode { + price_mode: price_mode.clone(), + }); + } } } @@ -1115,6 +1116,7 @@ mod tests { let reserved_mode = PricingMode::Reserved { receipt: Default::default(), paid_amount: Default::default(), + strike_price: Default::default(), }; let reserved_transaction = TransactionV1Builder::new_random(rng) @@ -1129,8 +1131,6 @@ mod tests { ret }; - let expected_pricing_handling = chainspec.core_config.pricing_handling; - let current_timestamp = reserved_transaction.timestamp(); let expected_error = InvalidTransactionV1::InvalidPricingMode { price_mode: reserved_mode, From 46c3bc760569bbcc8fd907d9a7abe43f36ac7794 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Wed, 27 Mar 2024 10:43:46 -0700 Subject: [PATCH 48/70] linting --- .../components/transaction_acceptor/tests.rs | 21 ++++++++++++++++--- types/src/transaction/transaction_v1.rs | 4 ++-- .../transaction/transaction_v1/errors_v1.rs | 14 ++++++------- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/node/src/components/transaction_acceptor/tests.rs b/node/src/components/transaction_acceptor/tests.rs index 9a593e90d1..a3acea9b30 100644 --- a/node/src/components/transaction_acceptor/tests.rs +++ b/node/src/components/transaction_acceptor/tests.rs @@ -25,7 +25,17 @@ use casper_storage::{ data_access_layer::{AddressableEntityResult, BalanceIdentifier, BalanceResult, QueryResult}, tracking_copy::TrackingCopyError, }; -use casper_types::{account::{Account, AccountHash, ActionThresholds, AssociatedKeys, Weight}, addressable_entity::{AddressableEntity, NamedKeys}, bytesrepr::Bytes, global_state::TrieMerkleProof, testing::TestRng, Block, BlockV2, CLValue, Chainspec, ChainspecRawBytes, Contract, Deploy, EraId, HashAddr, InvalidDeploy, InvalidTransaction, InvalidTransactionV1, Package, ProtocolVersion, PublicKey, SecretKey, StoredValue, TestBlockBuilder, TimeDiff, Timestamp, Transaction, TransactionSessionKind, TransactionV1, TransactionV1Builder, URef, U512, PricingMode}; +use casper_types::{ + account::{Account, AccountHash, ActionThresholds, AssociatedKeys, Weight}, + addressable_entity::{AddressableEntity, NamedKeys}, + bytesrepr::Bytes, + global_state::TrieMerkleProof, + testing::TestRng, + Block, BlockV2, CLValue, Chainspec, ChainspecRawBytes, Contract, Deploy, EraId, HashAddr, + InvalidDeploy, InvalidTransaction, InvalidTransactionV1, Package, PricingMode, ProtocolVersion, + PublicKey, SecretKey, StoredValue, TestBlockBuilder, TimeDiff, Timestamp, Transaction, + TransactionSessionKind, TransactionV1, TransactionV1Builder, URef, U512, +}; use super::*; use crate::{ @@ -550,7 +560,7 @@ impl TestScenario { .with_pricing_mode(PricingMode::Classic { payment_amount: 10000u64, gas_price: 1u8, - standard_payment: true + standard_payment: true, }) .with_chain_name("casper-example") .build() @@ -2316,5 +2326,10 @@ async fn should_accept_transaction_v1_signed_by_admin_from_client() { async fn should_reject_transaction_v1_with_invalid_pricing_mode() { let test_scenario = TestScenario::InvalidPricingModeForTransactionV1; let result = run_transaction_acceptor(test_scenario).await; - assert!(matches!(result, Err(super::Error::InvalidTransaction(InvalidTransaction::V1(InvalidTransactionV1::InvalidPricingMode { .. }))))) + assert!(matches!( + result, + Err(super::Error::InvalidTransaction(InvalidTransaction::V1( + InvalidTransactionV1::InvalidPricingMode { .. } + ))) + )) } diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index e604000b6d..68497a19f0 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -360,7 +360,7 @@ impl TransactionV1 { let chain_name = chainspec.network_config.name.clone(); let header = self.header(); - if header.chain_name() != &chain_name { + if header.chain_name() != chain_name { debug!( transaction_hash = %self.hash(), transaction_header = %header, @@ -368,7 +368,7 @@ impl TransactionV1 { "invalid chain identifier" ); return Err(InvalidTransactionV1::InvalidChainName { - expected: chain_name.to_string(), + expected: chain_name, got: header.chain_name().to_string(), }); } diff --git a/types/src/transaction/transaction_v1/errors_v1.rs b/types/src/transaction/transaction_v1/errors_v1.rs index abe1f9d2fc..e24ceaee50 100644 --- a/types/src/transaction/transaction_v1/errors_v1.rs +++ b/types/src/transaction/transaction_v1/errors_v1.rs @@ -13,10 +13,7 @@ use serde::Serialize; use super::super::TransactionEntryPoint; #[cfg(doc)] use super::TransactionV1; -use crate::{ - bytesrepr, crypto, CLType, DisplayIter, TimeDiff, - Timestamp, U512, PricingMode, -}; +use crate::{bytesrepr, crypto, CLType, DisplayIter, PricingMode, TimeDiff, Timestamp, U512}; /// Returned when a [`TransactionV1`] fails validation. #[derive(Clone, Eq, PartialEq, Debug)] @@ -273,10 +270,11 @@ impl Display for InvalidTransaction { InvalidTransaction::UnableToCalculateGasLimit => { write!(formatter, "unable to calculate gas limit",) } - InvalidTransaction::InvalidPricingMode { - price_mode, - } => { - write!(formatter, "received a transaction with an invalid mode {price_mode}") + InvalidTransaction::InvalidPricingMode { price_mode } => { + write!( + formatter, + "received a transaction with an invalid mode {price_mode}" + ) } } } From 8533c8a08e13b5f641325856217ca13890199fc2 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Wed, 27 Mar 2024 17:02:47 -0700 Subject: [PATCH 49/70] deoupled limit and cost calcs, made deploy / transactionV1 config compliance consistent --- .../components/contract_runtime/operations.rs | 24 +- node/src/components/transaction_acceptor.rs | 5 +- .../transaction/transaction_footprint.rs | 6 +- resources/local/chainspec.toml.in | 2 - resources/production/chainspec.toml | 2 - .../src/data_access_layer/handle_payment.rs | 18 +- storage/src/system/handle_payment.rs | 10 +- .../handle_payment/handle_payment_native.rs | 1 - storage/src/system/handle_payment/internal.rs | 92 +++-- types/src/chainspec.rs | 18 + types/src/chainspec/transaction_config.rs | 9 - types/src/gas.rs | 9 + types/src/transaction.rs | 45 +-- types/src/transaction/deploy.rs | 313 +++++++----------- types/src/transaction/deploy/deploy_header.rs | 19 +- types/src/transaction/deploy/error.rs | 10 +- types/src/transaction/transaction_v1.rs | 49 +-- .../transaction/transaction_v1/errors_v1.rs | 6 + 18 files changed, 309 insertions(+), 329 deletions(-) diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 8c84cdf5a5..bf07a108e6 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -100,9 +100,7 @@ pub fn execute_finalized_block( .iter() .map(Transaction::fetch_id) .collect_vec(); - let system_costs = chainspec.system_costs_config; let insufficient_balance_handling = InsufficientBalanceHandling::HoldRemaining; - let gas_price = Some(current_gas_price); for transaction in executable_block.transactions { let mut artifact_builder = ExecutionArtifactBuilder::new(&transaction); @@ -133,10 +131,10 @@ pub fn execute_finalized_block( // post processing // NOTE: this is the allowed computation limit (gas limit) - let gas_limit = match transaction.gas_limit(&system_costs, None) { + let gas_limit = match transaction.gas_limit(chainspec) { Ok(gas) => gas, Err(ite) => { - debug!(%ite, "invalid transaction (gas limit)"); + debug!(%transaction_hash, %ite, "invalid transaction (gas limit)"); artifact_builder.with_invalid_transaction(&ite); artifacts.push(artifact_builder.build()); continue; @@ -145,10 +143,10 @@ pub fn execute_finalized_block( artifact_builder.with_gas_limit(gas_limit); // NOTE: this is the actual adjusted cost that we charge for (gas limit * gas price) - let cost = match transaction.gas_limit(&system_costs, gas_price) { - Ok(gas) => gas.value(), + let cost = match transaction.gas_cost(chainspec, current_gas_price) { + Ok(motes) => motes.value(), Err(ite) => { - debug!(%ite, "invalid transaction (cost)"); + debug!(%transaction_hash, "invalid transaction (motes conversion)"); artifact_builder.with_invalid_transaction(&ite); artifacts.push(artifact_builder.build()); continue; @@ -348,10 +346,10 @@ pub fn execute_finalized_block( protocol_version, transaction_hash, HandlePaymentMode::finalize( - gas_limit, - gas_price, + gas_limit.value(), + current_gas_price, cost, - consumed, + consumed.value(), balance_identifier, BalanceIdentifier::Public(*(proposer.clone())), holds_epoch, @@ -365,7 +363,7 @@ pub fn execute_finalized_block( FeeHandling::Accumulate => { // in this mode, consumed gas is accumulated into a single purse for later // distribution - let consumed = Gas::new(artifact_builder.consumed()); + let consumed = Some(artifact_builder.consumed()); let handle_payment_request = HandlePaymentRequest::new( native_runtime_config.clone(), state_root_hash, @@ -373,7 +371,7 @@ pub fn execute_finalized_block( transaction_hash, HandlePaymentMode::distribute_accumulated( BalanceIdentifier::Accumulate, - Some(consumed), + consumed, ), ); let handle_payment_result = scratch_state.handle_payment(handle_payment_request); @@ -736,7 +734,7 @@ where let block_time = block_header .timestamp() .saturating_add(chainspec.core_config.minimum_block_time); - let gas_limit = match transaction.gas_limit(&chainspec.system_costs_config, None) { + let gas_limit = match transaction.gas_limit(chainspec) { Ok(gas_limit) => gas_limit, Err(_) => { return SpeculativeExecutionResult::invalid_gas_limit(transaction); diff --git a/node/src/components/transaction_acceptor.rs b/node/src/components/transaction_acceptor.rs index 8f5a7c59fc..3f4db1042d 100644 --- a/node/src/components/transaction_acceptor.rs +++ b/node/src/components/transaction_acceptor.rs @@ -115,10 +115,7 @@ impl TransactionAcceptor { let is_config_compliant = match &event_metadata.transaction { Transaction::Deploy(deploy) => deploy .is_config_compliant( - &self.chainspec.network_config.name, - &self.chainspec.system_costs_config, - &self.chainspec.transaction_config, - self.chainspec.core_config.max_associated_keys, + &self.chainspec, self.acceptor_config.timestamp_leeway, event_metadata.verification_start_timestamp, ) diff --git a/node/src/types/transaction/transaction_footprint.rs b/node/src/types/transaction/transaction_footprint.rs index 5c0b4b5765..a7e5bfde4b 100644 --- a/node/src/types/transaction/transaction_footprint.rs +++ b/node/src/types/transaction/transaction_footprint.rs @@ -35,12 +35,8 @@ impl TransactionFootprint { chainspec: &Chainspec, transaction: &Transaction, ) -> Result { - let cost_table = &chainspec.system_costs_config; - // IMPORTANT: block inclusion is always calculated based upon gas price multiple = 1 - // Do not confuse actual cost with retail cost. - let gas_price: Option = None; let gas_price_tolerance = transaction.gas_price_tolerance()?; - let gas_limit = transaction.gas_limit(cost_table, gas_price)?; + let gas_limit = transaction.gas_limit(chainspec)?; let category = transaction.category(); let transaction_hash = transaction.hash(); let body_hash = transaction.body_hash(); diff --git a/resources/local/chainspec.toml.in b/resources/local/chainspec.toml.in index 4c3f296feb..1b89866bdb 100644 --- a/resources/local/chainspec.toml.in +++ b/resources/local/chainspec.toml.in @@ -150,8 +150,6 @@ block_max_approval_count = 2600 max_block_size = 10_485_760 # The upper limit of total gas of all transactions in a block. block_gas_limit = 10_000_000_000_000 -# Chainspec configured cost for native transfers. -native_transfer_cost = 2_500_000_000 # The minimum amount in motes for a valid native transfer. native_transfer_minimum_motes = 2_500_000_000 # The maximum value to which `transaction_acceptor.timestamp_leeway` can be set in the config.toml file. diff --git a/resources/production/chainspec.toml b/resources/production/chainspec.toml index 264d832805..426ae281d7 100644 --- a/resources/production/chainspec.toml +++ b/resources/production/chainspec.toml @@ -159,8 +159,6 @@ block_max_approval_count = 2600 max_block_size = 10_485_760 # The upper limit of total gas of all transactions in a block. block_gas_limit = 4_000_000_000_000 -# Chainspec configured cost for native transfers. -native_transfer_cost = 2_500_000_000 # The minimum amount in motes for a valid native transfer. native_transfer_minimum_motes = 2_500_000_000 # The maximum value to which `transaction_acceptor.timestamp_leeway` can be set in the config.toml file. diff --git a/storage/src/data_access_layer/handle_payment.rs b/storage/src/data_access_layer/handle_payment.rs index ca42c2cb58..a8dff86915 100644 --- a/storage/src/data_access_layer/handle_payment.rs +++ b/storage/src/data_access_layer/handle_payment.rs @@ -2,22 +2,22 @@ use crate::{ data_access_layer::BalanceIdentifier, system::runtime_native::Config as NativeRuntimeConfig, tracking_copy::TrackingCopyError, }; -use casper_types::{execution::Effects, Digest, Gas, ProtocolVersion, TransactionHash, U512}; +use casper_types::{execution::Effects, Digest, ProtocolVersion, TransactionHash, U512}; #[derive(Debug, Clone, PartialEq, Eq)] pub enum HandlePaymentMode { Finalize { - limit: Gas, - gas_price: Option, + limit: U512, + gas_price: u8, cost: U512, - consumed: Gas, + consumed: U512, source: Box, target: Box, holds_epoch: Option, }, Distribute { source: BalanceIdentifier, - amount: Option, + amount: Option, }, Burn { source: BalanceIdentifier, @@ -27,10 +27,10 @@ pub enum HandlePaymentMode { impl HandlePaymentMode { pub fn finalize( - limit: Gas, - gas_price: Option, + limit: U512, + gas_price: u8, cost: U512, - consumed: Gas, + consumed: U512, source: BalanceIdentifier, target: BalanceIdentifier, holds_epoch: Option, @@ -50,7 +50,7 @@ impl HandlePaymentMode { /// much? If amount is None or greater than the available balance, the full available /// balance will be distributed. If amount is less than available balance, only that much /// will be distributed leaving a remaining balance. - pub fn distribute_accumulated(source: BalanceIdentifier, amount: Option) -> Self { + pub fn distribute_accumulated(source: BalanceIdentifier, amount: Option) -> Self { HandlePaymentMode::Distribute { source, amount } } diff --git a/storage/src/system/handle_payment.rs b/storage/src/system/handle_payment.rs index 0d672f4551..784b405f81 100644 --- a/storage/src/system/handle_payment.rs +++ b/storage/src/system/handle_payment.rs @@ -4,7 +4,7 @@ pub mod mint_provider; pub mod runtime_provider; pub mod storage_provider; -use casper_types::{system::handle_payment::Error, AccessRights, Gas, URef, U512}; +use casper_types::{system::handle_payment::Error, AccessRights, URef, U512}; use crate::system::handle_payment::{ mint_provider::MintProvider, runtime_provider::RuntimeProvider, @@ -38,10 +38,10 @@ pub trait HandlePayment: MintProvider + RuntimeProvider + StorageProvider + Size #[allow(clippy::too_many_arguments)] fn finalize_payment( &mut self, - limit: Gas, - gas_price: Option, + limit: U512, + gas_price: u8, cost: U512, - consumed: Gas, + consumed: U512, source_purse: URef, target_purse: URef, holds_epoch: Option, @@ -62,7 +62,7 @@ pub trait HandlePayment: MintProvider + RuntimeProvider + StorageProvider + Size fn distribute_accumulated_fees( &mut self, source_uref: URef, - amount: Option, + amount: Option, ) -> Result<(), Error> { internal::distribute_accumulated_fees(self, source_uref, amount) } diff --git a/storage/src/system/handle_payment/handle_payment_native.rs b/storage/src/system/handle_payment/handle_payment_native.rs index 4ded1aa4a9..a9b0491809 100644 --- a/storage/src/system/handle_payment/handle_payment_native.rs +++ b/storage/src/system/handle_payment/handle_payment_native.rs @@ -129,7 +129,6 @@ where match ::reduce_total_supply(self, amount) { Ok(ret) => Ok(ret), Err(err) => { - println!("{}", err); error!("{}", err); Err(Error::ReduceTotalSupply) } diff --git a/storage/src/system/handle_payment/internal.rs b/storage/src/system/handle_payment/internal.rs index 5f98460a1a..d12147613d 100644 --- a/storage/src/system/handle_payment/internal.rs +++ b/storage/src/system/handle_payment/internal.rs @@ -1,6 +1,6 @@ use casper_types::{ system::handle_payment::{Error, PAYMENT_PURSE_KEY, REFUND_PURSE_KEY}, - FeeHandling, Gas, Key, Phase, PublicKey, RefundHandling, URef, U512, + FeeHandling, Key, Phase, PublicKey, RefundHandling, URef, U512, }; use num::{CheckedMul, One}; use num_rational::Ratio; @@ -50,10 +50,10 @@ pub fn get_refund_purse( /// /// Any dust amounts are added to the fee. fn calculate_overpayment_and_fee( - limit: Gas, - gas_price: Option, + limit: U512, + gas_price: u8, cost: U512, - consumed: Gas, + consumed: U512, available_balance: U512, refund_handling: RefundHandling, ) -> Result<(U512, U512), Error> { @@ -97,11 +97,10 @@ fn calculate_overpayment_and_fee( return Ok((U512::zero(), cost)); } let unspent = limit.saturating_sub(consumed); - if unspent == Gas::zero() { + if unspent == U512::zero() { return Ok((U512::zero(), cost)); } - let gas_price = gas_price.unwrap_or(1); - let base_refund = unspent.value() * gas_price; + let base_refund = unspent * gas_price; let refund_ratio = match refund_handling { RefundHandling::Refund { refund_ratio } | RefundHandling::Burn { refund_ratio } => { debug_assert!( @@ -135,10 +134,10 @@ fn calculate_overpayment_and_fee( #[allow(clippy::too_many_arguments)] pub fn finalize_payment( provider: &mut P, - limit: Gas, - gas_price: Option, + limit: U512, + gas_price: u8, cost: U512, - consumed: Gas, + consumed: U512, source_purse: URef, target_purse: URef, holds_epoch: Option, @@ -238,10 +237,7 @@ pub fn burn( Some(balance) => balance, None => return Err(Error::PaymentPurseBalanceNotFound), }; - let burn_amount = match amount { - Some(amount) => amount, - None => total_balance, - }; + let burn_amount = amount.unwrap_or(total_balance); if burn_amount.is_zero() { // nothing to burn == noop return Ok(()); @@ -261,7 +257,7 @@ pub fn burn( pub fn distribute_accumulated_fees

( provider: &mut P, source_uref: URef, - amount: Option, + amount: Option, ) -> Result<(), Error> where P: RuntimeProvider + MintProvider, @@ -279,7 +275,7 @@ where let reward_recipients = U512::from(administrative_accounts.len()); let distribute_amount = match amount { - Some(amount) => amount.value(), + Some(amount) => amount, None => provider .available_balance(source_uref, None)? .unwrap_or_default(), @@ -329,10 +325,10 @@ mod tests { #[test] fn should_handle_straight_percentages() { - let limit = Gas::new(100u64); - let gas_price = Some(1); - let cost = limit.value(); - let consumed = Gas::from(50u64); + let limit = U512::from(100u64); + let gas_price = 1; + let cost = limit; + let consumed = U512::from(50u64); let available = U512::from(1000u64); let denom = 100; @@ -344,23 +340,23 @@ mod tests { ) .unwrap(); - let unspent = limit.saturating_sub(consumed).value().as_u64(); + let unspent = limit.saturating_sub(consumed).as_u64(); let expected = Ratio::from(unspent) .checked_mul(&refund_ratio) .ok_or(Error::ArithmeticOverflow) .expect("should math") .to_integer(); assert_eq!(expected, overpay.as_u64(), "overpay"); - let expected_fee = limit.value().as_u64() - expected; + let expected_fee = limit.as_u64() - expected; assert_eq!(expected_fee, fee.as_u64(), "fee"); } } fn test_handle_payment(refund_handling: RefundHandling) { - let limit = Gas::new(6u64); - let gas_price = Some(1); - let cost = limit.value(); - let consumed = Gas::from(3u64); + let limit = U512::from(6u64); + let gas_price = 1; + let cost = limit; + let consumed = U512::from(3u64); let available = U512::from(10u64); let (overpay, fee) = calculate_overpayment_and_fee( limit, @@ -373,18 +369,18 @@ mod tests { .unwrap(); let unspent = limit.saturating_sub(consumed); - let expected = unspent.value(); + let expected = unspent; assert_eq!(expected, overpay, "{:?}", refund_handling); - let expected_fee = consumed.value(); + let expected_fee = consumed; assert_eq!(expected_fee, fee, "fee"); } #[test] fn should_roll_over_dust() { - let limit = Gas::new(6u64); - let gas_price = Some(1); - let cost = limit.value(); - let consumed = Gas::from(3u64); + let limit = U512::from(6u64); + let gas_price = 1; + let cost = limit; + let consumed = U512::from(3u64); let available = U512::from(10u64); for percentage in 0..=100 { @@ -406,10 +402,10 @@ mod tests { #[test] fn should_take_all_of_insufficient_balance() { - let limit = Gas::new(6u64); - let gas_price = Some(1); - let cost = limit.value(); - let consumed = Gas::from(3u64); + let limit = U512::from(6u64); + let gas_price = 1; + let cost = limit; + let consumed = U512::from(3u64); let available = U512::from(5u64); let (overpay, fee) = calculate_overpayment_and_fee( @@ -431,15 +427,15 @@ mod tests { #[test] fn should_handle_non_1_gas_price() { - let limit = Gas::new(6u64); + let limit = U512::from(6u64); let gas_price = 2; - let cost = limit.value() * gas_price; - let consumed = Gas::from(3u64); + let cost = limit * gas_price; + let consumed = U512::from(3u64); let available = U512::from(12u64); let (overpay, fee) = calculate_overpayment_and_fee( limit, - Some(gas_price), + gas_price, cost, consumed, available, @@ -450,24 +446,24 @@ mod tests { .unwrap(); let unspent = limit.saturating_sub(consumed); - let expected = unspent.value() * gas_price; + let expected = unspent * gas_price; assert_eq!(expected, overpay, "overpay"); - let expected_fee = consumed.value() * gas_price; + let expected_fee = consumed * gas_price; assert_eq!(expected_fee, fee, "fee"); } #[test] fn should_handle_extra_cost() { - let limit = Gas::new(6u64); + let limit = U512::from(6u64); let gas_price = 2; let extra_cost = U512::from(1u64); - let cost = limit.value() * gas_price + extra_cost; - let consumed = Gas::from(3u64); + let cost = limit * gas_price + extra_cost; + let consumed = U512::from(3u64); let available = U512::from(21u64); let (overpay, fee) = calculate_overpayment_and_fee( limit, - Some(gas_price), + gas_price, cost, consumed, available, @@ -478,9 +474,9 @@ mod tests { .unwrap(); let unspent = limit.saturating_sub(consumed); - let expected = unspent.value() * gas_price; + let expected = unspent * gas_price; assert_eq!(expected, overpay, "overpay"); - let expected_fee = consumed.value() * gas_price + extra_cost; + let expected_fee = consumed * gas_price + extra_cost; assert_eq!(expected_fee, fee, "fee"); } } diff --git a/types/src/chainspec.rs b/types/src/chainspec.rs index 04c8e366e4..0a81896cfe 100644 --- a/types/src/chainspec.rs +++ b/types/src/chainspec.rs @@ -233,6 +233,24 @@ impl Chainspec { vacancy_config, } } + + /// Set the chain name; + pub fn with_chain_name(&mut self, chain_name: String) -> &mut Self { + self.network_config.name = chain_name; + self + } + + /// Set max associated keys. + pub fn with_max_associated_keys(&mut self, max_associated_keys: u32) -> &mut Self { + self.core_config.max_associated_keys = max_associated_keys; + self + } + + /// Set pricing handling. + pub fn with_pricing_handling(&mut self, pricing_handling: PricingHandling) -> &mut Self { + self.core_config.pricing_handling = pricing_handling; + self + } } impl ToBytes for Chainspec { diff --git a/types/src/chainspec/transaction_config.rs b/types/src/chainspec/transaction_config.rs index 8382809982..1c0b2a1ff9 100644 --- a/types/src/chainspec/transaction_config.rs +++ b/types/src/chainspec/transaction_config.rs @@ -47,8 +47,6 @@ pub struct TransactionConfig { pub max_block_size: u32, /// Maximum sum of payment across all transactions included in a block. pub block_gas_limit: u64, - /// Chainspec configured cost for native transfers. - pub native_transfer_cost: u32, /// Minimum token amount for a native transfer deploy or transaction (a transfer deploy or /// transaction received with an transfer amount less than this will be rejected upon receipt). pub native_transfer_minimum_motes: u64, @@ -76,7 +74,6 @@ impl TransactionConfig { let block_max_approval_count = rng.gen(); let max_block_size = rng.gen_range(1_000_000..1_000_000_000); let block_gas_limit = rng.gen_range(100_000_000_000..1_000_000_000_000_000); - let native_transfer_cost = 2_500_000_000; let native_transfer_minimum_motes = rng.gen_range(DEFAULT_MIN_TRANSFER_MOTES..1_000_000_000_000_000); let max_timestamp_leeway = TimeDiff::from_seconds(rng.gen_range(0..6)); @@ -93,7 +90,6 @@ impl TransactionConfig { block_max_approval_count, max_block_size, block_gas_limit, - native_transfer_cost, native_transfer_minimum_motes, max_timestamp_leeway, deploy_config, @@ -115,7 +111,6 @@ impl Default for TransactionConfig { block_max_approval_count: 2600, max_block_size: 10_485_760, block_gas_limit: 10_000_000_000_000, - native_transfer_cost: 2_500_000_000, native_transfer_minimum_motes: DEFAULT_MIN_TRANSFER_MOTES, max_timestamp_leeway: TimeDiff::from_seconds(5), deploy_config: DeployConfig::default(), @@ -135,7 +130,6 @@ impl ToBytes for TransactionConfig { self.block_max_approval_count.write_bytes(writer)?; self.max_block_size.write_bytes(writer)?; self.block_gas_limit.write_bytes(writer)?; - self.native_transfer_cost.write_bytes(writer)?; self.native_transfer_minimum_motes.write_bytes(writer)?; self.max_timestamp_leeway.write_bytes(writer)?; self.deploy_config.write_bytes(writer)?; @@ -158,7 +152,6 @@ impl ToBytes for TransactionConfig { + self.block_max_approval_count.serialized_length() + self.max_block_size.serialized_length() + self.block_gas_limit.serialized_length() - + self.native_transfer_cost.serialized_length() + self.native_transfer_minimum_motes.serialized_length() + self.max_timestamp_leeway.serialized_length() + self.deploy_config.serialized_length() @@ -177,7 +170,6 @@ impl FromBytes for TransactionConfig { let (block_max_approval_count, remainder) = u32::from_bytes(remainder)?; let (max_block_size, remainder) = u32::from_bytes(remainder)?; let (block_gas_limit, remainder) = u64::from_bytes(remainder)?; - let (native_transfer_cost, remainder) = u32::from_bytes(remainder)?; let (native_transfer_minimum_motes, remainder) = u64::from_bytes(remainder)?; let (max_timestamp_leeway, remainder) = TimeDiff::from_bytes(remainder)?; let (deploy_config, remainder) = DeployConfig::from_bytes(remainder)?; @@ -193,7 +185,6 @@ impl FromBytes for TransactionConfig { block_max_approval_count, max_block_size, block_gas_limit, - native_transfer_cost, native_transfer_minimum_motes, max_timestamp_leeway, deploy_config, diff --git a/types/src/gas.rs b/types/src/gas.rs index 7224addd3e..de6f7f0a2f 100644 --- a/types/src/gas.rs +++ b/types/src/gas.rs @@ -53,6 +53,15 @@ impl Gas { .map(Self::new) } + /// Converts the given `U512` to `Gas` by dividing it by `gas_price`. + /// + /// Returns `None` if `gas_price == 0`. + pub fn from_price(base_amount: U512, gas_price: u8) -> Option { + base_amount + .checked_div(U512::from(gas_price)) + .map(Self::new) + } + /// Checked integer addition. Computes `self + rhs`, returning `None` if overflow occurred. pub fn checked_add(&self, rhs: Self) -> Option { self.0.checked_add(rhs.value()).map(Self::new) diff --git a/types/src/transaction.rs b/types/src/transaction.rs index fa54cc66c9..37734b5c52 100644 --- a/types/src/transaction.rs +++ b/types/src/transaction.rs @@ -40,13 +40,8 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use tracing::error; -#[cfg(any(feature = "std", test))] -use crate::SystemConfig; - #[cfg(any(all(feature = "std", feature = "testing"), test))] use crate::testing::TestRng; -#[cfg(any(feature = "std", test))] -use crate::Gas; #[cfg(feature = "json-schema")] use crate::URef; use crate::{ @@ -54,6 +49,8 @@ use crate::{ bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, Digest, Phase, SecretKey, TimeDiff, Timestamp, }; +#[cfg(any(feature = "std", test))] +use crate::{Chainspec, Gas, Motes}; pub use addressable_entity_identifier::AddressableEntityIdentifier; pub use approval::Approval; pub use approvals_hash::ApprovalsHash; @@ -409,20 +406,23 @@ impl Categorized for Transaction { } } -/// Calculates gas limit for a transaction. +/// Calculates gas limit. #[cfg(any(feature = "std", test))] pub trait GasLimited { /// The error type. type Error; - /// Returns the gas limit or an error. - fn gas_limit( - &self, - system_costs: &SystemConfig, - gas_price: Option, - ) -> Result; + /// The minimum allowed gas price (aka the floor). + const GAS_PRICE_FLOOR: u8 = 1; + + /// Returns a gas cost based upon the gas_limit, the gas price, + /// and the chainspec settings. + fn gas_cost(&self, chainspec: &Chainspec, gas_price: u8) -> Result; + + /// Returns the gas / computation limit prior to execution. + fn gas_limit(&self, chainspec: &Chainspec) -> Result; - /// Returns the gas tolerance of transaction sender. + /// Returns the gas price tolerance. fn gas_price_tolerance(&self) -> Result; } @@ -430,18 +430,23 @@ pub trait GasLimited { impl GasLimited for Transaction { type Error = InvalidTransaction; - fn gas_limit( - &self, - system_costs: &SystemConfig, - gas_price: Option, - ) -> Result { + fn gas_cost(&self, chainspec: &Chainspec, gas_price: u8) -> Result { match self { Transaction::Deploy(deploy) => deploy - .gas_limit(system_costs, gas_price) + .gas_cost(chainspec, gas_price) .map_err(InvalidTransaction::from), Transaction::V1(v1) => v1 - .gas_limit(system_costs, gas_price) + .gas_cost(chainspec, gas_price) + .map_err(InvalidTransaction::from), + } + } + + fn gas_limit(&self, chainspec: &Chainspec) -> Result { + match self { + Transaction::Deploy(deploy) => deploy + .gas_limit(chainspec) .map_err(InvalidTransaction::from), + Transaction::V1(v1) => v1.gas_limit(chainspec).map_err(InvalidTransaction::from), } } diff --git a/types/src/transaction/deploy.rs b/types/src/transaction/deploy.rs index 147258d1b4..c3f99f2222 100644 --- a/types/src/transaction/deploy.rs +++ b/types/src/transaction/deploy.rs @@ -51,8 +51,7 @@ use crate::{ METHOD_REDELEGATE, METHOD_UNDELEGATE, METHOD_WITHDRAW_BID, }, testing::TestRng, - AddressableEntityHash, RuntimeArgs, TransactionConfig, DEFAULT_MAX_PAYMENT_MOTES, - DEFAULT_MIN_TRANSFER_MOTES, + AddressableEntityHash, RuntimeArgs, DEFAULT_MAX_PAYMENT_MOTES, DEFAULT_MIN_TRANSFER_MOTES, }; use crate::{ bytesrepr::{self, FromBytes, ToBytes}, @@ -60,8 +59,11 @@ use crate::{ transaction::{Approval, ApprovalsHash, Categorized}, Digest, DisplayIter, PublicKey, SecretKey, TimeDiff, Timestamp, TransactionCategory, }; + +#[cfg(any(feature = "std", test))] +use crate::{chainspec::PricingHandling, Chainspec}; #[cfg(any(feature = "std", test))] -use crate::{system::auction::ARG_AMOUNT, transaction::GasLimited, Gas, Motes, SystemConfig, U512}; +use crate::{system::auction::ARG_AMOUNT, transaction::GasLimited, Gas, Motes, U512}; #[cfg(any(feature = "std", test))] pub use deploy_builder::{DeployBuilder, DeployBuilderError}; pub use deploy_category::DeployCategory; @@ -261,7 +263,7 @@ impl Deploy { self.header.expired(current_instant) } - /// Returns the price per gas unit for the `Deploy`. + /// Returns the sender's gas price tolerance for block inclusion. pub fn gas_price(&self) -> u64 { self.header.gas_price() } @@ -396,16 +398,15 @@ impl Deploy { #[cfg(any(all(feature = "std", feature = "testing"), test))] pub fn is_config_compliant( &self, - chain_name: &str, - cost_table: &SystemConfig, - config: &TransactionConfig, - max_associated_keys: u32, + chainspec: &Chainspec, timestamp_leeway: TimeDiff, at: Timestamp, ) -> Result<(), InvalidDeploy> { + let config = &chainspec.transaction_config; self.is_valid_size(config.max_transaction_size)?; let header = self.header(); + let chain_name = &chainspec.network_config.name; if header.chain_name() != chain_name { debug!( deploy_hash = %self.hash(), @@ -421,6 +422,7 @@ impl Deploy { header.is_valid(config, timestamp_leeway, at, &self.hash)?; + let max_associated_keys = chainspec.core_config.max_associated_keys; if self.approvals.len() > max_associated_keys as usize { debug!( deploy_hash = %self.hash(), @@ -434,8 +436,8 @@ impl Deploy { }); } - let gas_limit = self.gas_limit(cost_table, None)?; - let block_gas_limit = Gas::new(U512::from(config.block_gas_limit)); + let gas_limit = self.gas_limit(chainspec)?; + let block_gas_limit = Gas::new(config.block_gas_limit); if gas_limit > block_gas_limit { debug!( payment_amount = %gas_limit, @@ -1159,37 +1161,46 @@ impl Categorized for Deploy { impl GasLimited for Deploy { type Error = InvalidDeploy; - fn gas_limit( - &self, - system_costs: &SystemConfig, - gas_price: Option, - ) -> Result { - let user_specified_price = - u8::try_from(self.gas_price()).map_err(|_| Self::Error::UnableToCalculateGasLimit)?; - let actual_price = match gas_price { - Some(price) => price.max(user_specified_price), - None => user_specified_price, - }; - let motes = { - if self.is_transfer() { - Motes::new(U512::from(system_costs.mint_costs().transfer)) - } else { - let value = self - .payment() - .args() - .get(ARG_AMOUNT) - .ok_or(InvalidDeploy::MissingPaymentAmount)?; - let payment_amount = value - .clone() - .into_t::() - .map_err(|_| InvalidDeploy::FailedToParsePaymentAmount)?; - Motes::new(payment_amount) + fn gas_cost(&self, chainspec: &Chainspec, gas_price: u8) -> Result { + let gas_limit = self.gas_limit(chainspec)?; + let motes = + Motes::from_gas(gas_limit, gas_price).ok_or(InvalidDeploy::UnableToCalculateGasCost)?; + Ok(motes) + } + + fn gas_limit(&self, chainspec: &Chainspec) -> Result { + let pricing_handling = chainspec.core_config.pricing_handling; + let costs = &chainspec.system_costs_config; + let gas_limit = match pricing_handling { + PricingHandling::Classic => { + // in the original implementation, for standard deploys the payment amount + // specified by the sender is the gas limit (up to the max block limit). + if self.is_transfer() { + Gas::new(costs.mint_costs().transfer) + } else { + let value = self + .payment() + .args() + .get(ARG_AMOUNT) + .ok_or(InvalidDeploy::MissingPaymentAmount)?; + let payment_amount = value + .clone() + .into_t::() + .map_err(|_| InvalidDeploy::FailedToParsePaymentAmount)?; + Gas::new(payment_amount) + } } + PricingHandling::Fixed => { + // in fixed, the computation limit is fixed per the chainspec settings + let computation_limit = if self.is_transfer() { + costs.mint_costs().transfer + } else { + costs.standard_transaction_limit() + }; + Gas::new(computation_limit) + } // legacy deploys do not support reservations }; - match Gas::from_motes(motes, actual_price) { - Some(gas) => Ok(gas), - None => Err(InvalidDeploy::MissingPaymentAmount), - } + Ok(gas_limit) } fn gas_price_tolerance(&self) -> Result { @@ -1389,9 +1400,7 @@ mod tests { use std::{iter, time::Duration}; use super::*; - use crate::CLValue; - - const DEFAULT_MAX_ASSOCIATED_KEYS: u32 = 100; + use crate::{CLValue, TransactionConfig}; #[test] fn json_roundtrip() { @@ -1457,6 +1466,7 @@ mod tests { #[test] fn is_valid() { let mut rng = TestRng::new(); + let deploy = create_deploy(&mut rng, TransactionConfig::default().max_ttl, 0, "net-1"); assert_eq!( deploy.is_valid.get(), @@ -1568,26 +1578,20 @@ mod tests { #[test] fn is_acceptable() { let mut rng = TestRng::new(); - let chain_name = "net-1"; - let cost_table = SystemConfig::default(); - let config = TransactionConfig::default(); + let chain_name = "net-1".to_string(); + let mut chainspec = Chainspec::default(); + chainspec.with_chain_name(chain_name.to_string()); + let config = chainspec.transaction_config; let deploy = create_deploy( &mut rng, config.max_ttl, config.deploy_config.max_dependencies.into(), - chain_name, + &chain_name, ); let current_timestamp = deploy.header().timestamp(); deploy - .is_config_compliant( - chain_name, - &cost_table, - &config, - DEFAULT_MAX_ASSOCIATED_KEYS, - TimeDiff::default(), - current_timestamp, - ) + .is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp) .expect("should be acceptable"); } @@ -1596,8 +1600,10 @@ mod tests { let mut rng = TestRng::new(); let expected_chain_name = "net-1"; let wrong_chain_name = "net-2".to_string(); - let cost_table = SystemConfig::default(); - let config = TransactionConfig::default(); + + let mut chainspec = Chainspec::default(); + chainspec.with_chain_name(expected_chain_name.to_string()); + let config = chainspec.transaction_config; let deploy = create_deploy( &mut rng, @@ -1613,14 +1619,7 @@ mod tests { let current_timestamp = deploy.header().timestamp(); assert_eq!( - deploy.is_config_compliant( - expected_chain_name, - &cost_table, - &config, - DEFAULT_MAX_ASSOCIATED_KEYS, - TimeDiff::default(), - current_timestamp - ), + deploy.is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp), Err(expected_error) ); assert!( @@ -1633,8 +1632,10 @@ mod tests { fn not_acceptable_due_to_excessive_dependencies() { let mut rng = TestRng::new(); let chain_name = "net-1"; - let cost_table = SystemConfig::default(); - let config = TransactionConfig::default(); + + let mut chainspec = Chainspec::default(); + chainspec.with_chain_name(chain_name.to_string()); + let config = chainspec.transaction_config; let dependency_count = usize::from(config.deploy_config.max_dependencies + 1); @@ -1644,14 +1645,7 @@ mod tests { let current_timestamp = deploy.header().timestamp(); assert_eq!( - deploy.is_config_compliant( - chain_name, - &cost_table, - &config, - DEFAULT_MAX_ASSOCIATED_KEYS, - TimeDiff::default(), - current_timestamp - ), + deploy.is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp), Err(expected_error) ); assert!( @@ -1664,8 +1658,10 @@ mod tests { fn not_acceptable_due_to_excessive_ttl() { let mut rng = TestRng::new(); let chain_name = "net-1"; - let cost_table = SystemConfig::default(); - let config = TransactionConfig::default(); + + let mut chainspec = Chainspec::default(); + chainspec.with_chain_name(chain_name.to_string()); + let config = chainspec.transaction_config; let ttl = config.max_ttl + TimeDiff::from(Duration::from_secs(1)); @@ -1683,14 +1679,7 @@ mod tests { let current_timestamp = deploy.header().timestamp(); assert_eq!( - deploy.is_config_compliant( - chain_name, - &cost_table, - &config, - DEFAULT_MAX_ASSOCIATED_KEYS, - TimeDiff::default(), - current_timestamp - ), + deploy.is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp), Err(expected_error) ); assert!( @@ -1703,8 +1692,10 @@ mod tests { fn not_acceptable_due_to_timestamp_in_future() { let mut rng = TestRng::new(); let chain_name = "net-1"; - let cost_table = SystemConfig::default(); - let config = TransactionConfig::default(); + + let mut chainspec = Chainspec::default(); + chainspec.with_chain_name(chain_name.to_string()); + let config = chainspec.transaction_config; let leeway = TimeDiff::from_seconds(2); let deploy = create_deploy( @@ -1722,14 +1713,7 @@ mod tests { }; assert_eq!( - deploy.is_config_compliant( - chain_name, - &cost_table, - &config, - DEFAULT_MAX_ASSOCIATED_KEYS, - leeway, - current_timestamp - ), + deploy.is_config_compliant(&chainspec, leeway, current_timestamp), Err(expected_error) ); assert!( @@ -1742,8 +1726,10 @@ mod tests { fn acceptable_if_timestamp_slightly_in_future() { let mut rng = TestRng::new(); let chain_name = "net-1"; - let cost_table = SystemConfig::default(); - let config = TransactionConfig::default(); + + let mut chainspec = Chainspec::default(); + chainspec.with_chain_name(chain_name.to_string()); + let config = chainspec.transaction_config; let leeway = TimeDiff::from_seconds(2); let deploy = create_deploy( @@ -1754,14 +1740,7 @@ mod tests { ); let current_timestamp = deploy.header.timestamp() - (leeway / 2); deploy - .is_config_compliant( - chain_name, - &cost_table, - &config, - DEFAULT_MAX_ASSOCIATED_KEYS, - leeway, - current_timestamp, - ) + .is_config_compliant(&chainspec, leeway, current_timestamp) .expect("should be acceptable"); } @@ -1769,8 +1748,11 @@ mod tests { fn not_acceptable_due_to_missing_payment_amount() { let mut rng = TestRng::new(); let chain_name = "net-1"; - let cost_table = SystemConfig::default(); - let config = TransactionConfig::default(); + + let mut chainspec = Chainspec::default(); + chainspec.with_chain_name(chain_name.to_string()); + chainspec.with_pricing_handling(PricingHandling::Classic); + let config = chainspec.transaction_config; let payment = ExecutableDeployItem::ModuleBytes { module_bytes: Bytes::new(), @@ -1797,14 +1779,7 @@ mod tests { let current_timestamp = deploy.header().timestamp(); assert_eq!( - deploy.is_config_compliant( - chain_name, - &cost_table, - &config, - DEFAULT_MAX_ASSOCIATED_KEYS, - TimeDiff::default(), - current_timestamp - ), + deploy.is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp), Err(InvalidDeploy::MissingPaymentAmount) ); assert!( @@ -1817,8 +1792,11 @@ mod tests { fn not_acceptable_due_to_mangled_payment_amount() { let mut rng = TestRng::new(); let chain_name = "net-1"; - let cost_table = SystemConfig::default(); - let config = TransactionConfig::default(); + + let mut chainspec = Chainspec::default(); + chainspec.with_chain_name(chain_name.to_string()); + chainspec.with_pricing_handling(PricingHandling::Classic); + let config = chainspec.transaction_config; let payment = ExecutableDeployItem::ModuleBytes { module_bytes: Bytes::new(), @@ -1847,14 +1825,7 @@ mod tests { let current_timestamp = deploy.header().timestamp(); assert_eq!( - deploy.is_config_compliant( - chain_name, - &cost_table, - &config, - DEFAULT_MAX_ASSOCIATED_KEYS, - TimeDiff::default(), - current_timestamp - ), + deploy.is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp), Err(InvalidDeploy::FailedToParsePaymentAmount) ); assert!( @@ -1867,8 +1838,11 @@ mod tests { fn not_acceptable_due_to_excessive_payment_amount() { let mut rng = TestRng::new(); let chain_name = "net-1"; - let cost_table = SystemConfig::default(); - let config = TransactionConfig::default(); + + let mut chainspec = Chainspec::default(); + chainspec.with_chain_name(chain_name.to_string()); + chainspec.with_pricing_handling(PricingHandling::Classic); + let config = chainspec.transaction_config; let amount = U512::from(config.block_gas_limit + 1); let payment = ExecutableDeployItem::ModuleBytes { @@ -1903,14 +1877,7 @@ mod tests { let current_timestamp = deploy.header().timestamp(); assert_eq!( - deploy.is_config_compliant( - chain_name, - &cost_table, - &config, - DEFAULT_MAX_ASSOCIATED_KEYS, - TimeDiff::default(), - current_timestamp - ), + deploy.is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp), Err(expected_error) ); assert!( @@ -1924,8 +1891,10 @@ mod tests { let mut rng = TestRng::new(); let secret_key = SecretKey::random(&mut rng); let chain_name = "net-1"; - let cost_table = SystemConfig::default(); - let config = TransactionConfig::default(); + + let mut chainspec = Chainspec::default(); + chainspec.with_chain_name(chain_name.to_string()); + let config = chainspec.transaction_config; let amount = U512::from(config.block_gas_limit + 1); let payment = ExecutableDeployItem::ModuleBytes { @@ -1960,14 +1929,7 @@ mod tests { let current_timestamp = deploy.header().timestamp(); assert_eq!( Ok(()), - deploy.is_config_compliant( - chain_name, - &cost_table, - &config, - DEFAULT_MAX_ASSOCIATED_KEYS, - TimeDiff::default(), - current_timestamp - ) + deploy.is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp) ) } @@ -1975,8 +1937,10 @@ mod tests { fn not_acceptable_due_to_excessive_approvals() { let mut rng = TestRng::new(); let chain_name = "net-1"; - let cost_table = SystemConfig::default(); - let config = TransactionConfig::default(); + + let mut chainspec = Chainspec::default(); + chainspec.with_chain_name(chain_name.to_string()); + let config = chainspec.transaction_config; let deploy = create_deploy( &mut rng, config.max_ttl, @@ -1986,20 +1950,14 @@ mod tests { // This test is to ensure a given limit is being checked. // Therefore, set the limit to one less than the approvals in the deploy. let max_associated_keys = (deploy.approvals.len() - 1) as u32; + chainspec.with_max_associated_keys(max_associated_keys); let current_timestamp = deploy.header().timestamp(); assert_eq!( Err(InvalidDeploy::ExcessiveApprovals { got: deploy.approvals.len() as u32, - max_associated_keys: (deploy.approvals.len() - 1) as u32 + max_associated_keys }), - deploy.is_config_compliant( - chain_name, - &cost_table, - &config, - max_associated_keys, - TimeDiff::default(), - current_timestamp - ) + deploy.is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp) ) } @@ -2007,8 +1965,10 @@ mod tests { fn not_acceptable_due_to_missing_transfer_amount() { let mut rng = TestRng::new(); let chain_name = "net-1"; - let cost_table = SystemConfig::default(); - let config = TransactionConfig::default(); + let mut chainspec = Chainspec::default(); + chainspec.with_chain_name(chain_name.to_string()); + + let config = chainspec.transaction_config; let mut deploy = create_deploy( &mut rng, config.max_ttl, @@ -2025,14 +1985,7 @@ mod tests { let current_timestamp = deploy.header().timestamp(); assert_eq!( Err(InvalidDeploy::MissingTransferAmount), - deploy.is_config_compliant( - chain_name, - &cost_table, - &config, - DEFAULT_MAX_ASSOCIATED_KEYS, - TimeDiff::default(), - current_timestamp - ) + deploy.is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp) ) } @@ -2040,8 +1993,10 @@ mod tests { fn not_acceptable_due_to_mangled_transfer_amount() { let mut rng = TestRng::new(); let chain_name = "net-1"; - let cost_table = SystemConfig::default(); - let config = TransactionConfig::default(); + let mut chainspec = Chainspec::default(); + chainspec.with_chain_name(chain_name.to_string()); + + let config = chainspec.transaction_config; let mut deploy = create_deploy( &mut rng, config.max_ttl, @@ -2062,14 +2017,7 @@ mod tests { let current_timestamp = deploy.header().timestamp(); assert_eq!( Err(InvalidDeploy::FailedToParseTransferAmount), - deploy.is_config_compliant( - chain_name, - &cost_table, - &config, - DEFAULT_MAX_ASSOCIATED_KEYS, - TimeDiff::default(), - current_timestamp - ) + deploy.is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp) ) } @@ -2077,8 +2025,10 @@ mod tests { fn not_acceptable_due_to_insufficient_transfer_amount() { let mut rng = TestRng::new(); let chain_name = "net-1"; - let cost_table = SystemConfig::default(); - let config = TransactionConfig::default(); + let mut chainspec = Chainspec::default(); + chainspec.with_chain_name(chain_name.to_string()); + + let config = chainspec.transaction_config; let mut deploy = create_deploy( &mut rng, config.max_ttl, @@ -2105,14 +2055,7 @@ mod tests { minimum: Box::new(U512::from(config.native_transfer_minimum_motes)), attempted: Box::new(insufficient_amount), }), - deploy.is_config_compliant( - chain_name, - &cost_table, - &config, - DEFAULT_MAX_ASSOCIATED_KEYS, - TimeDiff::default(), - current_timestamp - ) + deploy.is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp) ) } } diff --git a/types/src/transaction/deploy/deploy_header.rs b/types/src/transaction/deploy/deploy_header.rs index 9e15a3a777..737e3ff95e 100644 --- a/types/src/transaction/deploy/deploy_header.rs +++ b/types/src/transaction/deploy/deploy_header.rs @@ -83,8 +83,25 @@ impl DeployHeader { self.expires() < current_instant } - /// Returns the price per gas unit for the `Deploy`. + /// Returns the sender's gas price tolerance for block inclusion. pub fn gas_price(&self) -> u64 { + // in the original implementation, we did not have dynamic gas pricing + // but the sender of the deploy could specify a higher gas price, + // and the the payment amount would be multiplied by that number + // for settlement purposes. This did not increase their computation limit, + // only how much they were charged. The intent was, the total cost + // would be a consideration for block proposal but in the end we shipped + // with an egalitarian subjective fifo proposer. Thus, there was no + // functional reason / no benefit to a sender setting gas price to + // anything higher than 1. + // + // As of 2.0 we have dynamic gas prices, this vestigial field has been + // repurposed, interpreted to indicate a gas price tolerance. + // If this deploy is buffered and the current gas price is higher than this + // value, it will not be included in a proposed block. + // + // This allowing the sender to opt out of block inclusion if the gas price is + // higher than they want to pay for. self.gas_price } diff --git a/types/src/transaction/deploy/error.rs b/types/src/transaction/deploy/error.rs index c84208cd56..f846fee0b7 100644 --- a/types/src/transaction/deploy/error.rs +++ b/types/src/transaction/deploy/error.rs @@ -118,8 +118,12 @@ pub enum InvalidDeploy { /// The chainspec limit for max_associated_keys. max_associated_keys: u32, }, + /// Unable to calculate gas limit. UnableToCalculateGasLimit, + + /// Unable to calculate gas cost. + UnableToCalculateGasCost, } impl Display for InvalidDeploy { @@ -234,6 +238,9 @@ impl Display for InvalidDeploy { InvalidDeploy::UnableToCalculateGasLimit => { write!(formatter, "unable to calculate gas limit",) } + InvalidDeploy::UnableToCalculateGasCost => { + write!(formatter, "unable to calculate gas cost",) + } } } } @@ -266,7 +273,8 @@ impl StdError for InvalidDeploy { | InvalidDeploy::FailedToParseTransferAmount | InvalidDeploy::InsufficientTransferAmount { .. } | InvalidDeploy::ExcessiveApprovals { .. } - | InvalidDeploy::UnableToCalculateGasLimit => None, + | InvalidDeploy::UnableToCalculateGasLimit + | InvalidDeploy::UnableToCalculateGasCost => None, } } } diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index 68497a19f0..98b2b84df6 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -39,7 +39,7 @@ use crate::{ #[cfg(any(all(feature = "std", feature = "testing"), test))] use crate::{chainspec::PricingHandling, testing::TestRng, Chainspec}; #[cfg(any(feature = "std", test))] -use crate::{Gas, Motes, SystemConfig, TransactionConfig, U512}; +use crate::{Gas, Motes, TransactionConfig, U512}; pub use errors_v1::{ DecodeFromJsonErrorV1 as TransactionV1DecodeFromJsonError, ErrorV1 as TransactionV1Error, ExcessiveSizeErrorV1 as TransactionV1ExcessiveSizeError, @@ -421,7 +421,7 @@ impl TransactionV1 { }); } - let gas_limit = self.gas_limit(&chainspec.system_costs_config, None)?; + let gas_limit = self.gas_limit(chainspec)?; let block_gas_limit = Gas::new(U512::from(transaction_config.block_gas_limit)); if gas_limit > block_gas_limit { debug!( @@ -614,22 +614,31 @@ impl Categorized for TransactionV1 { impl GasLimited for TransactionV1 { type Error = InvalidTransactionV1; - fn gas_limit(&self, costs: &SystemConfig, gas_price: Option) -> Result { + fn gas_cost(&self, chainspec: &Chainspec, gas_price: u8) -> Result { + let gas_limit = self.gas_limit(chainspec)?; + let motes = match self.header().pricing_mode() { + PricingMode::Classic { .. } | PricingMode::Fixed { .. } => { + Motes::from_gas(gas_limit, gas_price) + .ok_or(InvalidTransactionV1::UnableToCalculateGasCost)? + } + PricingMode::Reserved { .. } => { + Motes::zero() // prepaid + } + }; + Ok(motes) + } + + fn gas_limit(&self, chainspec: &Chainspec) -> Result { + let costs = chainspec.system_costs_config; let gas = match self.header().pricing_mode() { PricingMode::Classic { payment_amount, gas_price: user_specified_price, .. } => { - let actual_price = match gas_price { - Some(system_specified_price) => { - // take the higher of the two possible prices - (*user_specified_price).max(system_specified_price) - } - None => *user_specified_price, - }; - let motes = Motes::new(U512::from(*payment_amount)); - Gas::from_motes(motes, actual_price).ok_or( + let actual_price = (*user_specified_price).max(Self::GAS_PRICE_FLOOR); + let base_amount = U512::from(*payment_amount); + Gas::from_price(base_amount, actual_price).ok_or( InvalidTransactionV1::GasPriceConversion { amount: *payment_amount, gas_price: actual_price, @@ -637,9 +646,7 @@ impl GasLimited for TransactionV1 { )? } PricingMode::Fixed { .. } => { - // if gas price is not provided, assume price == 1 - let gas_price = gas_price.unwrap_or(1); - let cost = { + let computation_limit = { if self.is_native_mint() { // Because we currently only support one native mint interaction, // native transfer, we can short circuit to return that value. @@ -672,21 +679,15 @@ impl GasLimited for TransactionV1 { costs.standard_transaction_limit() } }; - let fixed_cost = U512::from(cost); - Gas::from_motes(Motes::new(fixed_cost), gas_price).ok_or( - InvalidTransactionV1::GasPriceConversion { - amount: fixed_cost.as_u64(), - gas_price, - }, - )? + Gas::new(U512::from(computation_limit)) } PricingMode::Reserved { paid_amount, strike_price, .. } => { - // prepaid, if receipt is legit (future use, not currently implemented) - Gas::from_motes(Motes::new(*paid_amount), *strike_price).ok_or( + // prepaid, if receipt is legit (future use) + Gas::from_price(*paid_amount, *strike_price).ok_or( InvalidTransactionV1::GasPriceConversion { amount: paid_amount.as_u64(), gas_price: *strike_price, diff --git a/types/src/transaction/transaction_v1/errors_v1.rs b/types/src/transaction/transaction_v1/errors_v1.rs index e24ceaee50..690eb5bb97 100644 --- a/types/src/transaction/transaction_v1/errors_v1.rs +++ b/types/src/transaction/transaction_v1/errors_v1.rs @@ -145,6 +145,8 @@ pub enum InvalidTransaction { }, /// Unable to calculate gas limit. UnableToCalculateGasLimit, + /// Unable to calculate gas cost. + UnableToCalculateGasCost, /// Invalid combination of pricing handling and pricing mode. InvalidPricingMode { /// The pricing mode as specified by the transaction. @@ -270,6 +272,9 @@ impl Display for InvalidTransaction { InvalidTransaction::UnableToCalculateGasLimit => { write!(formatter, "unable to calculate gas limit",) } + InvalidTransaction::UnableToCalculateGasCost => { + write!(formatter, "unable to calculate gas cost",) + } InvalidTransaction::InvalidPricingMode { price_mode } => { write!( formatter, @@ -310,6 +315,7 @@ impl StdError for InvalidTransaction { | InvalidTransaction::EmptyModuleBytes | InvalidTransaction::GasPriceConversion { .. } | InvalidTransaction::UnableToCalculateGasLimit + | InvalidTransaction::UnableToCalculateGasCost | InvalidTransaction::InvalidPricingMode { .. } => None, } } From e83b6a7cf13f0fde004b60c664bc53c4d08f0178 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Wed, 27 Mar 2024 18:15:51 -0700 Subject: [PATCH 50/70] more test coverage for cost / limit --- types/src/chainspec.rs | 6 + types/src/transaction/deploy.rs | 116 +++++++++++++++++ types/src/transaction/pricing_mode.rs | 6 +- types/src/transaction/transaction_v1.rs | 158 +++++++++++++++++++++--- 4 files changed, 267 insertions(+), 19 deletions(-) diff --git a/types/src/chainspec.rs b/types/src/chainspec.rs index 0a81896cfe..8b33ef08b1 100644 --- a/types/src/chainspec.rs +++ b/types/src/chainspec.rs @@ -251,6 +251,12 @@ impl Chainspec { self.core_config.pricing_handling = pricing_handling; self } + + /// Set allow reservations. + pub fn with_allow_reservations(&mut self, allow_reservations: bool) -> &mut Self { + self.core_config.allow_reservations = allow_reservations; + self + } } impl ToBytes for Chainspec { diff --git a/types/src/transaction/deploy.rs b/types/src/transaction/deploy.rs index c3f99f2222..035f989f4d 100644 --- a/types/src/transaction/deploy.rs +++ b/types/src/transaction/deploy.rs @@ -2058,4 +2058,120 @@ mod tests { deploy.is_config_compliant(&chainspec, TimeDiff::default(), current_timestamp) ) } + + #[test] + fn should_use_payment_amount_for_classic_payment() { + let payment_amount = 500u64; + let mut rng = TestRng::new(); + let chain_name = "net-1"; + let mut chainspec = Chainspec::default(); + chainspec + .with_chain_name(chain_name.to_string()) + .with_pricing_handling(PricingHandling::Classic); + + let config = chainspec.transaction_config; + + let payment = ExecutableDeployItem::ModuleBytes { + module_bytes: Bytes::new(), + args: runtime_args! { + "amount" => U512::from(payment_amount) + }, + }; + + // Create an empty session object that is not transfer to ensure + // that the payment amount is checked. + let session = ExecutableDeployItem::StoredContractByName { + name: "".to_string(), + entry_point: "".to_string(), + args: Default::default(), + }; + + let mut deploy = create_deploy( + &mut rng, + config.max_ttl, + config.deploy_config.max_dependencies.into(), + chain_name, + ); + deploy.payment = payment; + deploy.session = session; + + let mut gas_price = 1; + let cost = deploy + .gas_cost(&chainspec, gas_price) + .expect("should cost") + .value(); + assert_eq!( + cost, + U512::from(payment_amount), + "in classic pricing, the user selected amount should be the cost if gas price is 1" + ); + gas_price += 1; + let cost = deploy + .gas_cost(&chainspec, gas_price) + .expect("should cost") + .value(); + assert_eq!( + cost, + U512::from(payment_amount) * gas_price, + "in classic pricing, the cost should == user selected amount * gas_price" + ); + } + + #[test] + fn should_use_cost_table_for_fixed_payment() { + let payment_amount = 500u64; + let mut rng = TestRng::new(); + let chain_name = "net-1"; + let mut chainspec = Chainspec::default(); + chainspec + .with_chain_name(chain_name.to_string()) + .with_pricing_handling(PricingHandling::Classic); + + let config = chainspec.transaction_config; + + let payment = ExecutableDeployItem::ModuleBytes { + module_bytes: Bytes::new(), + args: runtime_args! { + "amount" => U512::from(payment_amount) + }, + }; + + // Create an empty session object that is not transfer to ensure + // that the payment amount is checked. + let session = ExecutableDeployItem::StoredContractByName { + name: "".to_string(), + entry_point: "".to_string(), + args: Default::default(), + }; + + let mut deploy = create_deploy( + &mut rng, + config.max_ttl, + config.deploy_config.max_dependencies.into(), + chain_name, + ); + deploy.payment = payment; + deploy.session = session; + + let mut gas_price = 1; + let limit = deploy.gas_limit(&chainspec).expect("should limit").value(); + let cost = deploy + .gas_cost(&chainspec, gas_price) + .expect("should cost") + .value(); + assert_eq!( + cost, limit, + "in fixed pricing, the cost & limit should == if gas price is 1" + ); + gas_price += 1; + let cost = deploy + .gas_cost(&chainspec, gas_price) + .expect("should cost") + .value(); + assert_eq!( + cost, + limit * gas_price, + "in fixed pricing, the cost should == limit * gas_price" + ); + } } diff --git a/types/src/transaction/pricing_mode.rs b/types/src/transaction/pricing_mode.rs index 8ae5b0cc88..74cc4fbd77 100644 --- a/types/src/transaction/pricing_mode.rs +++ b/types/src/transaction/pricing_mode.rs @@ -15,7 +15,7 @@ use super::Transaction; use crate::testing::TestRng; use crate::{ bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, - Digest, U512, + Digest, }; const CLASSIC_TAG: u8 = 0; @@ -56,7 +56,7 @@ pub enum PricingMode { /// Pre-paid receipt. receipt: Digest, /// Price paid in the past to reserve space in a future block. - paid_amount: U512, + paid_amount: u64, /// The gas price at the time of reservation. strike_price: u8, }, @@ -210,7 +210,7 @@ impl FromBytes for PricingMode { } RESERVED_TAG => { let (receipt, remainder) = Digest::from_bytes(remainder)?; - let (paid_amount, remainder) = U512::from_bytes(remainder)?; + let (paid_amount, remainder) = u64::from_bytes(remainder)?; let (strike_price, remainder) = u8::from_bytes(remainder)?; Ok(( PricingMode::Reserved { diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index 98b2b84df6..d1777a2a87 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -631,20 +631,7 @@ impl GasLimited for TransactionV1 { fn gas_limit(&self, chainspec: &Chainspec) -> Result { let costs = chainspec.system_costs_config; let gas = match self.header().pricing_mode() { - PricingMode::Classic { - payment_amount, - gas_price: user_specified_price, - .. - } => { - let actual_price = (*user_specified_price).max(Self::GAS_PRICE_FLOOR); - let base_amount = U512::from(*payment_amount); - Gas::from_price(base_amount, actual_price).ok_or( - InvalidTransactionV1::GasPriceConversion { - amount: *payment_amount, - gas_price: actual_price, - }, - )? - } + PricingMode::Classic { payment_amount, .. } => Gas::new(*payment_amount), PricingMode::Fixed { .. } => { let computation_limit = { if self.is_native_mint() { @@ -687,9 +674,9 @@ impl GasLimited for TransactionV1 { .. } => { // prepaid, if receipt is legit (future use) - Gas::from_price(*paid_amount, *strike_price).ok_or( + Gas::from_price(U512::from(*paid_amount), *strike_price).ok_or( InvalidTransactionV1::GasPriceConversion { - amount: paid_amount.as_u64(), + amount: *paid_amount, gas_price: *strike_price, }, )? @@ -1233,4 +1220,143 @@ mod tests { ) .is_ok()); } + + #[test] + fn should_use_payment_amount_for_classic_payment() { + let payment_amount = 500u64; + let mut chainspec = Chainspec::default(); + let chain_name = "net-1"; + chainspec + .with_chain_name(chain_name.to_string()) + .with_pricing_handling(PricingHandling::Classic); + + let rng = &mut TestRng::new(); + let builder = TransactionV1Builder::new_random(rng) + .with_chain_name(chain_name) + .with_pricing_mode(PricingMode::Classic { + payment_amount, + gas_price: 1, + standard_payment: true, + }); + let transaction = builder.build().expect("should build"); + let mut gas_price = 1; + let cost = transaction + .gas_cost(&chainspec, gas_price) + .expect("should cost") + .value(); + assert_eq!( + cost, + U512::from(payment_amount), + "in classic pricing, the user selected amount should be the cost if gas price is 1" + ); + gas_price += 1; + let cost = transaction + .gas_cost(&chainspec, gas_price) + .expect("should cost") + .value(); + assert_eq!( + cost, + U512::from(payment_amount) * gas_price, + "in classic pricing, the cost should == user selected amount * gas_price" + ); + } + + #[test] + fn should_use_cost_table_for_fixed_payment() { + let mut chainspec = Chainspec::default(); + let chain_name = "net-1"; + chainspec + .with_chain_name(chain_name.to_string()) + .with_pricing_handling(PricingHandling::Fixed); + + let rng = &mut TestRng::new(); + let builder = TransactionV1Builder::new_random(rng) + .with_chain_name(chain_name) + .with_pricing_mode(PricingMode::Fixed { + gas_price_tolerance: 5, + }); + let transaction = builder.build().expect("should build"); + let mut gas_price = 1; + let limit = transaction + .gas_limit(&chainspec) + .expect("should limit") + .value(); + let cost = transaction + .gas_cost(&chainspec, gas_price) + .expect("should cost") + .value(); + assert_eq!( + cost, limit, + "in fixed pricing, the cost & limit should == if gas price is 1" + ); + gas_price += 1; + let cost = transaction + .gas_cost(&chainspec, gas_price) + .expect("should cost") + .value(); + assert_eq!( + cost, + limit * gas_price, + "in fixed pricing, the cost should == limit * gas_price" + ); + } + + #[test] + fn should_have_limit_but_no_cost_for_reserved() { + reserved_pricing(500u64, 1u8); + } + + #[test] + fn should_respect_strike_price_for_reserved() { + reserved_pricing(500u64, 2u8); + } + + fn reserved_pricing(paid_amount: u64, strike_price: u8) { + let mut chainspec = Chainspec::default(); + let chain_name = "net-1"; + chainspec + .with_chain_name(chain_name.to_string()) + .with_pricing_handling(PricingHandling::Fixed) + .with_allow_reservations(true); + + let rng = &mut TestRng::new(); + let builder = TransactionV1Builder::new_random(rng) + .with_chain_name(chain_name) + .with_pricing_mode(PricingMode::Reserved { + paid_amount, + strike_price, + receipt: Digest::default(), + }); + let transaction = builder.build().expect("should build"); + let mut gas_price = 1; + let limit = transaction + .gas_limit(&chainspec) + .expect("should limit") + .value() + .as_u64(); + assert_eq!( + limit, + paid_amount / strike_price as u64, + "in reserved pricing, limit should == paid_amount / strike price" + ); + let cost = transaction + .gas_cost(&chainspec, gas_price) + .expect("should cost") + .value(); + assert_eq!( + cost, + U512::zero(), + "in reserved pricing, cost should == 0 as it was prepaid" + ); + gas_price += 1; + let cost = transaction + .gas_cost(&chainspec, gas_price) + .expect("should cost") + .value(); + assert_eq!( + cost, + U512::zero(), + "in reserved pricing, gas price does not matter as it was prepaid" + ); + } } From 0db3bad8dfb22a0248b956a301fd6490019a27df Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Wed, 27 Mar 2024 18:40:00 -0700 Subject: [PATCH 51/70] increasing headroom for standard & installer gas limits --- node/src/reactor/main_reactor/tests.rs | 4 ++-- resources/local/chainspec.toml.in | 4 ++-- resources/production/chainspec.toml | 4 ++-- storage/src/system/auction/auction_native.rs | 2 -- storage/src/tracking_copy/error.rs | 3 --- .../src/chainspec/vm_config/system_config.rs | 20 +++++++++---------- types/src/transaction/deploy.rs | 2 +- types/src/transaction/transaction_v1.rs | 7 ++++--- 8 files changed, 21 insertions(+), 25 deletions(-) diff --git a/node/src/reactor/main_reactor/tests.rs b/node/src/reactor/main_reactor/tests.rs index 10cdad5e2a..16187cd9b8 100644 --- a/node/src/reactor/main_reactor/tests.rs +++ b/node/src/reactor/main_reactor/tests.rs @@ -192,8 +192,8 @@ impl TestFixture { let (mut chainspec, chainspec_raw_bytes) = <(Chainspec, ChainspecRawBytes)>::from_resources("local"); - let min_motes = 1_000_000_000_000u64; // 1000 token - let max_motes = min_motes * 100; // 100_000 token + let min_motes = 100_000_000_000_000_000u64; + let max_motes = min_motes * 100; let balance = U512::from(rng.gen_range(min_motes..max_motes)); // Override accounts with those generated from the keys. diff --git a/resources/local/chainspec.toml.in b/resources/local/chainspec.toml.in index 1b89866bdb..a87d9941d2 100644 --- a/resources/local/chainspec.toml.in +++ b/resources/local/chainspec.toml.in @@ -288,8 +288,8 @@ max_topics_per_contract = 128 max_message_size = 1_024 [system_costs] -install_upgrade_gas_limit = 3_500_000_000 -standard_transaction_gas_limit = 350_000_000 +install_upgrade_gas_limit = 3_500_000_000_000 +standard_transaction_gas_limit = 500_000_000_000 [system_costs.auction_costs] get_era_validators = 10_000 diff --git a/resources/production/chainspec.toml b/resources/production/chainspec.toml index 426ae281d7..70d713659f 100644 --- a/resources/production/chainspec.toml +++ b/resources/production/chainspec.toml @@ -297,8 +297,8 @@ max_topics_per_contract = 128 max_message_size = 1_024 [system_costs] -install_upgrade_gas_limit = 0 -standard_transaction_gas_limit = 0 +install_upgrade_gas_limit = 3_500_000_000_000 +standard_transaction_gas_limit = 500_000_000_000 [system_costs.auction_costs] get_era_validators = 10_000 diff --git a/storage/src/system/auction/auction_native.rs b/storage/src/system/auction/auction_native.rs index bd96b363ef..379fb67960 100644 --- a/storage/src/system/auction/auction_native.rs +++ b/storage/src/system/auction/auction_native.rs @@ -142,7 +142,6 @@ where } Ok(None) => Ok(None), Err(TrackingCopyError::BytesRepr(_)) => Err(Error::Serialization), - Err(TrackingCopyError::GasLimit) => Err(Error::GasLimit), Err(err) => { error!("StorageProvider::read_bid: {:?}", err); Err(Error::Storage) @@ -174,7 +173,6 @@ where } Ok(None) => Ok(Vec::new()), Err(TrackingCopyError::BytesRepr(_)) => Err(Error::Serialization), - Err(TrackingCopyError::GasLimit) => Err(Error::GasLimit), Err(err) => { error!("StorageProvider::read_unbonds: {:?}", err); Err(Error::Storage) diff --git a/storage/src/tracking_copy/error.rs b/storage/src/tracking_copy/error.rs index c17f3d5ad1..818bf84ac6 100644 --- a/storage/src/tracking_copy/error.rs +++ b/storage/src/tracking_copy/error.rs @@ -27,9 +27,6 @@ pub enum Error { /// Type mismatch error. #[error("{}", _0)] TypeMismatch(StoredValueTypeMismatch), - /// Execution exceeded the gas limit. - #[error("Out of gas error")] - GasLimit, /// ApiError. #[error("{}", _0)] Api(ApiError), diff --git a/types/src/chainspec/vm_config/system_config.rs b/types/src/chainspec/vm_config/system_config.rs index ffed53d044..dcc1787127 100644 --- a/types/src/chainspec/vm_config/system_config.rs +++ b/types/src/chainspec/vm_config/system_config.rs @@ -13,10 +13,10 @@ use crate::{ }; /// Default gas limit of install / upgrade contracts -pub const DEFAULT_INSTALL_UPGRADE_GAS_LIMIT: u32 = 3_500_000_000; +pub const DEFAULT_INSTALL_UPGRADE_GAS_LIMIT: u64 = 3_500_000_000_000; /// Default gas limit of standard transactions -pub const DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT: u32 = 350_000_000; +pub const DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT: u64 = 500_000_000_000; /// Definition of costs in the system. /// @@ -27,10 +27,10 @@ pub const DEFAULT_STANDARD_TRANSACTION_GAS_LIMIT: u32 = 350_000_000; #[serde(deny_unknown_fields)] pub struct SystemConfig { /// Standard transaction gas limit expressed in gas. - standard_transaction_gas_limit: u32, + standard_transaction_gas_limit: u64, /// Install or upgrade transaction gas limit expressed in gas. - install_upgrade_gas_limit: u32, + install_upgrade_gas_limit: u64, /// Configuration of auction entrypoint costs. auction_costs: AuctionCosts, @@ -48,8 +48,8 @@ pub struct SystemConfig { impl SystemConfig { /// Creates new system config instance. pub fn new( - install_upgrade_gas_limit: u32, - standard_transaction_gas_limit: u32, + install_upgrade_gas_limit: u64, + standard_transaction_gas_limit: u64, auction_costs: AuctionCosts, mint_costs: MintCosts, handle_payment_costs: HandlePaymentCosts, @@ -66,12 +66,12 @@ impl SystemConfig { } /// Returns install / upgrade cost. - pub fn install_upgrade_limit(&self) -> u32 { + pub fn install_upgrade_limit(&self) -> u64 { self.install_upgrade_gas_limit } /// Returns standard / flat cost. - pub fn standard_transaction_limit(&self) -> u32 { + pub fn standard_transaction_limit(&self) -> u64 { self.standard_transaction_gas_limit } @@ -191,8 +191,8 @@ pub mod gens { prop_compose! { pub fn system_config_arb()( - install_upgrade_gas_limit in num::u32::ANY, - standard_transaction_gas_limit in num::u32::ANY, + install_upgrade_gas_limit in num::u64::ANY, + standard_transaction_gas_limit in num::u64::ANY, auction_costs in auction_costs_arb(), mint_costs in mint_costs_arb(), handle_payment_costs in handle_payment_costs_arb(), diff --git a/types/src/transaction/deploy.rs b/types/src/transaction/deploy.rs index 035f989f4d..78eb6d3bf2 100644 --- a/types/src/transaction/deploy.rs +++ b/types/src/transaction/deploy.rs @@ -1193,7 +1193,7 @@ impl GasLimited for Deploy { PricingHandling::Fixed => { // in fixed, the computation limit is fixed per the chainspec settings let computation_limit = if self.is_transfer() { - costs.mint_costs().transfer + costs.mint_costs().transfer as u64 } else { costs.standard_transaction_limit() }; diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index d1777a2a87..d3e9252122 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -641,10 +641,10 @@ impl GasLimited for TransactionV1 { // in the future (such as the upcoming burn feature), // this logic will need to be expanded to self.mint_costs().field? // for the value for each verb...see how auction is set up below. - costs.mint_costs().transfer + costs.mint_costs().transfer as u64 } else if self.is_native_auction() { let entry_point = self.body().entry_point(); - match entry_point { + let amount = match entry_point { TransactionEntryPoint::Custom(_) | TransactionEntryPoint::Transfer => { return Err(InvalidTransactionV1::EntryPointCannotBeCustom { entry_point: entry_point.clone(), @@ -659,7 +659,8 @@ impl GasLimited for TransactionV1 { TransactionEntryPoint::Delegate => costs.auction_costs().delegate, TransactionEntryPoint::Undelegate => costs.auction_costs().undelegate, TransactionEntryPoint::Redelegate => costs.auction_costs().redelegate, - } + }; + amount as u64 } else if self.is_install_or_upgrade() { costs.install_upgrade_limit() } else { From 550b1ec323bf5b62c664498339c4eac9a46ff5ac Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Wed, 27 Mar 2024 22:47:07 -0700 Subject: [PATCH 52/70] fixing feature based imports, added random() for transaction config --- .../components/transaction_buffer/tests.rs | 10 ++++++ resources/test/sse_data_schema.json | 8 ++--- types/src/chainspec.rs | 2 +- .../src/chainspec/vm_config/system_config.rs | 32 +++++++++++++++++-- types/src/transaction/transaction_v1.rs | 9 ++++-- utils/validation/tests/fixtures/ABI/key.json | 2 +- .../tests/fixtures/ABI/stored_value.json | 30 ++--------------- 7 files changed, 54 insertions(+), 39 deletions(-) diff --git a/node/src/components/transaction_buffer/tests.rs b/node/src/components/transaction_buffer/tests.rs index 437862f0ec..5d6e1d7191 100644 --- a/node/src/components/transaction_buffer/tests.rs +++ b/node/src/components/transaction_buffer/tests.rs @@ -356,6 +356,7 @@ fn get_appendable_block_when_transfers_are_of_one_category() { block_max_install_upgrade_count: 0, block_max_standard_count: 10, block_max_approval_count: 210, + block_gas_limit: u64::MAX, // making sure this test does not hit gas limit first ..Default::default() }; @@ -386,6 +387,7 @@ fn get_appendable_block_when_transfers_are_both_legacy_and_v1() { block_max_install_upgrade_count: 0, block_max_standard_count: 10, block_max_approval_count: 210, + block_gas_limit: u64::MAX, // making sure this test does not hit gas limit first ..Default::default() }; @@ -417,6 +419,7 @@ fn get_appendable_block_when_standards_are_of_one_category() { block_max_install_upgrade_count: 0, block_max_standard_count: 10, block_max_approval_count: 210, + block_gas_limit: u64::MAX, // making sure this test does not hit gas limit first ..Default::default() }; @@ -446,6 +449,7 @@ fn get_appendable_block_when_standards_are_both_legacy_and_v1() { block_max_install_upgrade_count: 0, block_max_standard_count: 10, block_max_approval_count: 210, + block_gas_limit: u64::MAX, // making sure this test does not hit gas limit first ..Default::default() }; let chainspec = Chainspec { @@ -485,6 +489,7 @@ fn block_fully_saturated() { block_max_install_upgrade_count: max_install_upgrade, block_max_standard_count: max_standard, block_max_approval_count: 210, + block_gas_limit: u64::MAX, // making sure this test does not hit gas limit first ..Default::default() }; @@ -585,6 +590,7 @@ fn block_not_fully_saturated() { block_max_install_upgrade_count: max_install_upgrade, block_max_standard_count: max_standard, block_max_approval_count: 210, + block_gas_limit: u64::MAX, // making sure this test does not hit gas limit first ..Default::default() }; @@ -689,6 +695,7 @@ fn excess_transactions_do_not_sneak_into_transfer_bucket() { block_max_install_upgrade_count: max_install_upgrade, block_max_standard_count: max_standard, block_max_approval_count: 210, + block_gas_limit: u64::MAX, // making sure this test does not hit gas limit first ..Default::default() }; @@ -753,6 +760,7 @@ fn excess_transactions_do_not_sneak_into_staking_bucket() { block_max_install_upgrade_count: max_install_upgrade, block_max_standard_count: max_standard, block_max_approval_count: 210, + block_gas_limit: u64::MAX, // making sure this test does not hit gas limit first ..Default::default() }; @@ -817,6 +825,7 @@ fn excess_transactions_do_not_sneak_into_install_upgrades_bucket() { block_max_install_upgrade_count: max_install_upgrade, block_max_standard_count: max_standard, block_max_approval_count: 210, + block_gas_limit: u64::MAX, // making sure this test does not hit gas limit first ..Default::default() }; @@ -881,6 +890,7 @@ fn excess_transactions_do_not_sneak_into_standards_bucket() { block_max_install_upgrade_count: max_install_upgrade, block_max_standard_count: max_standard, block_max_approval_count: 210, + block_gas_limit: u64::MAX, // making sure this test does not hit gas limit first ..Default::default() }; diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index 23a1d64251..f9f9c1f557 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -1714,11 +1714,9 @@ }, "paid_amount": { "description": "Price paid in the past to reserve space in a future block.", - "allOf": [ - { - "$ref": "#/definitions/U512" - } - ] + "type": "integer", + "format": "uint64", + "minimum": 0.0 }, "strike_price": { "description": "The gas price at the time of reservation.", diff --git a/types/src/chainspec.rs b/types/src/chainspec.rs index 8b33ef08b1..024412dd02 100644 --- a/types/src/chainspec.rs +++ b/types/src/chainspec.rs @@ -219,7 +219,7 @@ impl Chainspec { let highway_config = HighwayConfig::random(rng); let transaction_config = TransactionConfig::random(rng); let wasm_config = rng.gen(); - let system_costs_config = rng.gen(); + let system_costs_config = SystemConfig::random(rng); let vacancy_config = VacancyConfig::random(rng); Chainspec { diff --git a/types/src/chainspec/vm_config/system_config.rs b/types/src/chainspec/vm_config/system_config.rs index dcc1787127..d345f2f736 100644 --- a/types/src/chainspec/vm_config/system_config.rs +++ b/types/src/chainspec/vm_config/system_config.rs @@ -1,3 +1,5 @@ +#[cfg(any(feature = "testing", test))] +use crate::testing::TestRng; #[cfg(feature = "datasize")] use datasize::DataSize; #[cfg(any(feature = "testing", test))] @@ -102,6 +104,30 @@ impl SystemConfig { } } +#[cfg(any(feature = "testing", test))] +impl SystemConfig { + /// Generates a random instance using a `TestRng`. + pub fn random(rng: &mut TestRng) -> Self { + // there's a bug in toml...under the hood it uses an i64 when it should use a u64 + // this causes flaky test failures if the random result exceeds i64::MAX + let install_upgrade_gas_limit = rng.gen::() as u64; + let standard_transaction_gas_limit = rng.gen::() as u64; + let auction_costs = rng.gen(); + let mint_costs = rng.gen(); + let handle_payment_costs = rng.gen(); + let standard_payment_costs = rng.gen(); + + SystemConfig { + install_upgrade_gas_limit, + standard_transaction_gas_limit, + auction_costs, + mint_costs, + handle_payment_costs, + standard_payment_costs, + } + } +} + impl Default for SystemConfig { fn default() -> Self { Self { @@ -191,13 +217,15 @@ pub mod gens { prop_compose! { pub fn system_config_arb()( - install_upgrade_gas_limit in num::u64::ANY, - standard_transaction_gas_limit in num::u64::ANY, + install_upgrade_gas_limit in num::u32::ANY, + standard_transaction_gas_limit in num::u32::ANY, auction_costs in auction_costs_arb(), mint_costs in mint_costs_arb(), handle_payment_costs in handle_payment_costs_arb(), standard_payment_costs in standard_payment_costs_arb(), ) -> SystemConfig { + let install_upgrade_gas_limit = install_upgrade_gas_limit as u64; + let standard_transaction_gas_limit =standard_transaction_gas_limit as u64; SystemConfig { install_upgrade_gas_limit, standard_transaction_gas_limit, diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index d3e9252122..b638b37c78 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -36,8 +36,9 @@ use crate::{ crypto, Digest, DisplayIter, RuntimeArgs, SecretKey, TimeDiff, Timestamp, TransactionRuntime, TransactionSessionKind, }; -#[cfg(any(all(feature = "std", feature = "testing"), test))] -use crate::{chainspec::PricingHandling, testing::TestRng, Chainspec}; +#[cfg(any(feature = "std", test))] +use crate::{chainspec::Chainspec, chainspec::PricingHandling}; + #[cfg(any(feature = "std", test))] use crate::{Gas, Motes, TransactionConfig, U512}; pub use errors_v1::{ @@ -52,6 +53,9 @@ pub use transaction_v1_category::TransactionCategory; pub use transaction_v1_hash::TransactionV1Hash; pub use transaction_v1_header::TransactionV1Header; +#[cfg(any(all(feature = "std", feature = "testing"), test))] +use crate::testing::TestRng; + /// A unit of work sent by a client to the network, which when executed can cause global state to /// be altered. /// @@ -1312,6 +1316,7 @@ mod tests { reserved_pricing(500u64, 2u8); } + #[cfg(test)] fn reserved_pricing(paid_amount: u64, strike_price: u8) { let mut chainspec = Chainspec::default(); let chain_name = "net-1"; diff --git a/utils/validation/tests/fixtures/ABI/key.json b/utils/validation/tests/fixtures/ABI/key.json index 60ce6b65c0..ee52ae10d4 100644 --- a/utils/validation/tests/fixtures/ABI/key.json +++ b/utils/validation/tests/fixtures/ABI/key.json @@ -159,7 +159,7 @@ "value": "bid-addr-00306633f962155a7d46658adb36143f28668f530454fe788c927cecf62e5964a1" } ], - "output": "0f306633f962155a7d46658adb36143f28668f530454fe788c927cecf62e5964a1" + "output": "0f00306633f962155a7d46658adb36143f28668f530454fe788c927cecf62e5964a1" }, "WriteValidatorBid": { "input": [ diff --git a/utils/validation/tests/fixtures/ABI/stored_value.json b/utils/validation/tests/fixtures/ABI/stored_value.json index ef1e2148af..8aedc86b66 100644 --- a/utils/validation/tests/fixtures/ABI/stored_value.json +++ b/utils/validation/tests/fixtures/ABI/stored_value.json @@ -173,8 +173,8 @@ "DeployInfo": { "deploy_hash": "3737373737373737373737373737373737373737373737373737373737373737", "transfers": [ - "transfer-v1-0101010101010101010101010101010101010101010101010101010101010101", - "transfer-v1-0202020202020202020202020202020202020202020202020202020202020202" + "transfer-0101010101010101010101010101010101010101010101010101010101010101", + "transfer-0202020202020202020202020202020202020202020202020202020202020202" ], "from": "account-hash-6464646464646464646464646464646464646464646464646464646464646464", "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007", @@ -280,32 +280,6 @@ ], "output": "0c2727272727272727272727272727272727272727272727272727272727272727010200000001000000010000006464646464646464646464646464646464646464646464646464646464646464010000000200000063636363636363636363636363636363636363636363636363636363636363630100000001000000010000000200000005000000456d707479000000000600000053696e676c650100000037373737373737373737373737373737373737373737373737373737373737370101" }, - "Transfer": { - "input": [ - { - "type": "StoredValue", - "value": { - "Transfer": { - "Version2": { - "transaction_hash": { - "Version1": "2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c" - }, - "from": { - "AccountHash": "account-hash-6464646464646464646464646464646464646464646464646464646464646464" - }, - "to": "account-hash-6565656565656565656565656565656565656565656565656565656565656565", - "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-002", - "target": "uref-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b-002", - "amount": "15000000000", - "gas": "2500000000", - "id": 1 - } - } - } - } - ], - "output": "1301012c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c0164646464646464646464646464646464646464646464646464646464646464640165656565656565656565656565656565656565656565656565656565656565650a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a020b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b020500d6117e030400f90295010100000000000000" - }, "Unbonding": { "input": [ { From 6992496f02103eb291e63fbd9520abbf28119bf6 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Thu, 28 Mar 2024 02:11:14 -0700 Subject: [PATCH 53/70] tightening up holds, adding HoldsEpoch newtype, fixing faucet costs --- .../src/runtime/auction_internal.rs | 8 +-- .../src/runtime/handle_payment_internal.rs | 4 +- execution_engine/src/runtime/mint_internal.rs | 5 +- execution_engine/src/runtime/mod.rs | 26 ++++---- execution_engine/src/runtime_context/mod.rs | 10 ++-- execution_engine/src/runtime_context/tests.rs | 4 +- .../test_support/src/chainspec_config.rs | 19 ++++-- .../test_support/src/deploy_item_builder.rs | 2 +- .../src/execute_request_builder.rs | 12 ++-- .../test_support/src/lib.rs | 7 +-- .../src/transfer_request_builder.rs | 11 ++-- .../test_support/src/wasm_test_builder.rs | 30 +++++----- .../tests/src/test/check_transfer_success.rs | 6 +- .../contract_api/account/authorized_keys.rs | 16 ++--- .../account/key_management_thresholds.rs | 2 +- .../tests/src/test/contract_api/dictionary.rs | 2 +- .../contract_api/list_authorization_keys.rs | 2 +- .../contract_api/multisig_authorization.rs | 2 +- .../src/test/deploy/context_association.rs | 2 +- .../tests/src/test/deploy/preconditions.rs | 6 +- .../tests/src/test/deploy/stored_contracts.rs | 2 +- .../tests/src/test/explorer/faucet.rs | 21 ++++--- .../src/test/explorer/faucet_test_helpers.rs | 2 +- .../tests/src/test/gas_counter.rs | 4 +- .../tests/src/test/groups.rs | 18 +++--- .../src/test/private_chain/management.rs | 8 +-- .../tests/src/test/regression/ee_1129.rs | 12 ++-- .../tests/src/test/regression/ee_441.rs | 2 +- .../tests/src/test/regression/ee_550.rs | 4 +- .../tests/src/test/regression/ee_598.rs | 2 +- .../tests/src/test/regression/ee_890.rs | 2 +- .../tests/src/test/regression/ee_966.rs | 2 +- .../tests/src/test/regression/gh_1688.rs | 8 +-- .../tests/src/test/regression/gh_1902.rs | 8 +-- .../tests/src/test/regression/gh_2280.rs | 20 +++---- .../tests/src/test/regression/gh_3208.rs | 6 +- .../tests/src/test/regression/gov_42.rs | 2 +- ...host_function_metrics_size_and_gas_cost.rs | 4 +- .../test/regression/regression_20210924.rs | 4 +- .../test/regression/regression_20211110.rs | 4 +- .../regression/transforms_must_be_ordered.rs | 2 +- .../system_contracts/auction/distribute.rs | 6 +- .../test/system_contracts/standard_payment.rs | 16 ++--- .../tests/src/test/system_costs.rs | 2 +- .../components/contract_runtime/operations.rs | 25 +++++--- node/src/components/transaction_acceptor.rs | 12 ++-- resources/local/chainspec.toml.in | 2 +- storage/src/data_access_layer/auction.rs | 14 ++--- storage/src/data_access_layer/balance.rs | 17 +++--- storage/src/data_access_layer/balance_hold.rs | 34 +++++------ storage/src/data_access_layer/fee.rs | 9 +-- .../src/data_access_layer/handle_payment.rs | 20 ++++++- storage/src/data_access_layer/mint.rs | 12 ++-- storage/src/global_state/state/mod.rs | 33 ++++++++--- storage/src/system/auction.rs | 6 +- storage/src/system/auction/auction_native.rs | 8 +-- storage/src/system/auction/detail.rs | 8 +-- storage/src/system/auction/providers.rs | 6 +- storage/src/system/handle_payment.rs | 4 +- .../handle_payment/handle_payment_native.rs | 17 ++++-- storage/src/system/handle_payment/internal.rs | 8 +-- .../system/handle_payment/mint_provider.rs | 4 +- storage/src/system/mint.rs | 16 +++-- storage/src/system/mint/mint_native.rs | 6 +- storage/src/system/mint/storage_provider.rs | 4 +- storage/src/system/transfer.rs | 6 +- storage/src/tracking_copy/ext.rs | 59 ++++++++++++++----- types/src/block_time.rs | 35 ++++++++++- types/src/chainspec/pricing_handling.rs | 4 +- types/src/lib.rs | 10 ++-- 70 files changed, 419 insertions(+), 297 deletions(-) diff --git a/execution_engine/src/runtime/auction_internal.rs b/execution_engine/src/runtime/auction_internal.rs index d0f26285cf..593876e602 100644 --- a/execution_engine/src/runtime/auction_internal.rs +++ b/execution_engine/src/runtime/auction_internal.rs @@ -16,7 +16,7 @@ use casper_types::{ auction::{BidAddr, BidKind, EraInfo, Error, UnbondingPurse}, mint, }, - CLTyped, CLValue, Key, KeyTag, PublicKey, RuntimeArgs, StoredValue, URef, U512, + CLTyped, CLValue, HoldsEpoch, Key, KeyTag, PublicKey, RuntimeArgs, StoredValue, URef, U512, }; use super::Runtime; @@ -244,7 +244,7 @@ where contract.main_purse(), *unbonding_purse.amount(), None, - None, + HoldsEpoch::NOT_APPLICABLE, ) .map_err(|_| Error::Transfer)? .map_err(|_| Error::Transfer)?; @@ -265,7 +265,7 @@ where target: URef, amount: U512, id: Option, - _holds_epoch: Option, + _holds_epoch: HoldsEpoch, ) -> Result, Error> { if !(self.context.entity().main_purse().addr() == source.addr() || self.context.get_caller() == PublicKey::System.to_account_hash()) @@ -345,7 +345,7 @@ where fn available_balance( &mut self, purse: URef, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result, Error> { Runtime::available_balance(self, purse, holds_epoch) .map_err(|exec_error| >::from(exec_error).unwrap_or(Error::GetBalance)) diff --git a/execution_engine/src/runtime/handle_payment_internal.rs b/execution_engine/src/runtime/handle_payment_internal.rs index 5020850272..0284d17d06 100644 --- a/execution_engine/src/runtime/handle_payment_internal.rs +++ b/execution_engine/src/runtime/handle_payment_internal.rs @@ -3,7 +3,7 @@ use std::collections::BTreeSet; use casper_types::{ account::AccountHash, addressable_entity::NamedKeyAddr, system::handle_payment::Error, CLValue, - FeeHandling, Key, Phase, RefundHandling, StoredValue, TransferredTo, URef, U512, + FeeHandling, HoldsEpoch, Key, Phase, RefundHandling, StoredValue, TransferredTo, URef, U512, }; use casper_storage::system::handle_payment::{ @@ -66,7 +66,7 @@ where fn available_balance( &mut self, purse: URef, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result, Error> { Runtime::available_balance(self, purse, holds_epoch) .map_err(|exec_error| >::from(exec_error).unwrap_or(Error::GetBalance)) diff --git a/execution_engine/src/runtime/mint_internal.rs b/execution_engine/src/runtime/mint_internal.rs index db7a5937f8..9bbeb0e079 100644 --- a/execution_engine/src/runtime/mint_internal.rs +++ b/execution_engine/src/runtime/mint_internal.rs @@ -14,7 +14,8 @@ use casper_types::{ account::AccountHash, bytesrepr::{FromBytes, ToBytes}, system::{mint::Error, Caller}, - AddressableEntity, CLTyped, CLValue, Key, Phase, StoredValue, SystemEntityRegistry, URef, U512, + AddressableEntity, CLTyped, CLValue, HoldsEpoch, Key, Phase, StoredValue, SystemEntityRegistry, + URef, U512, }; use super::Runtime; @@ -143,7 +144,7 @@ where fn available_balance( &mut self, purse: URef, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result, Error> { Runtime::available_balance(self, purse, holds_epoch) .map_err(|exec_error| >::from(exec_error).unwrap_or(Error::Storage)) diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index 8b8a894f67..2b2ea44e9c 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -50,7 +50,7 @@ use casper_types::{ }, AccessRights, ApiError, BlockTime, ByteCode, ByteCodeAddr, ByteCodeHash, ByteCodeKind, CLTyped, CLValue, ContextAccessRights, ContractWasm, EntityAddr, EntityKind, EntityVersion, - EntityVersionKey, EntityVersions, Gas, GrantedAccess, Group, Groups, HostFunction, + EntityVersionKey, EntityVersions, Gas, GrantedAccess, Group, Groups, HoldsEpoch, HostFunction, HostFunctionCost, InitiatorAddr, Key, NamedArg, Package, PackageHash, PackageStatus, Phase, PublicKey, RuntimeArgs, StoredValue, Tagged, Transfer, TransferResult, TransferV2, TransferredTo, URef, DICTIONARY_ITEM_KEY_MAX_LENGTH, U512, @@ -555,11 +555,11 @@ where } /// Returns holds epoch. - fn holds_epoch(&self) -> u64 { - self.context - .get_blocktime() - .value() - .saturating_sub(self.context.engine_config().balance_hold_interval.millis()) + fn holds_epoch(&self) -> HoldsEpoch { + HoldsEpoch::from_block_time( + self.context.get_blocktime(), + self.context.engine_config().balance_hold_interval, + ) } /// Calls host mint contract. @@ -628,7 +628,7 @@ where mint_runtime.charge_system_contract_call(mint_costs.balance)?; let uref: URef = Self::get_named_argument(runtime_args, mint::ARG_PURSE)?; - let holds_epoch = Some(self.holds_epoch()); + let holds_epoch = self.holds_epoch(); let maybe_balance: Option = mint_runtime .balance(uref, holds_epoch) @@ -646,7 +646,7 @@ where let target: URef = Self::get_named_argument(runtime_args, mint::ARG_TARGET)?; let amount: U512 = Self::get_named_argument(runtime_args, mint::ARG_AMOUNT)?; let id: Option = Self::get_named_argument(runtime_args, mint::ARG_ID)?; - let holds_epoch = Some(self.holds_epoch()); + let holds_epoch = self.holds_epoch(); let result: Result<(), mint::Error> = mint_runtime.transfer(maybe_to, source, target, amount, id, holds_epoch); @@ -832,7 +832,7 @@ where let delegation_rate = Self::get_named_argument(runtime_args, auction::ARG_DELEGATION_RATE)?; let amount = Self::get_named_argument(runtime_args, auction::ARG_AMOUNT)?; - let holds_epoch = Some(self.holds_epoch()); + let holds_epoch = self.holds_epoch(); let result = runtime .add_bid(account_hash, delegation_rate, amount, holds_epoch) @@ -864,7 +864,7 @@ where self.context.engine_config().max_delegators_per_validator(); let minimum_delegation_amount = self.context.engine_config().minimum_delegation_amount(); - let holds_epoch = Some(self.holds_epoch()); + let holds_epoch = self.holds_epoch(); let result = runtime .delegate( delegator, @@ -2435,7 +2435,7 @@ where return Err(ExecError::DisabledUnrestrictedTransfers); } - let holds_epoch = Some(self.holds_epoch()); + let holds_epoch = self.holds_epoch(); // A precondition check that verifies that the transfer can be done // as the source purse has enough funds to cover the transfer. if amount @@ -2694,7 +2694,7 @@ where fn available_balance( &mut self, purse: URef, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result, ExecError> { match self.context.available_balance(&purse, holds_epoch) { Ok(motes) => Ok(Some(motes.value())), @@ -2721,7 +2721,7 @@ where } }; - let balance = match self.available_balance(purse, Some(self.holds_epoch()))? { + let balance = match self.available_balance(purse, self.holds_epoch())? { Some(balance) => balance, None => return Ok(Err(ApiError::InvalidPurse)), }; diff --git a/execution_engine/src/runtime_context/mod.rs b/execution_engine/src/runtime_context/mod.rs index 7ae2e3fe52..59fc793d2e 100644 --- a/execution_engine/src/runtime_context/mod.rs +++ b/execution_engine/src/runtime_context/mod.rs @@ -31,10 +31,10 @@ use casper_types::{ handle_stored_dictionary_value, system::auction::EraInfo, AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, CLType, CLValue, - CLValueDictionary, ContextAccessRights, EntityAddr, EntryPointType, Gas, GrantedAccess, Key, - KeyTag, Motes, Package, PackageHash, Phase, ProtocolVersion, PublicKey, RuntimeArgs, - StoredValue, StoredValueTypeMismatch, SystemEntityRegistry, TransactionHash, Transfer, URef, - URefAddr, DICTIONARY_ITEM_KEY_MAX_LENGTH, KEY_HASH_LENGTH, U512, + CLValueDictionary, ContextAccessRights, EntityAddr, EntryPointType, Gas, GrantedAccess, + HoldsEpoch, Key, KeyTag, Motes, Package, PackageHash, Phase, ProtocolVersion, PublicKey, + RuntimeArgs, StoredValue, StoredValueTypeMismatch, SystemEntityRegistry, TransactionHash, + Transfer, URef, URefAddr, DICTIONARY_ITEM_KEY_MAX_LENGTH, KEY_HASH_LENGTH, U512, }; use crate::{engine_state::EngineConfig, execution::ExecError}; @@ -428,7 +428,7 @@ where pub(crate) fn available_balance( &mut self, purse_uref: &URef, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result { let key = Key::URef(*purse_uref); self.tracking_copy diff --git a/execution_engine/src/runtime_context/tests.rs b/execution_engine/src/runtime_context/tests.rs index 52f9977299..21e82b2d20 100644 --- a/execution_engine/src/runtime_context/tests.rs +++ b/execution_engine/src/runtime_context/tests.rs @@ -18,7 +18,7 @@ use casper_types::{ execution::TransformKindV2, system::{AUCTION, HANDLE_PAYMENT, MINT, STANDARD_PAYMENT}, AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, ByteCodeHash, CLValue, - ContextAccessRights, EntityAddr, EntityKind, EntryPointType, EntryPoints, Gas, Key, + ContextAccessRights, EntityAddr, EntityKind, EntryPointType, EntryPoints, Gas, HoldsEpoch, Key, PackageHash, Phase, ProtocolVersion, PublicKey, RuntimeArgs, SecretKey, StoredValue, SystemEntityRegistry, Tagged, TransactionHash, TransactionV1Hash, URef, KEY_HASH_LENGTH, U256, U512, @@ -846,7 +846,7 @@ fn can_roundtrip_key_value_pairs() { .expect("should write_ls"); let result = runtime_context - .available_balance(&test_uref, None) + .available_balance(&test_uref, HoldsEpoch::NOT_APPLICABLE) .expect("should read_ls"); let actual = CLValue::from_t(result.value()).unwrap(); diff --git a/execution_engine_testing/test_support/src/chainspec_config.rs b/execution_engine_testing/test_support/src/chainspec_config.rs index 617ea3c338..eaa943d45a 100644 --- a/execution_engine_testing/test_support/src/chainspec_config.rs +++ b/execution_engine_testing/test_support/src/chainspec_config.rs @@ -12,8 +12,8 @@ use casper_execution_engine::engine_state::{EngineConfig, EngineConfigBuilder}; use casper_storage::data_access_layer::GenesisRequest; use casper_types::{ system::auction::VESTING_SCHEDULE_LENGTH_MILLIS, CoreConfig, FeeHandling, GenesisAccount, - GenesisConfig, GenesisConfigBuilder, MintCosts, ProtocolVersion, RefundHandling, SystemConfig, - TimeDiff, WasmConfig, + GenesisConfig, GenesisConfigBuilder, MintCosts, PricingHandling, ProtocolVersion, + RefundHandling, SystemConfig, TimeDiff, WasmConfig, }; use crate::{ @@ -24,8 +24,8 @@ use crate::{ /// The name of the chainspec file on disk. pub const CHAINSPEC_NAME: &str = "chainspec.toml"; -/// Path to the production chainspec used in the Casper mainnet. -pub static PRODUCTION_PATH: Lazy = Lazy::new(|| { +/// Symlink to chainspec. +pub static CHAINSPEC_SYMLINK: Lazy = Lazy::new(|| { PathBuf::from(env!("CARGO_MANIFEST_DIR")) .join("resources/") .join(CHAINSPEC_NAME) @@ -81,7 +81,8 @@ impl ChainspecConfig { ChainspecConfig::from_bytes(&bytes) } - pub(crate) fn from_chainspec_path>(filename: P) -> Result { + /// Load from path. + pub fn from_chainspec_path>(filename: P) -> Result { Self::from_path(filename) } @@ -148,7 +149,7 @@ impl ChainspecConfig { protocol_version: ProtocolVersion, ) -> Result { Self::create_genesis_request_from_chainspec( - &*PRODUCTION_PATH, + &*CHAINSPEC_SYMLINK, genesis_accounts, protocol_version, ) @@ -208,6 +209,12 @@ impl ChainspecConfig { self } + /// Sets pricing handling config option. + pub fn with_pricing_handling(mut self, pricing_handling: PricingHandling) -> Self { + self.core_config.pricing_handling = pricing_handling; + self + } + /// Sets strict argument checking. pub fn with_strict_argument_checking(mut self, strict_argument_checking: bool) -> Self { self.core_config.strict_argument_checking = strict_argument_checking; diff --git a/execution_engine_testing/test_support/src/deploy_item_builder.rs b/execution_engine_testing/test_support/src/deploy_item_builder.rs index 05c4303ea7..78b619e26c 100644 --- a/execution_engine_testing/test_support/src/deploy_item_builder.rs +++ b/execution_engine_testing/test_support/src/deploy_item_builder.rs @@ -51,7 +51,7 @@ impl DeployItemBuilder { } /// Sets the payment bytes of the deploy to an empty Vec. - pub fn with_empty_payment_bytes(self, args: RuntimeArgs) -> Self { + pub fn with_standard_payment(self, args: RuntimeArgs) -> Self { self.with_payment_bytes(vec![], args) } diff --git a/execution_engine_testing/test_support/src/execute_request_builder.rs b/execution_engine_testing/test_support/src/execute_request_builder.rs index b684663ed5..828b0f0724 100644 --- a/execution_engine_testing/test_support/src/execute_request_builder.rs +++ b/execution_engine_testing/test_support/src/execute_request_builder.rs @@ -149,7 +149,7 @@ impl<'a> ExecuteRequestBuilder<'a> { let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(session_file, session_args) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }) .with_authorization_keys(&[account_hash]) @@ -166,7 +166,7 @@ impl<'a> ExecuteRequestBuilder<'a> { let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_bytes(module_bytes, session_args) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }) .with_authorization_keys(&[account_hash]) @@ -185,7 +185,7 @@ impl<'a> ExecuteRequestBuilder<'a> { let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_hash(contract_hash, entry_point, args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[sender]) .build(); Self::from_deploy_item(Box::leak(Box::new(deploy_item))) @@ -202,7 +202,7 @@ impl<'a> ExecuteRequestBuilder<'a> { let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_named_key(contract_name, entry_point, args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[sender]) .build(); Self::from_deploy_item(Box::leak(Box::new(deploy_item))) @@ -225,7 +225,7 @@ impl<'a> ExecuteRequestBuilder<'a> { entry_point_name, args, ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[sender]) .build(); Self::from_deploy_item(Box::leak(Box::new(deploy_item))) @@ -243,7 +243,7 @@ impl<'a> ExecuteRequestBuilder<'a> { let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_versioned_contract_by_name(contract_name, version, entry_point_name, args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[sender]) .build(); Self::from_deploy_item(Box::leak(Box::new(deploy_item))) diff --git a/execution_engine_testing/test_support/src/lib.rs b/execution_engine_testing/test_support/src/lib.rs index dd2e443fd4..fd90f4dcd1 100644 --- a/execution_engine_testing/test_support/src/lib.rs +++ b/execution_engine_testing/test_support/src/lib.rs @@ -28,8 +28,7 @@ use casper_types::{ SystemConfig, WasmConfig, U512, }; -pub use chainspec_config::ChainspecConfig; -use chainspec_config::PRODUCTION_PATH; +pub use chainspec_config::{ChainspecConfig, CHAINSPEC_SYMLINK}; pub use deploy_item_builder::DeployItemBuilder; pub use execute_request_builder::{ExecuteRequest, ExecuteRequestBuilder}; pub use step_request_builder::StepRequestBuilder; @@ -172,7 +171,7 @@ pub static LOCAL_GENESIS_REQUEST: Lazy = Lazy::new(|| { }); /// Round seigniorage rate from the production chainspec. pub static PRODUCTION_ROUND_SEIGNIORAGE_RATE: Lazy> = Lazy::new(|| { - let chainspec = ChainspecConfig::from_chainspec_path(&*PRODUCTION_PATH) + let chainspec = ChainspecConfig::from_chainspec_path(&*CHAINSPEC_SYMLINK) .expect("must create chainspec_config"); chainspec.core_config.round_seigniorage_rate }); @@ -185,7 +184,7 @@ mod tests { #[test] fn defaults_should_match_production_chainspec_values() { - let production = ChainspecConfig::from_chainspec_path(&*PRODUCTION_PATH).unwrap(); + let production = ChainspecConfig::from_chainspec_path(&*CHAINSPEC_SYMLINK).unwrap(); // No need to test `CoreConfig::validator_slots`. assert_eq!(production.core_config.auction_delay, DEFAULT_AUCTION_DELAY); assert_eq!( diff --git a/execution_engine_testing/test_support/src/transfer_request_builder.rs b/execution_engine_testing/test_support/src/transfer_request_builder.rs index f156181189..7656a37957 100644 --- a/execution_engine_testing/test_support/src/transfer_request_builder.rs +++ b/execution_engine_testing/test_support/src/transfer_request_builder.rs @@ -17,8 +17,8 @@ use casper_types::{ account::AccountHash, bytesrepr::ToBytes, system::mint::{ARG_AMOUNT, ARG_ID, ARG_SOURCE, ARG_TARGET}, - BlockTime, CLValue, Digest, FeeHandling, Gas, InitiatorAddr, ProtocolVersion, RefundHandling, - RuntimeArgs, TransactionHash, TransactionV1Hash, TransferTarget, URef, + BlockTime, CLValue, Digest, FeeHandling, Gas, HoldsEpoch, InitiatorAddr, ProtocolVersion, + RefundHandling, RuntimeArgs, TransactionHash, TransactionV1Hash, TransferTarget, URef, DEFAULT_BALANCE_HOLD_INTERVAL, U512, }; @@ -155,11 +155,8 @@ impl TransferRequestBuilder { /// that this generated hash is not the same as what would have been generated on an actual /// `Transaction` for an equivalent request. pub fn build(self) -> TransferRequest { - let holds_epoch = Some( - self.block_time - .value() - .saturating_sub(self.config.balance_hold_interval()), - ); + let holds_epoch = + HoldsEpoch::from_millis(self.block_time.value(), self.config.balance_hold_interval()); let txn_hash = match self.transaction_hash { Some(txn_hash) => txn_hash, diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index 7361c8d18c..2aea4d2fae 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -61,13 +61,13 @@ use casper_types::{ }, AddressableEntity, AddressableEntityHash, AuctionCosts, BlockTime, ByteCode, ByteCodeAddr, ByteCodeHash, CLTyped, CLValue, Contract, Digest, EntityAddr, EraId, Gas, HandlePaymentCosts, - InitiatorAddr, Key, KeyTag, MintCosts, Motes, Package, PackageHash, ProtocolUpgradeConfig, - ProtocolVersion, PublicKey, RefundHandling, StoredValue, SystemEntityRegistry, TransactionHash, - TransactionV1Hash, URef, OS_PAGE_SIZE, U512, + HoldsEpoch, InitiatorAddr, Key, KeyTag, MintCosts, Motes, Package, PackageHash, + ProtocolUpgradeConfig, ProtocolVersion, PublicKey, RefundHandling, StoredValue, + SystemEntityRegistry, TransactionHash, TransactionV1Hash, URef, OS_PAGE_SIZE, U512, }; use crate::{ - chainspec_config::{ChainspecConfig, PRODUCTION_PATH}, + chainspec_config::{ChainspecConfig, CHAINSPEC_SYMLINK}, ExecuteRequest, ExecuteRequestBuilder, StepRequestBuilder, DEFAULT_GAS_PRICE, DEFAULT_PROPOSER_ADDR, DEFAULT_PROTOCOL_VERSION, SYSTEM_ADDR, }; @@ -240,7 +240,7 @@ pub type LmdbWasmTestBuilder = WasmTestBuilder> impl Default for LmdbWasmTestBuilder { fn default() -> Self { - Self::new_temporary_with_chainspec(&*PRODUCTION_PATH) + Self::new_temporary_with_chainspec(&*CHAINSPEC_SYMLINK) } } @@ -424,7 +424,7 @@ impl LmdbWasmTestBuilder { /// Returns an [`LmdbWasmTestBuilder`] with configuration and values from /// the production chainspec. pub fn new_with_production_chainspec + ?Sized>(data_dir: &T) -> Self { - Self::new_with_chainspec(data_dir, &*PRODUCTION_PATH) + Self::new_with_chainspec(data_dir, &*CHAINSPEC_SYMLINK) } /// Returns a new [`LmdbWasmTestBuilder`]. @@ -950,9 +950,11 @@ where block_time: u64, ) -> FeeResult { let native_runtime_config = self.native_runtime_config(); - let holds_epoch = Some( - block_time.saturating_sub(self.chainspec.core_config.balance_hold_interval.millis()), + let holds_epoch = HoldsEpoch::from_millis( + block_time, + self.chainspec.core_config.balance_hold_interval.millis(), ); + let pre_state_hash = pre_state_hash.or(self.post_state_hash).unwrap(); let fee_req = FeeRequest::new( native_runtime_config, @@ -1211,10 +1213,8 @@ where block_time: u64, ) -> BalanceResult { let hold_interval = self.chainspec.core_config.balance_hold_interval.millis(); - let balance_handling = BalanceHandling::Available { - block_time, - hold_interval, - }; + let holds_epoch = HoldsEpoch::from_millis(block_time, hold_interval); + let balance_handling = BalanceHandling::Available { holds_epoch }; let state_root_hash: Digest = self.post_state_hash.expect("should have post_state_hash"); let request = @@ -1231,10 +1231,8 @@ where ) -> BalanceResult { let state_root_hash: Digest = self.post_state_hash.expect("should have post_state_hash"); let hold_interval = self.chainspec.core_config.balance_hold_interval.millis(); - let balance_handling = BalanceHandling::Available { - block_time, - hold_interval, - }; + let holds_epoch = HoldsEpoch::from_millis(block_time, hold_interval); + let balance_handling = BalanceHandling::Available { holds_epoch }; let request = BalanceRequest::from_public_key( state_root_hash, protocol_version, diff --git a/execution_engine_testing/tests/src/test/check_transfer_success.rs b/execution_engine_testing/tests/src/test/check_transfer_success.rs index 821bc5fefa..da90701b71 100644 --- a/execution_engine_testing/tests/src/test/check_transfer_success.rs +++ b/execution_engine_testing/tests/src/test/check_transfer_success.rs @@ -48,7 +48,7 @@ fn test_check_transfer_success_with_source_only() { // build the deploy. let deploy_item = DeployItemBuilder::new() - .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT}) + .with_standard_payment(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT}) .with_session_code(path, session_args) .with_address(*DEFAULT_ACCOUNT_ADDR) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) @@ -111,7 +111,7 @@ fn test_check_transfer_success_with_source_only_errors() { }; let deploy_item = DeployItemBuilder::new() - .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT}) + .with_standard_payment(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT}) .with_session_code(path, session_args) .with_address(*DEFAULT_ACCOUNT_ADDR) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) @@ -168,7 +168,7 @@ fn test_check_transfer_success_with_source_and_target() { ARG_AMOUNT => transfer_amount }; let deploy_item = DeployItemBuilder::new() - .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT}) + .with_standard_payment(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT}) .with_session_code(path, session_args) .with_address(*DEFAULT_ACCOUNT_ADDR) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) diff --git a/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs b/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs index a7a7cbdca8..6b1d72896a 100644 --- a/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs +++ b/execution_engine_testing/tests/src/test/contract_api/account/authorized_keys.rs @@ -50,7 +50,7 @@ fn should_raise_auth_failure_with_invalid_key() { let deploy = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_session_code( CONTRACT_SET_ACTION_THRESHOLDS, runtime_args! { @@ -101,7 +101,7 @@ fn should_raise_auth_failure_with_invalid_keys() { let deploy = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_session_code( CONTRACT_SET_ACTION_THRESHOLDS, runtime_args! { @@ -199,7 +199,7 @@ fn should_raise_deploy_authorization_failure() { let deploy = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) // Next deploy will see deploy threshold == 4, keymgmnt == 5 .with_session_code( CONTRACT_SET_ACTION_THRESHOLDS, @@ -228,7 +228,7 @@ fn should_raise_deploy_authorization_failure() { } let deploy = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) // change deployment threshold to 4 .with_session_code( CONTRACT_SET_ACTION_THRESHOLDS, @@ -250,7 +250,7 @@ fn should_raise_deploy_authorization_failure() { let deploy = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) // change deployment threshold to 4 .with_session_code( CONTRACT_SET_ACTION_THRESHOLDS, @@ -281,7 +281,7 @@ fn should_raise_deploy_authorization_failure() { let deploy = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) // change deployment threshold to 4 .with_session_code( CONTRACT_SET_ACTION_THRESHOLDS, @@ -340,7 +340,7 @@ fn should_authorize_deploy_with_multiple_keys() { let deploy = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_session_code( CONTRACT_SET_ACTION_THRESHOLDS, runtime_args! { @@ -406,7 +406,7 @@ fn should_not_authorize_deploy_with_duplicated_keys() { let deploy = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_session_code( diff --git a/execution_engine_testing/tests/src/test/contract_api/account/key_management_thresholds.rs b/execution_engine_testing/tests/src/test/contract_api/account/key_management_thresholds.rs index cedaae2260..ee2e8f734b 100644 --- a/execution_engine_testing/tests/src/test/contract_api/account/key_management_thresholds.rs +++ b/execution_engine_testing/tests/src/test/contract_api/account/key_management_thresholds.rs @@ -44,7 +44,7 @@ fn should_verify_key_management_permission_with_sufficient_weight() { .build(); let deploy = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) // This test verifies that all key management operations succeed .with_session_code( "key_management_thresholds.wasm", diff --git a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs index f1257b327c..a0bb96553c 100644 --- a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs +++ b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs @@ -530,7 +530,7 @@ fn should_query_dictionary_items_with_test_builder() { let dictionary_code = PathBuf::from(DICTIONARY_WASM); let deploy_item = DeployItemBuilder::new() - .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT}) + .with_standard_payment(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT}) .with_session_code(dictionary_code, RuntimeArgs::new()) .with_address(*DEFAULT_ACCOUNT_ADDR) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) diff --git a/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs b/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs index 182d5f06bb..2341af92d1 100644 --- a/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs +++ b/execution_engine_testing/tests/src/test/contract_api/list_authorization_keys.rs @@ -108,7 +108,7 @@ fn test_match( let deploy_item = DeployItemBuilder::new() .with_address(caller) .with_session_code(CONTRACT_LIST_AUTHORIZATION_KEYS, session_args) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }) .with_authorization_keys(&signatures) diff --git a/execution_engine_testing/tests/src/test/contract_api/multisig_authorization.rs b/execution_engine_testing/tests/src/test/contract_api/multisig_authorization.rs index b825b15ca3..77375da334 100644 --- a/execution_engine_testing/tests/src/test/contract_api/multisig_authorization.rs +++ b/execution_engine_testing/tests/src/test/contract_api/multisig_authorization.rs @@ -154,7 +154,7 @@ fn test_multisig_auth( let deploy_item = DeployItemBuilder::new() .with_address(caller) .with_stored_session_named_key(CONTRACT_KEY, entry_point, session_args) - .with_empty_payment_bytes(payment_args) + .with_standard_payment(payment_args) .with_authorization_keys(authorization_keys) .with_deploy_hash(deploy_hash) .build(); diff --git a/execution_engine_testing/tests/src/test/deploy/context_association.rs b/execution_engine_testing/tests/src/test/deploy/context_association.rs index 5a75f1b558..109e2986d0 100644 --- a/execution_engine_testing/tests/src/test/deploy/context_association.rs +++ b/execution_engine_testing/tests/src/test/deploy/context_association.rs @@ -20,7 +20,7 @@ fn should_put_system_contract_hashes_to_account_context() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code(SYSTEM_CONTRACT_HASHES_WASM, runtime_args! {}) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount}) + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_purse_amount}) .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .with_deploy_hash([1; 32]) .build(); diff --git a/execution_engine_testing/tests/src/test/deploy/preconditions.rs b/execution_engine_testing/tests/src/test/deploy/preconditions.rs index a7d5964c06..c26274f1db 100644 --- a/execution_engine_testing/tests/src/test/deploy/preconditions.rs +++ b/execution_engine_testing/tests/src/test/deploy/preconditions.rs @@ -27,7 +27,7 @@ fn should_raise_precondition_authorization_failure_invalid_account() { runtime_args! { "target" =>account_1_account_hash, "amount" => U512::from(transferred_amount) }, ) // .with_address(nonexistent_account_addr) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => U512::from(payment_purse_amount) }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => U512::from(payment_purse_amount) }) .with_authorization_keys(&[nonexistent_account_addr]) .build(); @@ -57,7 +57,7 @@ fn should_raise_precondition_authorization_failure_empty_authorized_keys() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code("do_nothing.wasm", RuntimeArgs::default()) - .with_empty_payment_bytes(RuntimeArgs::default()) + .with_standard_payment(RuntimeArgs::default()) .with_deploy_hash([1; 32]) // empty authorization keys to force error .with_authorization_keys(&empty_keys) @@ -97,7 +97,7 @@ fn should_raise_precondition_authorization_failure_invalid_authorized_keys() { "transfer_purse_to_account.wasm", runtime_args! { "target" =>account_1_account_hash, "amount" => U512::from(transferred_amount) }, ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => U512::from(payment_purse_amount) }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => U512::from(payment_purse_amount) }) // invalid authorization key to force error .with_authorization_keys(&[nonexistent_account_addr]) .build(); diff --git a/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs b/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs index 6de1dc7ff5..c771b9f31e 100644 --- a/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs +++ b/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs @@ -84,7 +84,7 @@ fn should_exec_non_stored_code() { ARG_AMOUNT => U512::from(transferred_amount) }, ) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_purse_amount, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) diff --git a/execution_engine_testing/tests/src/test/explorer/faucet.rs b/execution_engine_testing/tests/src/test/explorer/faucet.rs index b67a7abce1..fab2d9125e 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet.rs @@ -3,12 +3,12 @@ use num_rational::Ratio; use casper_execution_engine::{engine_state, execution::ExecError}; use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, TransferRequestBuilder, - DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, + ChainspecConfig, DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, + TransferRequestBuilder, CHAINSPEC_SYMLINK, DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, }; use casper_types::{ - account::AccountHash, addressable_entity::EntityKindTag, runtime_args, ApiError, Key, - PublicKey, SecretKey, U512, + account::AccountHash, addressable_entity::EntityKindTag, runtime_args, ApiError, FeeHandling, + Key, PricingHandling, PublicKey, RefundHandling, SecretKey, U512, }; // test constants. @@ -934,6 +934,13 @@ fn faucet_costs() { let installer_account = AccountHash::new([1u8; 32]); let user_account: AccountHash = AccountHash::new([2u8; 32]); + let chainspec = ChainspecConfig::from_chainspec_path(&*CHAINSPEC_SYMLINK) + .expect("must build chainspec configuration"); + let chainspec_config = chainspec + .with_fee_handling(FeeHandling::NoFee) + .with_refund_handling(RefundHandling::NoRefund) + .with_pricing_handling(PricingHandling::Fixed); + LmdbWasmTestBuilder::new_temporary_with_config(chainspec_config); let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); @@ -973,7 +980,7 @@ fn faucet_costs() { ARG_DISTRIBUTIONS_PER_INTERVAL => Some(assigned_distributions_per_interval) }, ) - .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT}) + .with_standard_payment(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT}) .with_deploy_hash([3; 32]) .build(); @@ -997,7 +1004,7 @@ fn faucet_costs() { ENTRY_POINT_FAUCET, runtime_args! {ARG_TARGET => user_account, ARG_AMOUNT => user_fund_amount, ARG_ID => >::None}, ) - .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT}) + .with_standard_payment(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT}) .with_deploy_hash([4; 32]) .build(); @@ -1020,7 +1027,7 @@ fn faucet_costs() { ENTRY_POINT_FAUCET, runtime_args! {ARG_TARGET => user_account, ARG_ID => >::None}, ) - .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => user_fund_amount}) + .with_standard_payment(runtime_args! {ARG_AMOUNT => user_fund_amount}) .with_deploy_hash([4; 32]) .build(); diff --git a/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs b/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs index 5a5f1b1a2c..ee3de0cd71 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs @@ -337,7 +337,7 @@ impl FaucetFundRequestBuilder { }, }, ) - .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => self.payment_amount}) + .with_standard_payment(runtime_args! {ARG_AMOUNT => self.payment_amount}) .with_deploy_hash(rng.gen()) .build(); diff --git a/execution_engine_testing/tests/src/test/gas_counter.rs b/execution_engine_testing/tests/src/test/gas_counter.rs index 61f4712e92..605505c417 100644 --- a/execution_engine_testing/tests/src/test/gas_counter.rs +++ b/execution_engine_testing/tests/src/test/gas_counter.rs @@ -46,7 +46,7 @@ fn should_fail_to_overflow_gas_counter() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_bytes(session_bytes, RuntimeArgs::default()) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) @@ -152,7 +152,7 @@ fn should_correctly_measure_gas_for_opcodes() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_bytes(session_bytes, RuntimeArgs::default()) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) diff --git a/execution_engine_testing/tests/src/test/groups.rs b/execution_engine_testing/tests/src/test/groups.rs index c77bb07e32..04654fb9b7 100644 --- a/execution_engine_testing/tests/src/test/groups.rs +++ b/execution_engine_testing/tests/src/test/groups.rs @@ -147,7 +147,7 @@ fn should_not_call_restricted_session_from_wrong_account() { RESTRICTED_SESSION, args, ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[ACCOUNT_1_ADDR]) .with_deploy_hash([3; 32]) .build(); @@ -208,7 +208,7 @@ fn should_not_call_restricted_session_caller_from_wrong_account() { RESTRICTED_SESSION_CALLER, args, ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[ACCOUNT_1_ADDR]) .with_deploy_hash([3; 32]) .build(); @@ -266,7 +266,7 @@ fn should_call_group_restricted_contract() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name(PACKAGE_HASH_KEY, None, RESTRICTED_CONTRACT, args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([3; 32]) .build(); @@ -323,7 +323,7 @@ fn should_not_call_group_restricted_contract_from_wrong_account() { RESTRICTED_CONTRACT, args, ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[ACCOUNT_1_ADDR]) .with_deploy_hash([3; 32]) .build(); @@ -368,7 +368,7 @@ fn should_call_group_unrestricted_contract_caller() { UNRESTRICTED_CONTRACT_CALLER, args, ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([3; 32]) .build(); @@ -551,7 +551,7 @@ fn should_not_call_uncallable_contract_from_deploy() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name(PACKAGE_HASH_KEY, None, UNCALLABLE_SESSION, args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([3; 32]) .build(); @@ -576,7 +576,7 @@ fn should_not_call_uncallable_contract_from_deploy() { CALL_RESTRICTED_ENTRY_POINTS, args, ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([6; 32]) .build(); @@ -615,7 +615,7 @@ fn should_not_call_uncallable_session_from_deploy() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name(PACKAGE_HASH_KEY, None, UNCALLABLE_CONTRACT, args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([3; 32]) .build(); @@ -640,7 +640,7 @@ fn should_not_call_uncallable_session_from_deploy() { CALL_RESTRICTED_ENTRY_POINTS, args, ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([6; 32]) .build(); diff --git a/execution_engine_testing/tests/src/test/private_chain/management.rs b/execution_engine_testing/tests/src/test/private_chain/management.rs index 5832c0e65b..65ffa72d8b 100644 --- a/execution_engine_testing/tests/src/test/private_chain/management.rs +++ b/execution_engine_testing/tests/src/test/private_chain/management.rs @@ -237,7 +237,7 @@ fn genesis_accounts_should_not_remove_associated_keys() { let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(ADD_ASSOCIATED_KEY_CONTRACT, session_args) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }) .with_authorization_keys(&[*ADMIN_1_ACCOUNT_ADDR]) @@ -310,7 +310,7 @@ fn administrator_account_should_disable_any_account() { let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_session_code(SET_ACTION_THRESHOLDS_CONTRACT, session_args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ADMIN_ACCOUNT_ADDR]) .with_deploy_hash(deploy_hash) .build(); @@ -354,7 +354,7 @@ fn administrator_account_should_disable_any_account() { let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_session_code(SET_ACTION_THRESHOLDS_CONTRACT, session_args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ADMIN_ACCOUNT_ADDR]) .with_deploy_hash(deploy_hash) .build(); @@ -373,7 +373,7 @@ fn administrator_account_should_disable_any_account() { let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_session_code(SET_ACTION_THRESHOLDS_CONTRACT, session_args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ADMIN_ACCOUNT_ADDR]) .with_deploy_hash(deploy_hash) .build(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_1129.rs b/execution_engine_testing/tests/src/test/regression/ee_1129.rs index 44e196bae9..3d9e3ecf62 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1129.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1129.rs @@ -80,7 +80,7 @@ fn should_run_ee_1129_underfunded_delegate_call() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_session_hash(auction, auction::METHOD_DELEGATE, args) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => *UNDERFUNDED_DELEGATE_AMOUNT, // underfunded deploy }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) @@ -141,7 +141,7 @@ fn should_run_ee_1129_underfunded_add_bid_call() { let deploy_item = DeployItemBuilder::new() .with_address(*VALIDATOR_1_ADDR) .with_stored_session_hash(auction, auction::METHOD_ADD_BID, args) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => *UNDERFUNDED_DELEGATE_AMOUNT, }) .with_authorization_keys(&[*VALIDATOR_1_ADDR]) @@ -184,7 +184,7 @@ fn should_run_ee_1129_underfunded_mint_contract_call() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_session_named_key(CONTRACT_KEY, ENTRY_POINT_NAME, RuntimeArgs::default()) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => *CALL_STORED_CONTRACT_OVERHEAD, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) @@ -228,7 +228,7 @@ fn should_not_panic_when_calling_session_contract_by_uref() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_session_named_key(ACCESS_KEY, ENTRY_POINT_NAME, RuntimeArgs::default()) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => *CALL_STORED_CONTRACT_OVERHEAD, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) @@ -319,7 +319,7 @@ fn should_not_panic_when_calling_contract_package_by_uref() { ENTRY_POINT_NAME, RuntimeArgs::default(), ) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => *CALL_STORED_CONTRACT_OVERHEAD, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) @@ -419,7 +419,7 @@ fn should_not_panic_when_calling_module_without_memory() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_bytes(do_nothing_without_memory(), RuntimeArgs::new()) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) diff --git a/execution_engine_testing/tests/src/test/regression/ee_441.rs b/execution_engine_testing/tests/src/test/regression/ee_441.rs index 2e635c4cb5..b0ee4393e5 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_441.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_441.rs @@ -18,7 +18,7 @@ fn do_pass(pass: &str) -> (URef, URef) { // more data let deploy = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_session_code( EE_441_RNG_STATE, runtime_args! { diff --git a/execution_engine_testing/tests/src/test/regression/ee_550.rs b/execution_engine_testing/tests/src/test/regression/ee_550.rs index 62ac5f0a9d..0e869dc6f6 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_550.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_550.rs @@ -30,7 +30,7 @@ fn should_run_ee_550_remove_with_saturated_threshold_regression() { CONTRACT_EE_550_REGRESSION, runtime_args! { ARG_PASS => String::from(PASS_TEST_REMOVE) }, ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, AccountHash::new(KEY_2_ADDR)]) .with_deploy_hash(DEPLOY_HASH) .build(); @@ -65,7 +65,7 @@ fn should_run_ee_550_update_with_saturated_threshold_regression() { CONTRACT_EE_550_REGRESSION, runtime_args! { ARG_PASS => String::from(PASS_TEST_UPDATE) }, ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, AccountHash::new(KEY_2_ADDR)]) .with_deploy_hash(DEPLOY_HASH) .build(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_598.rs b/execution_engine_testing/tests/src/test/regression/ee_598.rs index f380d68977..ef42fa1663 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_598.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_598.rs @@ -62,7 +62,7 @@ fn should_handle_unbond_for_more_than_stake_as_full_unbond_of_stake_ee_598_regre .build(); let deploy = DeployItemBuilder::new() .with_address(*ACCOUNT_1_ADDR) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *ACCOUNT_1_FUND }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *ACCOUNT_1_FUND }) .with_session_code( "ee_598_regression.wasm", runtime_args! { diff --git a/execution_engine_testing/tests/src/test/regression/ee_890.rs b/execution_engine_testing/tests/src/test/regression/ee_890.rs index 3651f864fa..ce7be9a44e 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_890.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_890.rs @@ -43,7 +43,7 @@ fn should_run_ee_890_gracefully_reject_start_node_in_session() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_bytes(wasm_binary, RuntimeArgs::new()) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([123; 32]) .build(); diff --git a/execution_engine_testing/tests/src/test/regression/ee_966.rs b/execution_engine_testing/tests/src/test/regression/ee_966.rs index 75da639a98..26785ac415 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_966.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_966.rs @@ -61,7 +61,7 @@ fn make_request_with_session_bytes<'a>(session_code: Vec) -> ExecuteRequest< let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_bytes(session_code, RuntimeArgs::new()) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) diff --git a/execution_engine_testing/tests/src/test/regression/gh_1688.rs b/execution_engine_testing/tests/src/test/regression/gh_1688.rs index 6afbbf0a02..1dde09696c 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1688.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1688.rs @@ -98,7 +98,7 @@ fn should_run_gh_1688_regression_stored_versioned_contract_by_hash() { METHOD_PUT_KEY, RuntimeArgs::default(), ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([42; 32]) .build() @@ -117,7 +117,7 @@ fn should_run_gh_1688_regression_stored_versioned_contract_by_name() { METHOD_PUT_KEY, RuntimeArgs::default(), ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([42; 32]) .build() @@ -131,7 +131,7 @@ fn should_run_gh_1688_regression_stored_contract_by_hash() { DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_session_hash(contract_hash, METHOD_PUT_KEY, RuntimeArgs::default()) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([42; 32]) .build() @@ -149,7 +149,7 @@ fn should_run_gh_1688_regression_stored_contract_by_name() { METHOD_PUT_KEY, RuntimeArgs::default(), ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) .with_deploy_hash([42; 32]) .build() diff --git a/execution_engine_testing/tests/src/test/regression/gh_1902.rs b/execution_engine_testing/tests/src/test/regression/gh_1902.rs index e36f9186a9..e97f2fc753 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1902.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1902.rs @@ -124,7 +124,7 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_hash(contract_hash, entry_point, session_args) - .with_empty_payment_bytes(payment_args) + .with_standard_payment(payment_args) .with_authorization_keys(&[sender]) .with_deploy_hash([43; 32]) .build(); @@ -160,7 +160,7 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_hash(contract_hash, entry_point, session_args) - .with_empty_payment_bytes(payment_args) + .with_standard_payment(payment_args) .with_authorization_keys(&[sender]) .with_deploy_hash(deploy_hash) .build(); @@ -196,7 +196,7 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_hash(contract_hash, entry_point, session_args) - .with_empty_payment_bytes(payment_args) + .with_standard_payment(payment_args) .with_authorization_keys(&[sender]) .with_deploy_hash(deploy_hash) .build(); @@ -230,7 +230,7 @@ fn should_not_charge_for_create_purse_in_first_time_bond() { let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_hash(contract_hash, entry_point, session_args) - .with_empty_payment_bytes(payment_args) + .with_standard_payment(payment_args) .with_authorization_keys(&[sender]) .with_deploy_hash([58; 32]) .build(); diff --git a/execution_engine_testing/tests/src/test/regression/gh_2280.rs b/execution_engine_testing/tests/src/test/regression/gh_2280.rs index 7b6f38477c..d12cb06827 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_2280.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_2280.rs @@ -92,7 +92,7 @@ fn gh_2280_transfer_should_always_cost_the_same_gas() { .with_address(account_hash) .with_session_code(session_file, faucet_args_2) // + default_create_purse_cost - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_amount.value() }) .with_authorization_keys(&[account_hash]) @@ -151,7 +151,7 @@ fn gh_2280_transfer_should_always_cost_the_same_gas() { let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(session_file, faucet_args_3) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE }) .with_authorization_keys(&[account_hash]) @@ -205,7 +205,7 @@ fn gh_2280_create_purse_should_always_cost_the_same_gas() { .with_address(account_hash) .with_session_code(session_file, create_purse_args_2) // + default_create_purse_cost - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_amount.value() }) .with_authorization_keys(&[account_hash]) @@ -265,7 +265,7 @@ fn gh_2280_create_purse_should_always_cost_the_same_gas() { let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(session_file, create_purse_args_3) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE }) .with_authorization_keys(&[account_hash]) @@ -321,7 +321,7 @@ fn gh_2280_transfer_purse_to_account_should_always_cost_the_same_gas() { .with_address(account_hash) .with_session_code(TRANSFER_PURSE_TO_ACCOUNT_CONTRACT, faucet_args_2) // + default_create_purse_cost - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_amount.value() }) .with_authorization_keys(&[account_hash]) @@ -384,7 +384,7 @@ fn gh_2280_transfer_purse_to_account_should_always_cost_the_same_gas() { let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(session_file, faucet_args_3) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE }) .with_authorization_keys(&[account_hash]) @@ -443,7 +443,7 @@ fn gh_2280_stored_transfer_to_account_should_always_cost_the_same_gas() { .with_address(account_hash) .with_stored_session_hash(gh_2280_regression, entry_point, faucet_args_2) // + default_create_purse_cost - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_amount.value() }) .with_authorization_keys(&[account_hash]) @@ -505,7 +505,7 @@ fn gh_2280_stored_transfer_to_account_should_always_cost_the_same_gas() { let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_stored_session_hash(gh_2280_regression, entry_point, faucet_args_3) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE }) .with_authorization_keys(&[account_hash]) @@ -561,7 +561,7 @@ fn gh_2280_stored_faucet_call_should_cost_the_same() { .with_address(account_hash) .with_session_code(session_file, faucet_args_2) // + default_create_purse_cost - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_amount.value() }) .with_authorization_keys(&[account_hash]) @@ -624,7 +624,7 @@ fn gh_2280_stored_faucet_call_should_cost_the_same() { let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_code(session_file, faucet_args_3) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_amount.value() + HOST_FUNCTION_COST_CHANGE }) .with_authorization_keys(&[account_hash]) diff --git a/execution_engine_testing/tests/src/test/regression/gh_3208.rs b/execution_engine_testing/tests/src/test/regression/gh_3208.rs index 6b34845ce1..a06d71aa64 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_3208.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_3208.rs @@ -209,7 +209,7 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule() let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_hash(contract_hash, entry_point, session_args) - .with_empty_payment_bytes(payment_args) + .with_standard_payment(payment_args) .with_authorization_keys(&[sender]) .with_deploy_hash([58; 32]) .build(); @@ -228,7 +228,7 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule() let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_hash(contract_hash, entry_point, session_args) - .with_empty_payment_bytes(payment_args) + .with_standard_payment(payment_args) .with_authorization_keys(&[sender]) .with_deploy_hash([59; 32]) .build(); @@ -353,7 +353,7 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule_a let deploy_item = DeployItemBuilder::new() .with_address(sender) .with_stored_session_hash(contract_hash, entry_point, session_args) - .with_empty_payment_bytes(payment_args) + .with_standard_payment(payment_args) .with_authorization_keys(&[sender]) .with_deploy_hash([58; 32]) .build(); diff --git a/execution_engine_testing/tests/src/test/regression/gov_42.rs b/execution_engine_testing/tests/src/test/regression/gov_42.rs index 2ecf7f8609..6da2bdb21d 100644 --- a/execution_engine_testing/tests/src/test/regression/gov_42.rs +++ b/execution_engine_testing/tests/src/test/regression/gov_42.rs @@ -56,7 +56,7 @@ fn run_test_case(input_wasm_bytes: &[u8], expected_error: &str, execution_phase: ExecutionPhase::Session => ( DeployItemBuilder::new() .with_session_bytes(input_wasm_bytes.to_vec(), session_args) - .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => payment_amount,}), + .with_standard_payment(runtime_args! {ARG_AMOUNT => payment_amount,}), expected_error, ), }; diff --git a/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs b/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs index 085e2319f4..3c6debc79f 100644 --- a/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs +++ b/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs @@ -96,9 +96,7 @@ fn host_function_metrics_has_acceptable_gas_cost() { ARG_AMOUNT => TRANSFER_FROM_MAIN_PURSE_AMOUNT, }, ) - .with_empty_payment_bytes( - runtime_args! { standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT }, - ) + .with_standard_payment(runtime_args! { standard_payment::ARG_AMOUNT => *DEFAULT_PAYMENT }) .with_authorization_keys(&[ACCOUNT0_ADDR]) .build(); let exec_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20210924.rs b/execution_engine_testing/tests/src/test/regression/regression_20210924.rs index cfb776d4d4..7adc31464a 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20210924.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20210924.rs @@ -22,7 +22,7 @@ fn should_charge_minimum_for_do_nothing_session() { let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_bytes(wasm_utils::do_nothing_bytes(), session_args) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => minimum_deploy_payment, }) .with_authorization_keys(&[account_hash]) @@ -78,7 +78,7 @@ fn should_execute_do_minimum_session() { let deploy_item = DeployItemBuilder::new() .with_address(account_hash) .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => minimum_deploy_payment, }) .with_authorization_keys(&[account_hash]) diff --git a/execution_engine_testing/tests/src/test/regression/regression_20211110.rs b/execution_engine_testing/tests/src/test/regression/regression_20211110.rs index 20d6624918..cfe80c4d9d 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20211110.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20211110.rs @@ -32,7 +32,7 @@ fn regression_20211110() { }; let deploy_item = DeployItemBuilder::new() .with_address(ACCOUNT_1_ADDR) - .with_empty_payment_bytes(payment_args) + .with_standard_payment(payment_args) .with_session_code(REGRESSION_20211110_CONTRACT, session_args) .with_authorization_keys(&[ACCOUNT_1_ADDR]) .with_deploy_hash([42; 32]) @@ -66,7 +66,7 @@ fn regression_20211110() { }; let deploy_item = DeployItemBuilder::new() .with_address(ACCOUNT_1_ADDR) - .with_empty_payment_bytes(payment_args) + .with_standard_payment(payment_args) .with_stored_session_hash(contract_hash, RECURSE_ENTRYPOINT, session_args) .with_authorization_keys(&[ACCOUNT_1_ADDR]) .with_deploy_hash([43; 32]) diff --git a/execution_engine_testing/tests/src/test/regression/transforms_must_be_ordered.rs b/execution_engine_testing/tests/src/test/regression/transforms_must_be_ordered.rs index ffa479fef0..a7054db06b 100644 --- a/execution_engine_testing/tests/src/test/regression/transforms_must_be_ordered.rs +++ b/execution_engine_testing/tests/src/test/regression/transforms_must_be_ordered.rs @@ -68,7 +68,7 @@ fn contract_transforms_should_be_ordered_in_the_effects() { ExecuteRequestBuilder::from_deploy_item( &DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { standard_payment::ARG_AMOUNT => U512::from(150_000_000_000_u64), }) .with_stored_session_hash( diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs b/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs index c55a9df9b7..8148e5087a 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction/distribute.rs @@ -22,7 +22,7 @@ use casper_types::{ ARG_DELEGATOR, ARG_PUBLIC_KEY, ARG_REWARDS_MAP, ARG_VALIDATOR, DELEGATION_RATE_DENOMINATOR, METHOD_DISTRIBUTE, SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY, }, - EntityAddr, EraId, Key, ProtocolVersion, PublicKey, SecretKey, Timestamp, U512, + EntityAddr, EraId, HoldsEpoch, Key, ProtocolVersion, PublicKey, SecretKey, Timestamp, U512, }; const ARG_ENTRY_POINT: &str = "entry_point"; @@ -1013,7 +1013,7 @@ fn should_distribute_rewards_after_restaking_delegated_funds() { validator: VALIDATOR_1.clone(), delegator: DELEGATOR_2.clone(), amount: updelegate_amount, - holds_epoch: None, + holds_epoch: HoldsEpoch::NOT_APPLICABLE, }, ); assert!(updelegate_result.is_success(), "{:?}", updelegate_result); @@ -1028,7 +1028,7 @@ fn should_distribute_rewards_after_restaking_delegated_funds() { public_key: VALIDATOR_1.clone(), amount, delegation_rate: 0, - holds_epoch: None, + holds_epoch: HoldsEpoch::NOT_APPLICABLE, } } else { AuctionMethod::WithdrawBid { diff --git a/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs b/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs index 447919a402..78c7d31fdc 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/standard_payment.rs @@ -219,7 +219,7 @@ fn should_run_out_of_gas_when_session_code_exceeds_gas_limit() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_purse_amount }) .with_session_code( ENDLESS_LOOP_WASM, runtime_args! { ARG_TARGET => account_1_account_hash, ARG_AMOUNT => U512::from(transferred_amount) }, @@ -260,7 +260,7 @@ fn should_correctly_charge_when_session_code_runs_out_of_gas() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_purse_amount }) .with_session_code(ENDLESS_LOOP_WASM, RuntimeArgs::default()) .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .build(); @@ -321,7 +321,7 @@ fn should_correctly_charge_when_session_code_fails() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_deploy_hash([1; 32]) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_purse_amount }) .with_session_code( REVERT_WASM, runtime_args! { ARG_TARGET => account_1_account_hash, ARG_AMOUNT => U512::from(transferred_amount) }, @@ -374,7 +374,7 @@ fn should_correctly_charge_when_session_code_succeeds() { TRANSFER_PURSE_TO_ACCOUNT_WASM, runtime_args! { ARG_TARGET => account_1_account_hash, ARG_AMOUNT => U512::from(transferred_amount) }, ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_purse_amount }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .build(); @@ -429,7 +429,7 @@ fn should_finalize_to_rewards_purse() { TRANSFER_PURSE_TO_ACCOUNT_WASM, runtime_args! { ARG_TARGET => account_1_account_hash, ARG_AMOUNT => U512::from(transferred_amount) }, ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_purse_amount }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .with_deploy_hash([1; 32]) .build(); @@ -468,7 +468,7 @@ fn independent_standard_payments_should_not_write_the_same_keys() { TRANSFER_PURSE_TO_ACCOUNT_WASM, runtime_args! { ARG_TARGET => account_1_account_hash, ARG_AMOUNT => U512::from(transfer_amount) }, ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_purse_amount }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .with_deploy_hash([1; 32]) .build(); @@ -485,7 +485,7 @@ fn independent_standard_payments_should_not_write_the_same_keys() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_code(DO_NOTHING_WASM, RuntimeArgs::default()) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_purse_amount }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_KEY]) .with_deploy_hash([2; 32]) .build(); @@ -495,7 +495,7 @@ fn independent_standard_payments_should_not_write_the_same_keys() { let deploy_item = DeployItemBuilder::new() .with_address(ACCOUNT_1_ADDR) .with_session_code(DO_NOTHING_WASM, RuntimeArgs::default()) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => payment_purse_amount }) + .with_standard_payment(runtime_args! { ARG_AMOUNT => payment_purse_amount }) .with_authorization_keys(&[account_1_account_hash]) .with_deploy_hash([1; 32]) .build(); diff --git a/execution_engine_testing/tests/src/test/system_costs.rs b/execution_engine_testing/tests/src/test/system_costs.rs index cbe00c40a0..6952baa797 100644 --- a/execution_engine_testing/tests/src/test/system_costs.rs +++ b/execution_engine_testing/tests/src/test/system_costs.rs @@ -761,7 +761,7 @@ fn should_verify_do_nothing_charges_only_for_standard_payment() { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) - .with_empty_payment_bytes(runtime_args! { + .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT }) .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index bf07a108e6..34c914f3f3 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -25,8 +25,8 @@ use casper_types::{ execution::{Effects, ExecutionResult, TransformKindV2, TransformV2}, system::mint::BalanceHoldAddrTag, BlockHeader, BlockTime, BlockV2, CLValue, CategorizedTransaction, Chainspec, ChecksumRegistry, - Digest, EraEndV2, EraId, FeeHandling, Gas, GasLimited, Key, ProtocolVersion, PublicKey, - Transaction, TransactionCategory, U512, + Digest, EraEndV2, EraId, FeeHandling, Gas, GasLimited, HoldsEpoch, Key, ProtocolVersion, + PublicKey, Transaction, TransactionCategory, U512, }; use super::{ @@ -84,11 +84,9 @@ pub fn execute_finalized_block( let mut state_root_hash = pre_state_root_hash; let mut artifacts = Vec::with_capacity(executable_block.transactions.len()); let block_time = BlockTime::new(executable_block.timestamp.millis()); - let balance_handling = BalanceHandling::Available { - block_time: executable_block.timestamp.millis(), - hold_interval: chainspec.core_config.balance_hold_interval.millis(), - }; - let holds_epoch = Some(chainspec.balance_holds_epoch(executable_block.timestamp)); + let holds_epoch = + HoldsEpoch::from_block_time(block_time, chainspec.core_config.balance_hold_interval); + let balance_handling = BalanceHandling::Available { holds_epoch }; let proposer = executable_block.proposer.clone(); let start = Instant::now(); @@ -323,6 +321,17 @@ pub fn execute_finalized_block( match fee_handling { FeeHandling::NoFee => { // in this mode, a hold for full cost is placed on the payer's purse. + let handle_payment_request = HandlePaymentRequest::new( + native_runtime_config.clone(), + state_root_hash, + protocol_version, + transaction_hash, + HandlePaymentMode::clear_holds(balance_identifier.clone(), holds_epoch), + ); + let handle_payment_result = scratch_state.handle_payment(handle_payment_request); + artifact_builder + .with_handle_payment_result(&handle_payment_result) + .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; let hold_result = scratch_state.balance_hold(BalanceHoldRequest::new( state_root_hash, protocol_version, @@ -330,7 +339,7 @@ pub fn execute_finalized_block( BalanceHoldAddrTag::Gas, cost, block_time, - chainspec.core_config.balance_hold_interval, + holds_epoch, insufficient_balance_handling, )); artifact_builder diff --git a/node/src/components/transaction_acceptor.rs b/node/src/components/transaction_acceptor.rs index 3f4db1042d..d95f145f8b 100644 --- a/node/src/components/transaction_acceptor.rs +++ b/node/src/components/transaction_acceptor.rs @@ -16,9 +16,9 @@ use casper_types::{ account::AccountHash, addressable_entity::AddressableEntity, contracts::ContractHash, system::auction::ARG_AMOUNT, AddressableEntityHash, AddressableEntityIdentifier, BlockHeader, Chainspec, EntityAddr, EntityVersion, EntityVersionKey, ExecutableDeployItem, - ExecutableDeployItemIdentifier, InitiatorAddr, Key, Package, PackageAddr, PackageHash, - PackageIdentifier, Transaction, TransactionEntryPoint, TransactionInvocationTarget, - TransactionTarget, U512, + ExecutableDeployItemIdentifier, HoldsEpoch, InitiatorAddr, Key, Package, PackageAddr, + PackageHash, PackageIdentifier, Transaction, TransactionEntryPoint, + TransactionInvocationTarget, TransactionTarget, U512, }; use crate::{ @@ -219,10 +219,8 @@ impl TransactionAcceptor { let protocol_version = block_header.protocol_version(); let hold_interval = self.balance_hold_interval; let block_time = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_millis() as u64; - let balance_handling = BalanceHandling::Available { - hold_interval, - block_time, - }; + let holds_epoch = HoldsEpoch::from_millis(block_time, hold_interval); + let balance_handling = BalanceHandling::Available { holds_epoch }; let balance_request = BalanceRequest::from_purse( *block_header.state_root_hash(), protocol_version, diff --git a/resources/local/chainspec.toml.in b/resources/local/chainspec.toml.in index a87d9941d2..8a10d5f73e 100644 --- a/resources/local/chainspec.toml.in +++ b/resources/local/chainspec.toml.in @@ -96,7 +96,7 @@ compute_rewards = true # This causes excess payment amounts to be sent to either a # pre-defined purse, or back to the sender. The refunded amount is calculated as the given ratio of the payment amount # minus the execution costs. -refund_handling = { type = 'refund', refund_ratio = [99, 100] } +refund_handling = { type = 'no_refund' } # Defines how fees are handled. # # Valid options are: diff --git a/storage/src/data_access_layer/auction.rs b/storage/src/data_access_layer/auction.rs index 2774185d46..3970b3429a 100644 --- a/storage/src/data_access_layer/auction.rs +++ b/storage/src/data_access_layer/auction.rs @@ -9,8 +9,8 @@ use casper_types::{ bytesrepr::FromBytes, execution::Effects, system::{auction, auction::DelegationRate}, - CLTyped, CLValue, CLValueError, Chainspec, Digest, InitiatorAddr, ProtocolVersion, PublicKey, - RuntimeArgs, TransactionEntryPoint, TransactionHash, U512, + CLTyped, CLValue, CLValueError, Chainspec, Digest, HoldsEpoch, InitiatorAddr, ProtocolVersion, + PublicKey, RuntimeArgs, TransactionEntryPoint, TransactionHash, U512, }; use crate::{ @@ -45,7 +45,7 @@ pub enum AuctionMethod { public_key: PublicKey, delegation_rate: DelegationRate, amount: U512, - holds_epoch: Option, + holds_epoch: HoldsEpoch, }, WithdrawBid { public_key: PublicKey, @@ -57,7 +57,7 @@ pub enum AuctionMethod { amount: U512, max_delegators_per_validator: u32, minimum_delegation_amount: u64, - holds_epoch: Option, + holds_epoch: HoldsEpoch, }, Undelegate { delegator: PublicKey, @@ -77,7 +77,7 @@ impl AuctionMethod { pub fn from_parts( entry_point: TransactionEntryPoint, runtime_args: &RuntimeArgs, - holds_epoch: Option, + holds_epoch: HoldsEpoch, chainspec: &Chainspec, ) -> Result { match entry_point { @@ -108,7 +108,7 @@ impl AuctionMethod { fn new_add_bid( runtime_args: &RuntimeArgs, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result { let public_key = Self::get_named_argument(runtime_args, auction::ARG_PUBLIC_KEY)?; let delegation_rate = Self::get_named_argument(runtime_args, auction::ARG_DELEGATION_RATE)?; @@ -131,7 +131,7 @@ impl AuctionMethod { runtime_args: &RuntimeArgs, max_delegators_per_validator: u32, minimum_delegation_amount: u64, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result { let delegator = Self::get_named_argument(runtime_args, auction::ARG_DELEGATOR)?; let validator = Self::get_named_argument(runtime_args, auction::ARG_VALIDATOR)?; diff --git a/storage/src/data_access_layer/balance.rs b/storage/src/data_access_layer/balance.rs index 422fca42f7..50acb56e33 100644 --- a/storage/src/data_access_layer/balance.rs +++ b/storage/src/data_access_layer/balance.rs @@ -8,8 +8,8 @@ use casper_types::{ mint::BalanceHoldAddrTag, HANDLE_PAYMENT, }, - AccessRights, BlockTime, Digest, EntityAddr, InitiatorAddr, Key, ProtocolVersion, PublicKey, - StoredValue, URef, URefAddr, U512, + AccessRights, BlockTime, Digest, EntityAddr, HoldsEpoch, InitiatorAddr, Key, ProtocolVersion, + PublicKey, StoredValue, URef, URefAddr, U512, }; use std::collections::BTreeMap; use tracing::error; @@ -27,7 +27,7 @@ pub enum BalanceHandling { #[default] Total, /// Adjust for balance holds (if any). - Available { block_time: u64, hold_interval: u64 }, + Available { holds_epoch: HoldsEpoch }, } /// Represents a way to make a balance inquiry. @@ -275,15 +275,14 @@ impl BalanceRequest { } impl From for BalanceRequest { - fn from(value: BalanceHoldRequest) -> Self { + fn from(request: BalanceHoldRequest) -> Self { let balance_handling = BalanceHandling::Available { - block_time: value.block_time().value(), - hold_interval: value.hold_interval().millis(), + holds_epoch: request.holds_epoch(), }; BalanceRequest::new( - value.state_hash(), - value.protocol_version(), - value.identifier().clone(), + request.state_hash(), + request.protocol_version(), + request.identifier().clone(), balance_handling, ) } diff --git a/storage/src/data_access_layer/balance_hold.rs b/storage/src/data_access_layer/balance_hold.rs index d56250e240..38e472e188 100644 --- a/storage/src/data_access_layer/balance_hold.rs +++ b/storage/src/data_access_layer/balance_hold.rs @@ -1,7 +1,7 @@ use crate::{data_access_layer::BalanceIdentifier, tracking_copy::TrackingCopyError}; use casper_types::{ account::AccountHash, execution::Effects, system::mint::BalanceHoldAddrTag, BlockTime, Digest, - EntityAddr, ProtocolVersion, PublicKey, TimeDiff, URef, URefAddr, U512, + EntityAddr, HoldsEpoch, ProtocolVersion, PublicKey, URef, URefAddr, U512, }; use std::fmt::{Display, Formatter}; use thiserror::Error; @@ -24,7 +24,7 @@ pub struct BalanceHoldRequest { hold_kind: BalanceHoldAddrTag, hold_amount: U512, block_time: BlockTime, - hold_interval: TimeDiff, + holds_epoch: HoldsEpoch, insufficient_handling: InsufficientBalanceHandling, } @@ -38,7 +38,7 @@ impl BalanceHoldRequest { hold_kind: BalanceHoldAddrTag, hold_amount: U512, block_time: BlockTime, - hold_interval: TimeDiff, + holds_epoch: HoldsEpoch, insufficient_handling: InsufficientBalanceHandling, ) -> Self { BalanceHoldRequest { @@ -48,7 +48,7 @@ impl BalanceHoldRequest { hold_kind, hold_amount, block_time, - hold_interval, + holds_epoch, insufficient_handling, } } @@ -62,7 +62,7 @@ impl BalanceHoldRequest { hold_kind: BalanceHoldAddrTag, hold_amount: U512, block_time: BlockTime, - hold_interval: TimeDiff, + holds_epoch: HoldsEpoch, insufficient_handling: InsufficientBalanceHandling, ) -> Self { BalanceHoldRequest { @@ -72,7 +72,7 @@ impl BalanceHoldRequest { hold_kind, hold_amount, block_time, - hold_interval, + holds_epoch, insufficient_handling, } } @@ -86,7 +86,7 @@ impl BalanceHoldRequest { hold_kind: BalanceHoldAddrTag, hold_amount: U512, block_time: BlockTime, - hold_interval: TimeDiff, + holds_epoch: HoldsEpoch, insufficient_handling: InsufficientBalanceHandling, ) -> Self { BalanceHoldRequest { @@ -96,7 +96,7 @@ impl BalanceHoldRequest { hold_kind, hold_amount, block_time, - hold_interval, + holds_epoch, insufficient_handling, } } @@ -110,7 +110,7 @@ impl BalanceHoldRequest { hold_kind: BalanceHoldAddrTag, hold_amount: U512, block_time: BlockTime, - hold_interval: TimeDiff, + holds_epoch: HoldsEpoch, insufficient_handling: InsufficientBalanceHandling, ) -> Self { BalanceHoldRequest { @@ -120,7 +120,7 @@ impl BalanceHoldRequest { hold_kind, hold_amount, block_time, - hold_interval, + holds_epoch, insufficient_handling, } } @@ -134,7 +134,7 @@ impl BalanceHoldRequest { hold_kind: BalanceHoldAddrTag, hold_amount: U512, block_time: BlockTime, - hold_interval: TimeDiff, + holds_epoch: HoldsEpoch, insufficient_handling: InsufficientBalanceHandling, ) -> Self { BalanceHoldRequest { @@ -144,7 +144,7 @@ impl BalanceHoldRequest { hold_kind, hold_amount, block_time, - hold_interval, + holds_epoch, insufficient_handling, } } @@ -158,7 +158,7 @@ impl BalanceHoldRequest { hold_kind: BalanceHoldAddrTag, hold_amount: U512, block_time: BlockTime, - hold_interval: TimeDiff, + holds_epoch: HoldsEpoch, insufficient_handling: InsufficientBalanceHandling, ) -> Self { BalanceHoldRequest { @@ -168,7 +168,7 @@ impl BalanceHoldRequest { hold_kind, hold_amount, block_time, - hold_interval, + holds_epoch, insufficient_handling, } } @@ -203,9 +203,9 @@ impl BalanceHoldRequest { self.block_time } - /// Returns the hold interval. - pub fn hold_interval(&self) -> TimeDiff { - self.hold_interval + /// Returns the holds epoch. + pub fn holds_epoch(&self) -> HoldsEpoch { + self.holds_epoch } /// Returns insufficient balance handling option. diff --git a/storage/src/data_access_layer/fee.rs b/storage/src/data_access_layer/fee.rs index f6491789d4..5abe07c0ab 100644 --- a/storage/src/data_access_layer/fee.rs +++ b/storage/src/data_access_layer/fee.rs @@ -6,7 +6,8 @@ use crate::system::{ transfer::TransferError, }; use casper_types::{ - account::AccountHash, execution::Effects, Digest, FeeHandling, ProtocolVersion, Transfer, + account::AccountHash, execution::Effects, Digest, FeeHandling, HoldsEpoch, ProtocolVersion, + Transfer, }; use crate::tracking_copy::TrackingCopyError; @@ -16,7 +17,7 @@ pub struct FeeRequest { config: NativeRuntimeConfig, state_hash: Digest, protocol_version: ProtocolVersion, - holds_epoch: Option, + holds_epoch: HoldsEpoch, } impl FeeRequest { @@ -24,7 +25,7 @@ impl FeeRequest { config: NativeRuntimeConfig, state_hash: Digest, protocol_version: ProtocolVersion, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Self { FeeRequest { config, @@ -55,7 +56,7 @@ impl FeeRequest { } /// Returns holds epoch. - pub fn holds_epoch(&self) -> Option { + pub fn holds_epoch(&self) -> HoldsEpoch { self.holds_epoch } diff --git a/storage/src/data_access_layer/handle_payment.rs b/storage/src/data_access_layer/handle_payment.rs index a8dff86915..2f73d9d948 100644 --- a/storage/src/data_access_layer/handle_payment.rs +++ b/storage/src/data_access_layer/handle_payment.rs @@ -2,7 +2,9 @@ use crate::{ data_access_layer::BalanceIdentifier, system::runtime_native::Config as NativeRuntimeConfig, tracking_copy::TrackingCopyError, }; -use casper_types::{execution::Effects, Digest, ProtocolVersion, TransactionHash, U512}; +use casper_types::{ + execution::Effects, Digest, HoldsEpoch, ProtocolVersion, TransactionHash, U512, +}; #[derive(Debug, Clone, PartialEq, Eq)] pub enum HandlePaymentMode { @@ -13,7 +15,7 @@ pub enum HandlePaymentMode { consumed: U512, source: Box, target: Box, - holds_epoch: Option, + holds_epoch: HoldsEpoch, }, Distribute { source: BalanceIdentifier, @@ -23,6 +25,10 @@ pub enum HandlePaymentMode { source: BalanceIdentifier, amount: Option, }, + ClearHolds { + source: BalanceIdentifier, + holds_epoch: HoldsEpoch, + }, } impl HandlePaymentMode { @@ -33,7 +39,7 @@ impl HandlePaymentMode { consumed: U512, source: BalanceIdentifier, target: BalanceIdentifier, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Self { HandlePaymentMode::Finalize { limit, @@ -61,6 +67,14 @@ impl HandlePaymentMode { pub fn burn(source: BalanceIdentifier, amount: Option) -> Self { HandlePaymentMode::Burn { source, amount } } + + /// Clear expired holds against source's balance per epoch. + pub fn clear_holds(source: BalanceIdentifier, holds_epoch: HoldsEpoch) -> Self { + HandlePaymentMode::ClearHolds { + source, + holds_epoch, + } + } } #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/storage/src/data_access_layer/mint.rs b/storage/src/data_access_layer/mint.rs index cb8ceb8c6e..d6a9f15f8f 100644 --- a/storage/src/data_access_layer/mint.rs +++ b/storage/src/data_access_layer/mint.rs @@ -2,8 +2,8 @@ use std::collections::BTreeSet; use crate::system::runtime_native::{Config as NativeRuntimeConfig, TransferConfig}; use casper_types::{ - account::AccountHash, execution::Effects, Digest, InitiatorAddr, ProtocolVersion, RuntimeArgs, - TransactionHash, Transfer, + account::AccountHash, execution::Effects, Digest, HoldsEpoch, InitiatorAddr, ProtocolVersion, + RuntimeArgs, TransactionHash, Transfer, }; use crate::system::transfer::{TransferArgs, TransferError}; @@ -23,7 +23,7 @@ pub struct TransferRequest { /// State root hash. state_hash: Digest, /// Balance holds epoch. - holds_epoch: Option, + holds_epoch: HoldsEpoch, /// Protocol version. protocol_version: ProtocolVersion, /// Transaction hash. @@ -42,7 +42,7 @@ impl TransferRequest { pub fn new( config: NativeRuntimeConfig, state_hash: Digest, - holds_epoch: Option, + holds_epoch: HoldsEpoch, protocol_version: ProtocolVersion, transaction_hash: TransactionHash, initiator: InitiatorAddr, @@ -67,7 +67,7 @@ impl TransferRequest { pub fn with_runtime_args( config: NativeRuntimeConfig, state_hash: Digest, - holds_epoch: Option, + holds_epoch: HoldsEpoch, protocol_version: ProtocolVersion, transaction_hash: TransactionHash, initiator: InitiatorAddr, @@ -116,7 +116,7 @@ impl TransferRequest { } /// Returns holds epoch. - pub fn holds_epoch(&self) -> Option { + pub fn holds_epoch(&self) -> HoldsEpoch { self.holds_epoch } diff --git a/storage/src/global_state/state/mod.rs b/storage/src/global_state/state/mod.rs index a7678ef141..25e94c4181 100644 --- a/storage/src/global_state/state/mod.rs +++ b/storage/src/global_state/state/mod.rs @@ -524,7 +524,7 @@ pub trait CommitProvider: StateProvider { let holds_epoch = request.holds_epoch(); let system_account_key = PublicKey::System; let id = { - let mut bytes = match holds_epoch.into_bytes() { + let mut bytes = match holds_epoch.value().into_bytes() { Ok(bytes) => bytes, Err(bre) => { return FeeResult::Failure(FeeError::TrackingCopy( @@ -680,13 +680,12 @@ pub trait StateProvider { let balance_holds = match request.balance_handling() { BalanceHandling::Total => BTreeMap::new(), - BalanceHandling::Available { - block_time, - hold_interval, - } => match tc.get_balance_holds_with_proof(purse_addr, block_time, hold_interval) { - Err(tce) => return BalanceResult::Failure(tce), - Ok(holds) => holds, - }, + BalanceHandling::Available { holds_epoch } => { + match tc.get_balance_holds_with_proof(purse_addr, holds_epoch) { + Err(tce) => return BalanceResult::Failure(tce), + Ok(holds) => holds, + } + } }; let available_balance = if balance_holds.is_empty() { @@ -1092,6 +1091,24 @@ pub trait StateProvider { }; runtime.burn(source_purse, amount) } + HandlePaymentMode::ClearHolds { + source, + holds_epoch, + } => { + let tag = BalanceHoldAddrTag::Gas; + let source_purse = match source.purse_uref(&mut tc.borrow_mut(), protocol_version) { + Ok(value) => value, + Err(tce) => return HandlePaymentResult::Failure(tce), + }; + if let Err(tce) = tc.borrow_mut().clear_expired_balance_holds( + source_purse.addr(), + tag, + holds_epoch, + ) { + return HandlePaymentResult::Failure(tce); + } + Ok(()) + } }; let effects = tc.borrow_mut().effects(); diff --git a/storage/src/system/auction.rs b/storage/src/system/auction.rs index 6223c05160..38eaafc7b9 100644 --- a/storage/src/system/auction.rs +++ b/storage/src/system/auction.rs @@ -18,7 +18,7 @@ use casper_types::{ BidAddr, BidKind, DelegationRate, EraInfo, EraValidators, Error, SeigniorageRecipients, UnbondingPurse, ValidatorBid, ValidatorWeights, DELEGATION_RATE_DENOMINATOR, }, - ApiError, EraId, PublicKey, U512, + ApiError, EraId, HoldsEpoch, PublicKey, U512, }; use self::providers::{AccountProvider, MintProvider, RuntimeProvider, StorageProvider}; @@ -69,7 +69,7 @@ pub trait Auction: public_key: PublicKey, delegation_rate: DelegationRate, amount: U512, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result { if !self.allow_auction_bids() { // The validator set may be closed on some side chains, @@ -213,7 +213,7 @@ pub trait Auction: amount: U512, max_delegators_per_validator: u32, minimum_delegation_amount: u64, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result { if !self.allow_auction_bids() { // Validation set rotation might be disabled on some private chains and we should not diff --git a/storage/src/system/auction/auction_native.rs b/storage/src/system/auction/auction_native.rs index 379fb67960..3cc0698a15 100644 --- a/storage/src/system/auction/auction_native.rs +++ b/storage/src/system/auction/auction_native.rs @@ -18,7 +18,7 @@ use casper_types::{ auction::{BidAddr, BidKind, EraInfo, Error, UnbondingPurse}, mint, }, - CLTyped, CLValue, Key, KeyTag, PublicKey, StoredValue, URef, U512, + CLTyped, CLValue, HoldsEpoch, Key, KeyTag, PublicKey, StoredValue, URef, U512, }; use std::collections::BTreeSet; use tracing::error; @@ -254,7 +254,7 @@ where contract.main_purse(), *unbonding_purse.amount(), None, - None, // unbonding purses do not have holds on them + HoldsEpoch::NOT_APPLICABLE, // unbonding purses do not have holds on them ) .map_err(|_| Error::Transfer)? .map_err(|_| Error::Transfer)?; @@ -272,7 +272,7 @@ where target: URef, amount: U512, id: Option, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result, Error> { if !(self.addressable_entity().main_purse().addr() == source.addr() || self.get_caller() == PublicKey::System.to_account_hash()) @@ -331,7 +331,7 @@ where fn available_balance( &mut self, purse: URef, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result, Error> { match ::balance(self, purse, holds_epoch) { Ok(ret) => Ok(ret), diff --git a/storage/src/system/auction/detail.rs b/storage/src/system/auction/detail.rs index 1e8debd151..b7f43fe563 100644 --- a/storage/src/system/auction/detail.rs +++ b/storage/src/system/auction/detail.rs @@ -11,7 +11,7 @@ use casper_types::{ ValidatorBids, AUCTION_DELAY_KEY, ERA_END_TIMESTAMP_MILLIS_KEY, ERA_ID_KEY, SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY, UNBONDING_DELAY_KEY, VALIDATOR_SLOTS_KEY, }, - ApiError, CLTyped, EraId, Key, KeyTag, PublicKey, URef, U512, + ApiError, CLTyped, EraId, HoldsEpoch, Key, KeyTag, PublicKey, URef, U512, }; use tracing::{error, warn}; @@ -277,7 +277,7 @@ pub fn create_unbonding_purse( new_validator: Option, ) -> Result<(), Error> { if provider - .available_balance(bonding_purse, None)? + .available_balance(bonding_purse, HoldsEpoch::NOT_APPLICABLE)? .unwrap_or_default() < amount { @@ -463,7 +463,7 @@ where *unbonding_purse.amount(), max_delegators_per_validator, minimum_delegation_amount, - None, + HoldsEpoch::NOT_APPLICABLE, ); match redelegation { Ok(_) => Ok(UnbondRedelegationOutcome::SuccessfullyRedelegated), @@ -495,7 +495,7 @@ pub fn handle_delegation

( amount: U512, max_delegators_per_validator: u32, minimum_delegation_amount: u64, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result where P: StorageProvider + MintProvider + RuntimeProvider, diff --git a/storage/src/system/auction/providers.rs b/storage/src/system/auction/providers.rs index 3ef806b263..ff795d499b 100644 --- a/storage/src/system/auction/providers.rs +++ b/storage/src/system/auction/providers.rs @@ -8,7 +8,7 @@ use casper_types::{ auction::{BidAddr, BidKind, EraInfo, Error, UnbondingPurse}, mint, }, - CLTyped, Key, KeyTag, URef, BLAKE2B_DIGEST_LENGTH, U512, + CLTyped, HoldsEpoch, Key, KeyTag, URef, BLAKE2B_DIGEST_LENGTH, U512, }; /// Provider of runtime host functionality. @@ -91,7 +91,7 @@ pub trait MintProvider { target: URef, amount: U512, id: Option, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result, Error>; /// Mint `amount` new token into `existing_purse`. @@ -106,7 +106,7 @@ pub trait MintProvider { fn available_balance( &mut self, purse: URef, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result, Error>; /// Reads the base round reward. diff --git a/storage/src/system/handle_payment.rs b/storage/src/system/handle_payment.rs index 784b405f81..fcced771c6 100644 --- a/storage/src/system/handle_payment.rs +++ b/storage/src/system/handle_payment.rs @@ -4,7 +4,7 @@ pub mod mint_provider; pub mod runtime_provider; pub mod storage_provider; -use casper_types::{system::handle_payment::Error, AccessRights, URef, U512}; +use casper_types::{system::handle_payment::Error, AccessRights, HoldsEpoch, URef, U512}; use crate::system::handle_payment::{ mint_provider::MintProvider, runtime_provider::RuntimeProvider, @@ -44,7 +44,7 @@ pub trait HandlePayment: MintProvider + RuntimeProvider + StorageProvider + Size consumed: U512, source_purse: URef, target_purse: URef, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result<(), Error> { internal::finalize_payment( self, diff --git a/storage/src/system/handle_payment/handle_payment_native.rs b/storage/src/system/handle_payment/handle_payment_native.rs index a9b0491809..6e8d7b4f38 100644 --- a/storage/src/system/handle_payment/handle_payment_native.rs +++ b/storage/src/system/handle_payment/handle_payment_native.rs @@ -14,8 +14,8 @@ use casper_types::{ account::AccountHash, addressable_entity::{NamedKeyAddr, NamedKeyValue}, system::handle_payment::Error, - AccessRights, AddressableEntityHash, CLValue, FeeHandling, GrantedAccess, Key, Phase, - RefundHandling, StoredValue, TransferredTo, URef, U512, + AccessRights, AddressableEntityHash, CLValue, FeeHandling, GrantedAccess, HoldsEpoch, Key, + Phase, RefundHandling, StoredValue, TransferredTo, URef, U512, }; use std::collections::BTreeSet; use tracing::error; @@ -101,8 +101,15 @@ where target: URef, amount: U512, ) -> Result<(), Error> { - let holds_epoch = None; // system purses do not have holds on them - match self.transfer(None, source, target, amount, None, holds_epoch) { + // system purses do not have holds on them + match self.transfer( + None, + source, + target, + amount, + None, + HoldsEpoch::NOT_APPLICABLE, + ) { Ok(ret) => Ok(ret), Err(err) => { error!("{}", err); @@ -114,7 +121,7 @@ where fn available_balance( &mut self, purse: URef, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result, Error> { match ::balance(self, purse, holds_epoch) { Ok(ret) => Ok(ret), diff --git a/storage/src/system/handle_payment/internal.rs b/storage/src/system/handle_payment/internal.rs index d12147613d..6ca8d62dc6 100644 --- a/storage/src/system/handle_payment/internal.rs +++ b/storage/src/system/handle_payment/internal.rs @@ -1,6 +1,6 @@ use casper_types::{ system::handle_payment::{Error, PAYMENT_PURSE_KEY, REFUND_PURSE_KEY}, - FeeHandling, Key, Phase, PublicKey, RefundHandling, URef, U512, + FeeHandling, HoldsEpoch, Key, Phase, PublicKey, RefundHandling, URef, U512, }; use num::{CheckedMul, One}; use num_rational::Ratio; @@ -140,7 +140,7 @@ pub fn finalize_payment( consumed: U512, source_purse: URef, target_purse: URef, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result<(), Error> { let refund_handling = provider.refund_handling(); let fee_handling = provider.fee_handling(); @@ -233,7 +233,7 @@ pub fn burn( amount: Option, ) -> Result<(), Error> { // get the purse total balance (without holds) - let total_balance = match provider.available_balance(purse, None)? { + let total_balance = match provider.available_balance(purse, HoldsEpoch::NOT_APPLICABLE)? { Some(balance) => balance, None => return Err(Error::PaymentPurseBalanceNotFound), }; @@ -277,7 +277,7 @@ where let distribute_amount = match amount { Some(amount) => amount, None => provider - .available_balance(source_uref, None)? + .available_balance(source_uref, HoldsEpoch::NOT_APPLICABLE)? .unwrap_or_default(), }; diff --git a/storage/src/system/handle_payment/mint_provider.rs b/storage/src/system/handle_payment/mint_provider.rs index 6411e33e02..f5f81faf0f 100644 --- a/storage/src/system/handle_payment/mint_provider.rs +++ b/storage/src/system/handle_payment/mint_provider.rs @@ -1,5 +1,5 @@ use casper_types::{ - account::AccountHash, system::handle_payment::Error, TransferredTo, URef, U512, + account::AccountHash, system::handle_payment::Error, HoldsEpoch, TransferredTo, URef, U512, }; /// Provides an access to mint. @@ -30,7 +30,7 @@ pub trait MintProvider { fn available_balance( &mut self, purse: URef, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result, Error>; /// Reduce total supply by `amount`. diff --git a/storage/src/system/mint.rs b/storage/src/system/mint.rs index 7c57454c7c..5acfc83798 100644 --- a/storage/src/system/mint.rs +++ b/storage/src/system/mint.rs @@ -12,7 +12,7 @@ use casper_types::{ mint::{Error, ROUND_SEIGNIORAGE_RATE_KEY, TOTAL_SUPPLY_KEY}, Caller, }, - Key, PublicKey, SystemEntityRegistry, URef, U512, + HoldsEpoch, Key, PublicKey, SystemEntityRegistry, URef, U512, }; use crate::system::mint::{ @@ -86,7 +86,7 @@ pub trait Mint: RuntimeProvider + StorageProvider + SystemProvider { } /// Read balance of given `purse`. - fn balance(&mut self, purse: URef, hold_epoch: Option) -> Result, Error> { + fn balance(&mut self, purse: URef, hold_epoch: HoldsEpoch) -> Result, Error> { match self.available_balance(purse, hold_epoch)? { some @ Some(_) => Ok(some), None => Err(Error::PurseNotFound), @@ -101,7 +101,7 @@ pub trait Mint: RuntimeProvider + StorageProvider + SystemProvider { target: URef, amount: U512, id: Option, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result<(), Error> { if !self.allow_unrestricted_transfers() { let registry = match self.get_system_entity_registry() { @@ -218,7 +218,10 @@ pub trait Mint: RuntimeProvider + StorageProvider + SystemProvider { if amount > source_balance { return Err(Error::InsufficientFunds); } - if self.available_balance(target, None)?.is_none() { + if self + .available_balance(target, HoldsEpoch::NOT_APPLICABLE)? + .is_none() + { return Err(Error::DestNotFound); } if self.get_caller() != PublicKey::System.to_account_hash() @@ -276,7 +279,10 @@ pub trait Mint: RuntimeProvider + StorageProvider + SystemProvider { // treat as noop return Ok(()); } - if self.available_balance(existing_purse, None)?.is_none() { + if self + .available_balance(existing_purse, HoldsEpoch::NOT_APPLICABLE)? + .is_none() + { return Err(Error::PurseNotFound); } self.add_balance(existing_purse, amount)?; diff --git a/storage/src/system/mint/mint_native.rs b/storage/src/system/mint/mint_native.rs index 9b476f8fc1..4286c10ad9 100644 --- a/storage/src/system/mint/mint_native.rs +++ b/storage/src/system/mint/mint_native.rs @@ -16,8 +16,8 @@ use casper_types::{ account::AccountHash, bytesrepr::{FromBytes, ToBytes}, system::{mint::Error, Caller}, - AccessRights, AddressableEntity, CLTyped, CLValue, Gas, InitiatorAddr, Key, Phase, PublicKey, - StoredValue, SystemEntityRegistry, Transfer, TransferV2, URef, U512, + AccessRights, AddressableEntity, CLTyped, CLValue, Gas, HoldsEpoch, InitiatorAddr, Key, Phase, + PublicKey, StoredValue, SystemEntityRegistry, Transfer, TransferV2, URef, U512, }; impl RuntimeProvider for RuntimeNative @@ -172,7 +172,7 @@ where fn available_balance( &mut self, uref: URef, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result, Error> { match self .tracking_copy() diff --git a/storage/src/system/mint/storage_provider.rs b/storage/src/system/mint/storage_provider.rs index b6804175c1..bee74a7daa 100644 --- a/storage/src/system/mint/storage_provider.rs +++ b/storage/src/system/mint/storage_provider.rs @@ -1,7 +1,7 @@ use casper_types::{ bytesrepr::{FromBytes, ToBytes}, system::mint::Error, - CLTyped, URef, U512, + CLTyped, HoldsEpoch, URef, U512, }; /// Provides functionality of a contract storage. @@ -22,7 +22,7 @@ pub trait StorageProvider { fn available_balance( &mut self, uref: URef, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result, Error>; /// Write balance. diff --git a/storage/src/system/transfer.rs b/storage/src/system/transfer.rs index 93b80985f1..78e319a434 100644 --- a/storage/src/system/transfer.rs +++ b/storage/src/system/transfer.rs @@ -6,8 +6,8 @@ use casper_types::{ addressable_entity::NamedKeys, bytesrepr::FromBytes, system::{mint, mint::Error as MintError}, - AccessRights, AddressableEntity, CLType, CLTyped, CLValue, CLValueError, Key, ProtocolVersion, - RuntimeArgs, StoredValue, StoredValueTypeMismatch, URef, U512, + AccessRights, AddressableEntity, CLType, CLTyped, CLValue, CLValueError, HoldsEpoch, Key, + ProtocolVersion, RuntimeArgs, StoredValue, StoredValueTypeMismatch, URef, U512, }; use crate::{ @@ -232,7 +232,7 @@ impl TransferRuntimeArgsBuilder { }; tracking_copy .borrow_mut() - .get_available_balance(key, None) + .get_available_balance(key, HoldsEpoch::NOT_APPLICABLE) .is_ok() } diff --git a/storage/src/tracking_copy/ext.rs b/storage/src/tracking_copy/ext.rs index f62d5b0c8a..801e8c8f33 100644 --- a/storage/src/tracking_copy/ext.rs +++ b/storage/src/tracking_copy/ext.rs @@ -10,8 +10,8 @@ use crate::{ use casper_types::{ account::AccountHash, addressable_entity::NamedKeys, global_state::TrieMerkleProof, system::mint::BalanceHoldAddrTag, BlockTime, ByteCode, ByteCodeAddr, ByteCodeHash, CLValue, - ChecksumRegistry, EntityAddr, Key, KeyTag, Motes, Package, PackageHash, StoredValue, - StoredValueTypeMismatch, SystemEntityRegistry, URef, URefAddr, U512, + ChecksumRegistry, EntityAddr, HoldsEpoch, Key, KeyTag, Motes, Package, PackageHash, + StoredValue, StoredValueTypeMismatch, SystemEntityRegistry, URef, URefAddr, U512, }; use crate::tracking_copy::{TrackingCopy, TrackingCopyError}; @@ -32,7 +32,7 @@ pub trait TrackingCopyExt { fn get_available_balance( &self, balance_key: Key, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result; /// Gets the purse balance key for a given purse and provides a Merkle proof. @@ -47,12 +47,19 @@ pub trait TrackingCopyExt { balance_key: Key, ) -> Result<(U512, TrieMerkleProof), Self::Error>; + /// Clear expired balance holds. + fn clear_expired_balance_holds( + &mut self, + purse_addr: URefAddr, + tag: BalanceHoldAddrTag, + holds_epoch: HoldsEpoch, + ) -> Result<(), Self::Error>; + /// Gets the balance holds for a given balance, with Merkle proofs. fn get_balance_holds_with_proof( &self, purse_addr: URefAddr, - block_time: u64, - hold_interval: u64, + holds_epoch: HoldsEpoch, ) -> Result, Self::Error>; /// Returns the collection of named keys for a given AddressableEntity. @@ -98,7 +105,7 @@ where fn get_available_balance( &self, key: Key, - holds_epoch: Option, + holds_epoch: HoldsEpoch, ) -> Result { let key = { if let Key::URef(uref) = key { @@ -116,7 +123,7 @@ where .try_into() .map_err(TrackingCopyError::TypeMismatch)?; let total_balance = cl_value.into_t::()?; - match holds_epoch { + match holds_epoch.value() { None => Ok(Motes::new(total_balance)), Some(epoch) => { let mut total_holds = U512::zero(); @@ -191,14 +198,36 @@ where } } + fn clear_expired_balance_holds( + &mut self, + purse_addr: URefAddr, + tag: BalanceHoldAddrTag, + holds_epoch: HoldsEpoch, + ) -> Result<(), Self::Error> { + let prefix = tag.purse_prefix_by_tag(purse_addr)?; + let immut: &_ = self; + let gas_hold_keys = immut.keys_with_prefix(&prefix)?; + for gas_hold_key in gas_hold_keys { + if let Some(balance_hold_addr) = gas_hold_key.as_balance_hold() { + let block_time = balance_hold_addr.block_time(); + if let Some(timestamp) = holds_epoch.value() { + if block_time.value() >= timestamp { + // skip still current holds + continue; + } + } + // prune outdated holds + self.prune(gas_hold_key) + } + } + Ok(()) + } + fn get_balance_holds_with_proof( &self, purse_addr: URefAddr, - block_time: u64, - hold_interval: u64, + holds_epoch: HoldsEpoch, ) -> Result, Self::Error> { - let hold_epoch = block_time.saturating_sub(hold_interval); - let mut ret: BTreeMap = BTreeMap::new(); let tag = BalanceHoldAddrTag::Gas; let prefix = tag.purse_prefix_by_tag(purse_addr)?; @@ -207,9 +236,11 @@ where for gas_hold_key in gas_hold_keys { if let Some(balance_hold_addr) = gas_hold_key.as_balance_hold() { let block_time = balance_hold_addr.block_time(); - if block_time.value() < hold_epoch { - // ignore holds older than the interval - continue; + if let Some(timestamp) = holds_epoch.value() { + if block_time.value() < timestamp { + // ignore holds older than the interval + continue; + } } let proof: TrieMerkleProof = self .read_with_proof(&gas_hold_key.normalize())? diff --git a/types/src/block_time.rs b/types/src/block_time.rs index c913371961..4fe4f73533 100644 --- a/types/src/block_time.rs +++ b/types/src/block_time.rs @@ -2,7 +2,7 @@ use alloc::vec::Vec; use crate::{ bytesrepr::{Error, FromBytes, ToBytes, U64_SERIALIZED_LENGTH}, - CLType, CLTyped, Timestamp, + CLType, CLTyped, TimeDiff, Timestamp, }; #[cfg(feature = "datasize")] @@ -14,6 +14,39 @@ use serde::{Deserialize, Serialize}; /// The number of bytes in a serialized [`BlockTime`]. pub const BLOCKTIME_SERIALIZED_LENGTH: usize = U64_SERIALIZED_LENGTH; +/// Holds epoch type. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] +pub struct HoldsEpoch(Option); + +impl HoldsEpoch { + /// No epoch is applicable. + pub const NOT_APPLICABLE: HoldsEpoch = HoldsEpoch(None); + + /// Instance from block time. + pub fn from_block_time(block_time: BlockTime, hold_internal: TimeDiff) -> Self { + HoldsEpoch(Some( + block_time.value().saturating_sub(hold_internal.millis()), + )) + } + + /// Instance from timestamp. + pub fn from_timestamp(timestamp: Timestamp, hold_internal: TimeDiff) -> Self { + HoldsEpoch(Some( + timestamp.millis().saturating_sub(hold_internal.millis()), + )) + } + + /// Instance from milliseconds. + pub fn from_millis(timestamp_millis: u64, hold_internal_millis: u64) -> Self { + HoldsEpoch(Some(timestamp_millis.saturating_sub(hold_internal_millis))) + } + + /// Returns the inner value. + pub fn value(&self) -> Option { + self.0 + } +} + /// A newtype wrapping a [`u64`] which represents the block time. #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] diff --git a/types/src/chainspec/pricing_handling.rs b/types/src/chainspec/pricing_handling.rs index f5548e513e..e7c934daf9 100644 --- a/types/src/chainspec/pricing_handling.rs +++ b/types/src/chainspec/pricing_handling.rs @@ -12,8 +12,8 @@ const PRICING_HANDLING_FIXED_TAG: u8 = 1; const PRICING_HANDLING_TAG_LENGTH: u8 = 1; -/// Defines what pricing mode a network allows. Correlates to the PricingMode of a [`Transaction`]. -/// Nodes will not accept transactions whose pricing mode does not match. +/// Defines what pricing mode a network allows. Correlates to the PricingMode of a +/// [`crate::Transaction`]. Nodes will not accept transactions whose pricing mode does not match. #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(tag = "type", rename_all = "snake_case")] #[cfg_attr(feature = "datasize", derive(DataSize))] diff --git a/types/src/lib.rs b/types/src/lib.rs index 0e50ebf2f6..424445ca62 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -105,7 +105,7 @@ pub use block::{ }; #[cfg(any(all(feature = "std", feature = "testing"), test))] pub use block::{TestBlockBuilder, TestBlockV1Builder}; -pub use block_time::{BlockTime, BLOCKTIME_SERIALIZED_LENGTH}; +pub use block_time::{BlockTime, HoldsEpoch, BLOCKTIME_SERIALIZED_LENGTH}; pub use byte_code::{ByteCode, ByteCodeAddr, ByteCodeHash, ByteCodeKind}; #[cfg(any(feature = "std", test))] @@ -116,10 +116,10 @@ pub use chainspec::{ GenesisConfig, GenesisConfigBuilder, GenesisValidator, GlobalStateUpdate, GlobalStateUpdateConfig, GlobalStateUpdateError, HandlePaymentCosts, HighwayConfig, HostFunction, HostFunctionCost, HostFunctionCosts, LegacyRequiredFinality, MessageLimits, - MintCosts, NetworkConfig, NextUpgrade, OpcodeCosts, ProtocolConfig, ProtocolUpgradeConfig, - RefundHandling, StandardPaymentCosts, StorageCosts, SystemConfig, TransactionConfig, - TransactionV1Config, VacancyConfig, ValidatorConfig, WasmConfig, DEFAULT_BALANCE_HOLD_INTERVAL, - DEFAULT_HOST_FUNCTION_NEW_DICTIONARY, DEFAULT_REFUND_HANDLING, + MintCosts, NetworkConfig, NextUpgrade, OpcodeCosts, PricingHandling, ProtocolConfig, + ProtocolUpgradeConfig, RefundHandling, StandardPaymentCosts, StorageCosts, SystemConfig, + TransactionConfig, TransactionV1Config, VacancyConfig, ValidatorConfig, WasmConfig, + DEFAULT_BALANCE_HOLD_INTERVAL, DEFAULT_HOST_FUNCTION_NEW_DICTIONARY, DEFAULT_REFUND_HANDLING, }; #[cfg(any(all(feature = "std", feature = "testing"), test))] pub use chainspec::{ From 131c6f2c0f186b29e0dfe96e9c2ba259f5f17c24 Mon Sep 17 00:00:00 2001 From: Karan Dhareshwar Date: Thu, 28 Mar 2024 11:26:14 -0500 Subject: [PATCH 54/70] Modify test to account for dynamic pricing --- .../src/components/block_accumulator/tests.rs | 3 +- .../components/contract_runtime/operations.rs | 26 +- node/src/components/contract_runtime/tests.rs | 3 +- node/src/components/contract_runtime/utils.rs | 76 ++--- node/src/components/fetcher/tests.rs | 3 +- node/src/components/gossiper/tests.rs | 3 +- node/src/components/storage.rs | 69 ++--- node/src/components/storage/tests.rs | 7 +- .../components/transaction_acceptor/tests.rs | 3 +- node/src/reactor/main_reactor.rs | 1 + node/src/reactor/main_reactor/tests.rs | 269 +++++++++++------- node/src/types/block/executable_block.rs | 4 +- node/src/types/block/finalized_block.rs | 4 +- types/src/block.rs | 37 ++- types/src/block/block_v2.rs | 4 +- 15 files changed, 324 insertions(+), 188 deletions(-) diff --git a/node/src/components/block_accumulator/tests.rs b/node/src/components/block_accumulator/tests.rs index c6608b3b38..fbcf7153c0 100644 --- a/node/src/components/block_accumulator/tests.rs +++ b/node/src/components/block_accumulator/tests.rs @@ -17,7 +17,7 @@ use tokio::time; use casper_types::{ generate_ed25519_keypair, testing::TestRng, ActivationPoint, BlockV2, ChainNameDigest, Chainspec, ChainspecRawBytes, FinalitySignature, FinalitySignatureV2, ProtocolVersion, - PublicKey, SecretKey, Signature, TestBlockBuilder, U512, + PublicKey, SecretKey, Signature, TestBlockBuilder, TransactionConfig, U512, }; use reactor::ReactorEvent; @@ -197,6 +197,7 @@ impl Reactor for MockReactor { chainspec.core_config.recent_era_count(), Some(registry), false, + TransactionConfig::default(), ) .unwrap(); diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 34c914f3f3..4101679567 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -453,7 +453,7 @@ pub fn execute_finalized_block( ); match scratch_state.distribute_fees(fee_req) { FeeResult::RootNotFound => { - return Err(BlockExecutionError::RootNotFound(state_root_hash)) + return Err(BlockExecutionError::RootNotFound(state_root_hash)); } FeeResult::Failure(fer) => return Err(BlockExecutionError::DistributeFees(fer)), FeeResult::Success { @@ -486,10 +486,10 @@ pub fn execute_finalized_block( ); match scratch_state.distribute_block_rewards(rewards_req) { BlockRewardsResult::RootNotFound => { - return Err(BlockExecutionError::RootNotFound(state_root_hash)) + return Err(BlockExecutionError::RootNotFound(state_root_hash)); } BlockRewardsResult::Failure(bre) => { - return Err(BlockExecutionError::DistributeBlockRewards(bre)) + return Err(BlockExecutionError::DistributeBlockRewards(bre)); } BlockRewardsResult::Success { post_state_hash, .. @@ -513,7 +513,7 @@ pub fn execute_finalized_block( executable_block.era_id.successor(), ) { StepResult::RootNotFound => { - return Err(BlockExecutionError::RootNotFound(state_root_hash)) + return Err(BlockExecutionError::RootNotFound(state_root_hash)); } StepResult::Failure(err) => return Err(BlockExecutionError::Step(err)), StepResult::Success { @@ -651,9 +651,9 @@ pub fn execute_finalized_block( (None, None) => None, ( Some(InternalEraReport { - equivocators, - inactive_validators, - }), + equivocators, + inactive_validators, + }), Some((next_era_validator_weights, next_era_gas_price)), ) => Some(EraEndV2::new( equivocators, @@ -736,8 +736,8 @@ pub(super) fn speculatively_execute( block_header: BlockHeader, transaction: Transaction, ) -> SpeculativeExecutionResult -where - S: StateProvider, + where + S: StateProvider, { let state_root_hash = block_header.state_root_hash(); let block_time = block_header @@ -811,14 +811,14 @@ fn commit_step( /// serialized results are not greater than `ChunkWithProof::CHUNK_SIZE_BYTES`), or otherwise will /// be a Merkle root hash of the chunks derived from the serialized results. pub(crate) fn compute_execution_results_checksum<'a>( - execution_results_iter: impl Iterator + Clone, + execution_results_iter: impl Iterator + Clone, ) -> Result { // Serialize the execution results as if they were `Vec`. let serialized_length = U32_SERIALIZED_LENGTH + execution_results_iter - .clone() - .map(|exec_result| exec_result.serialized_length()) - .sum::(); + .clone() + .map(|exec_result| exec_result.serialized_length()) + .sum::(); let mut serialized = vec![]; serialized .try_reserve_exact(serialized_length) diff --git a/node/src/components/contract_runtime/tests.rs b/node/src/components/contract_runtime/tests.rs index 07cb6eb709..576089a2d9 100644 --- a/node/src/components/contract_runtime/tests.rs +++ b/node/src/components/contract_runtime/tests.rs @@ -9,7 +9,7 @@ use tempfile::TempDir; use casper_types::{ bytesrepr::Bytes, runtime_args, BlockHash, Chainspec, ChainspecRawBytes, Deploy, Digest, EraId, ExecutableDeployItem, PublicKey, SecretKey, TimeDiff, Timestamp, Transaction, - TransactionCategory, U512, + TransactionCategory, TransactionConfig, U512, }; use super::*; @@ -103,6 +103,7 @@ impl reactor::Reactor for Reactor { RECENT_ERA_COUNT, Some(registry), false, + TransactionConfig::default(), ) .unwrap(); diff --git a/node/src/components/contract_runtime/utils.rs b/node/src/components/contract_runtime/utils.rs index 9d7c038c5e..9a7b818bf8 100644 --- a/node/src/components/contract_runtime/utils.rs +++ b/node/src/components/contract_runtime/utils.rs @@ -46,9 +46,9 @@ static INTENSIVE_TASKS_SEMAPHORE: Lazy = /// The task is a closure that takes no arguments and returns a value. /// This function returns a future for that value. pub(super) async fn run_intensive_task(task: T) -> V -where - T: 'static + Send + FnOnce() -> V, - V: 'static + Send + Debug, + where + T: 'static + Send + FnOnce() -> V, + V: 'static + Send + Debug, { // This will never panic since the semaphore is never closed. let _permit = INTENSIVE_TASKS_SEMAPHORE.acquire().await.unwrap(); @@ -78,16 +78,14 @@ pub(super) async fn exec_or_requeue( current_gas_price: u8, ) where REv: From - + From - + From - + From - + From - + Send, + + From + + From + + From + + From + + Send, { debug!("ContractRuntime: execute_finalized_block_or_requeue"); let contract_runtime_metrics = metrics.clone(); - let block_max_install_upgrade_count = - chainspec.transaction_config.block_max_install_upgrade_count; let is_era_end = executable_block.era_report.is_some(); if is_era_end && executable_block.rewards.is_none() { executable_block.rewards = Some(if chainspec.core_config.compute_rewards { @@ -96,7 +94,7 @@ pub(super) async fn exec_or_requeue( chainspec.as_ref(), executable_block.clone(), ) - .await + .await { Ok(rewards) => rewards, Err(e) => { @@ -117,6 +115,8 @@ pub(super) async fn exec_or_requeue( let block_max_standard_count = chainspec.transaction_config.block_max_standard_count; let block_max_mint_count = chainspec.transaction_config.block_max_mint_count; let block_max_auction_count = chainspec.transaction_config.block_max_auction_count; + let block_max_install_upgrade_count = + chainspec.transaction_config.block_max_install_upgrade_count; let go_up = chainspec.vacancy_config.upper_threshold; let go_down = chainspec.vacancy_config.lower_threshold; let max = chainspec.vacancy_config.max_gas_price; @@ -125,10 +125,32 @@ pub(super) async fn exec_or_requeue( let era_id = executable_block.era_id; let block_height = executable_block.height; - let switch_block_transaction_hashes = executable_block.transactions.len() as u64; + let per_block_capacity = { + block_max_install_upgrade_count + + block_max_standard_count + + block_max_mint_count + + block_max_auction_count + } as u64; + + let switch_block_utilization_score = { + let has_hit_slot_limt = { + (executable_block.mint.len() as u32 >= block_max_mint_count) + || (executable_block.auction.len() as u32 >= block_max_auction_count) + || (executable_block.standard.len() as u32 >= block_max_standard_count) + || (executable_block.install_upgrade.len() as u32 + >= block_max_install_upgrade_count) + }; + + if has_hit_slot_limt { + 100u64 + } else { + let num = executable_block.transactions.len() as u64; + Ratio::new(num * 100, per_block_capacity).to_integer() + } + }; let maybe_utilization = effect_builder - .get_block_utilization(era_id, block_height, switch_block_transaction_hashes) + .get_block_utilization(era_id, block_height, switch_block_utilization_score) .await; match maybe_utilization { @@ -137,18 +159,8 @@ pub(super) async fn exec_or_requeue( return fatal!(effect_builder, "{}", error).await; } Some((utilization, block_count)) => { - let per_block_capacity = { - block_max_install_upgrade_count - + block_max_standard_count - + block_max_mint_count - + block_max_auction_count - } as u64; - - let era_score = { - let numerator = utilization * 100; - let denominator = per_block_capacity * block_count; - Ratio::new(numerator, denominator).to_integer() - }; + let era_score = { Ratio::new(utilization, block_count).to_integer() }; + let new_gas_price = if era_score >= go_up { let new_gas_price = current_gas_price + 1; @@ -194,7 +206,7 @@ pub(super) async fn exec_or_requeue( maybe_next_era_gas_price, ) }) - .await + .await { Ok(ret) => ret, Err(error) => { @@ -228,9 +240,9 @@ pub(super) async fn exec_or_requeue( let current_era_id = block.era_id(); if let Some(StepOutcome { - step_effects, - mut upcoming_era_validators, - }) = maybe_step_outcome + step_effects, + mut upcoming_era_validators, + }) = maybe_step_outcome { effect_builder .announce_commit_step_success(current_era_id, step_effects) @@ -312,9 +324,9 @@ pub(super) async fn exec_or_requeue( // We schedule the next block from the queue to be executed: if let Some(QueueItem { - executable_block, - meta_block_state, - }) = next_block + executable_block, + meta_block_state, + }) = next_block { metrics.exec_queue_size.dec(); debug!("ContractRuntime: next block enqueue_block_for_execution"); diff --git a/node/src/components/fetcher/tests.rs b/node/src/components/fetcher/tests.rs index 5ee80f61c9..fcea95e531 100644 --- a/node/src/components/fetcher/tests.rs +++ b/node/src/components/fetcher/tests.rs @@ -13,7 +13,7 @@ use thiserror::Error; use casper_types::{ testing::TestRng, BlockV2, Chainspec, ChainspecRawBytes, FinalitySignatureV2, Transaction, - TransactionHash, TransactionId, + TransactionConfig, TransactionHash, TransactionId, }; use super::*; @@ -295,6 +295,7 @@ impl ReactorTrait for Reactor { chainspec.core_config.unbonding_delay, Some(registry), false, + TransactionConfig::default(), ) .unwrap(); diff --git a/node/src/components/gossiper/tests.rs b/node/src/components/gossiper/tests.rs index a1954ee9f7..78c657bbe6 100644 --- a/node/src/components/gossiper/tests.rs +++ b/node/src/components/gossiper/tests.rs @@ -19,7 +19,7 @@ use tracing::debug; use casper_types::{ testing::TestRng, BlockV2, Chainspec, ChainspecRawBytes, EraId, FinalitySignatureV2, - ProtocolVersion, TimeDiff, Transaction, + ProtocolVersion, TimeDiff, Transaction, TransactionConfig, }; use super::*; @@ -169,6 +169,7 @@ impl reactor::Reactor for Reactor { RECENT_ERA_COUNT, Some(registry), false, + TransactionConfig::default(), ) .unwrap(); diff --git a/node/src/components/storage.rs b/node/src/components/storage.rs index 5f95ffc7a2..326dc46559 100644 --- a/node/src/components/storage.rs +++ b/node/src/components/storage.rs @@ -69,7 +69,7 @@ use casper_types::{ Approval, ApprovalsHash, AvailableBlockRange, Block, BlockBody, BlockHash, BlockHeader, BlockSignatures, BlockSignaturesV1, BlockSignaturesV2, BlockV2, ChainNameDigest, DeployHash, EraId, ExecutionInfo, FinalitySignature, ProtocolVersion, SignedBlockHeader, Timestamp, - Transaction, TransactionHash, TransactionHeader, TransactionId, Transfer, + Transaction, TransactionConfig, TransactionHash, TransactionHeader, TransactionId, Transfer, }; use datasize::DataSize; use prometheus::Registry; @@ -148,6 +148,8 @@ pub struct Storage { max_ttl: MaxTtl, /// The hash of the chain name. chain_name_hash: ChainNameDigest, + /// The transaction config as specified by the chainspec. + transaction_config: TransactionConfig, /// The utilization of blocks. utilization_tracker: BTreeMap>, } @@ -178,8 +180,8 @@ impl Display for HighestOrphanedBlockResult { } impl Component for Storage -where - REv: From + From> + Send, + where + REv: From + From> + Send, { type Event = Event; @@ -245,6 +247,7 @@ impl Storage { recent_era_count: u64, registry: Option<&Registry>, force_resync: bool, + transaction_config: TransactionConfig, ) -> Result { let config = cfg.value(); @@ -289,6 +292,7 @@ impl Storage { utilization_tracker: BTreeMap::new(), metrics, chain_name_hash: ChainNameDigest::from_chain_name(network_name), + transaction_config, }; if force_resync { @@ -392,8 +396,8 @@ impl Storage { effect_builder: EffectBuilder, incoming: &NetRequestIncoming, ) -> Result, GetRequestError> - where - REv: From> + Send, + where + REv: From> + Send, { if self.enable_mem_deduplication { let unique_id = incoming.message.unique_id(); @@ -865,7 +869,7 @@ impl Storage { signature.era_id(), signature.chain_name_hash(), ) - .into(), + .into(), } }; match (&mut block_signatures, *signature) { @@ -960,8 +964,10 @@ impl Storage { responder, } => { let block: Block = (*block).clone().into(); + let transaction_config = self.transaction_config; responder .respond(self.put_executed_block( + transaction_config, &block, &approvals_hashes, execution_results, @@ -1036,7 +1042,7 @@ impl Storage { #[allow(clippy::type_complexity)] fn get_transactions_with_finalized_approvals<'a>( &self, - transaction_hashes: impl Iterator, + transaction_hashes: impl Iterator, ) -> Result>)>; 1]>, FatalStorageError> { let mut ro_txn = self.block_store.checkout_ro()?; @@ -1051,13 +1057,14 @@ impl Storage { pub(crate) fn put_executed_block( &mut self, + transaction_config: TransactionConfig, block: &Block, approvals_hashes: &ApprovalsHashes, execution_results: HashMap, ) -> Result { let mut txn = self.block_store.checkout_rw()?; - let transaction_hash_count = block.transaction_count(); let era_id = block.era_id(); + let block_utilization_score = block.block_utilization(transaction_config); let block_hash = txn.write(block)?; let _ = txn.write(approvals_hashes)?; let block_info = BlockHashHeightAndEra::new(block_hash, block.height(), block.era_id()); @@ -1068,17 +1075,13 @@ impl Storage { })?; txn.commit()?; - if let Some(block_score) = self.utilization_tracker.get_mut(&era_id) { - block_score.insert(block.height(), transaction_hash_count); - }; - match self.utilization_tracker.get_mut(&era_id) { Some(block_score) => { - block_score.insert(block.height(), transaction_hash_count); + block_score.insert(block.height(), block_utilization_score); } None => { let mut block_score = BTreeMap::new(); - block_score.insert(block.height(), transaction_hash_count); + block_score.insert(block.height(), block_utilization_score); self.utilization_tracker.insert(era_id, block_score); } } @@ -1267,8 +1270,8 @@ impl Storage { let mut transactions = vec![]; for (transaction, _) in (self .get_transactions_with_finalized_approvals(block.all_transactions())?) - .into_iter() - .flatten() + .into_iter() + .flatten() { transactions.push(transaction) } @@ -1630,7 +1633,7 @@ impl Storage { fn get_transaction_with_finalized_approvals( &self, txn: &mut (impl DataReader - + DataReader>), + + DataReader>), transaction_hash: &TransactionHash, ) -> Result>)>, FatalStorageError> { let maybe_transaction: Option = txn.read(*transaction_hash)?; @@ -1735,9 +1738,9 @@ impl Storage { serialized_id: &[u8], fetch_response: FetchResponse, ) -> Result, FatalStorageError> - where - REv: From> + Send, - T: FetchItem, + where + REv: From> + Send, + T: FetchItem, { let serialized = fetch_response .to_serialized() @@ -1860,7 +1863,7 @@ impl Storage { block.era_id(), self.chain_name_hash, ) - .into(), + .into(), } } @@ -1927,8 +1930,8 @@ impl Storage { fn get_execution_results_with_transaction_headers( &self, txn: &mut (impl DataReader - + DataReader - + DataReader), + + DataReader + + DataReader), block_hash: &BlockHash, ) -> Result>, FatalStorageError> { @@ -1967,11 +1970,11 @@ impl Storage { &mut self, era_id: EraId, block_height: u64, - transaction_count: u64, + block_utilization: u64, ) -> Option<(u64, u64)> { let ret = match self.utilization_tracker.get_mut(&era_id) { Some(utilization) => { - utilization.entry(block_height).or_insert(transaction_count); + utilization.entry(block_height).or_insert(block_utilization); let transaction_count = utilization.values().into_iter().sum(); let block_count = utilization.keys().len() as u64; @@ -1980,12 +1983,12 @@ impl Storage { } None => { let mut utilization = BTreeMap::new(); - utilization.insert(block_height, transaction_count); + utilization.insert(block_height, block_utilization); self.utilization_tracker.insert(era_id, utilization); let block_count = 1u64; - Some((transaction_count, block_count)) + Some((block_utilization, block_count)) } }; @@ -1998,8 +2001,8 @@ impl Storage { /// Decodes an item's ID, typically from an incoming request. fn decode_item_id(raw: &[u8]) -> Result -where - T: FetchItem, + where + T: FetchItem, { bincode::deserialize(raw).map_err(GetRequestError::MalformedIncomingItemId) } @@ -2078,10 +2081,10 @@ fn successful_transfers(execution_result: &ExecutionResult) -> Vec { } } ExecutionResult::V2(ExecutionResultV2 { - transfers, - error_message, - .. - }) => { + transfers, + error_message, + .. + }) => { if error_message.is_none() { for transfer in transfers { all_transfers.push(transfer.clone()); diff --git a/node/src/components/storage/tests.rs b/node/src/components/storage/tests.rs index d88ce58972..e45cec5c4a 100644 --- a/node/src/components/storage/tests.rs +++ b/node/src/components/storage/tests.rs @@ -27,7 +27,8 @@ use casper_types::{ BlockSignaturesV2, BlockV2, ChainNameDigest, Chainspec, ChainspecRawBytes, Deploy, DeployHash, Digest, EraId, ExecutionInfo, FinalitySignature, FinalitySignatureV2, Gas, InitiatorAddr, ProtocolVersion, PublicKey, SecretKey, SignedBlockHeader, TestBlockBuilder, TestBlockV1Builder, - TimeDiff, Transaction, TransactionHash, TransactionV1Hash, Transfer, TransferV2, U512, + TimeDiff, Transaction, TransactionConfig, TransactionHash, TransactionV1Hash, Transfer, + TransferV2, U512, }; use tempfile::tempdir; @@ -193,6 +194,7 @@ fn storage_fixture(harness: &ComponentHarness) -> Storage { RECENT_ERA_COUNT, None, false, + TransactionConfig::default(), ) .expect("could not create storage component fixture") } @@ -223,6 +225,7 @@ fn storage_fixture_from_parts( recent_era_count.unwrap_or(RECENT_ERA_COUNT), None, false, + TransactionConfig::default(), ) .expect("could not create storage component fixture from parts") } @@ -245,6 +248,7 @@ fn storage_fixture_with_force_resync(cfg: &WithDir) -> Storage { RECENT_ERA_COUNT, None, true, + TransactionConfig::default(), ) .expect("could not create storage component fixture") } @@ -1782,6 +1786,7 @@ fn should_create_subdir_named_after_network() { RECENT_ERA_COUNT, None, false, + TransactionConfig::default(), ) .unwrap(); diff --git a/node/src/components/transaction_acceptor/tests.rs b/node/src/components/transaction_acceptor/tests.rs index a3acea9b30..51b9c1a0e4 100644 --- a/node/src/components/transaction_acceptor/tests.rs +++ b/node/src/components/transaction_acceptor/tests.rs @@ -34,7 +34,7 @@ use casper_types::{ Block, BlockV2, CLValue, Chainspec, ChainspecRawBytes, Contract, Deploy, EraId, HashAddr, InvalidDeploy, InvalidTransaction, InvalidTransactionV1, Package, PricingMode, ProtocolVersion, PublicKey, SecretKey, StoredValue, TestBlockBuilder, TimeDiff, Timestamp, Transaction, - TransactionSessionKind, TransactionV1, TransactionV1Builder, URef, U512, + TransactionConfig, TransactionSessionKind, TransactionV1, TransactionV1Builder, URef, U512, }; use super::*; @@ -910,6 +910,7 @@ impl reactor::Reactor for Reactor { chainspec.core_config.recent_era_count(), Some(registry), false, + TransactionConfig::default(), ) .unwrap(); diff --git a/node/src/reactor/main_reactor.rs b/node/src/reactor/main_reactor.rs index 8159a2edcf..f9255e9926 100644 --- a/node/src/reactor/main_reactor.rs +++ b/node/src/reactor/main_reactor.rs @@ -1111,6 +1111,7 @@ impl reactor::Reactor for MainReactor { chainspec.core_config.recent_era_count(), Some(registry), config.node.force_resync, + chainspec.transaction_config.clone(), )?; let contract_runtime = ContractRuntime::new( diff --git a/node/src/reactor/main_reactor/tests.rs b/node/src/reactor/main_reactor/tests.rs index 16187cd9b8..8951f2c1dd 100644 --- a/node/src/reactor/main_reactor/tests.rs +++ b/node/src/reactor/main_reactor/tests.rs @@ -20,22 +20,16 @@ use tokio::time::{self, error::Elapsed}; use tracing::{error, info}; use casper_storage::{ - data_access_layer::{BidsRequest, BidsResult, TotalSupplyRequest, TotalSupplyResult}, - global_state::state::{StateProvider, StateReader}, -}; -use casper_types::{ - execution::{ExecutionResult, ExecutionResultV2, TransformKindV2, TransformV2}, - system::{ - auction::{BidAddr, BidKind, BidsExt, DelegationRate}, - AUCTION, + data_access_layer::{ + balance::BalanceHandling, BalanceRequest, BalanceResult, BidsRequest, BidsResult, + TotalSupplyRequest, TotalSupplyResult, }, - testing::TestRng, - AccountConfig, AccountsConfig, ActivationPoint, AddressableEntityHash, AvailableBlockRange, - Block, BlockHash, BlockHeader, BlockV2, CLValue, Chainspec, ChainspecRawBytes, - ConsensusProtocolName, Deploy, EraId, Key, Motes, NextUpgrade, ProtocolVersion, PublicKey, - Rewards, SecretKey, StoredValue, SystemEntityRegistry, TimeDiff, Timestamp, Transaction, - TransactionHash, ValidatorConfig, U512, + global_state::state::{StateProvider, StateReader}, }; +use casper_types::{execution::{ExecutionResult, ExecutionResultV2, TransformKindV2, TransformV2}, system::{ + auction::{BidAddr, BidKind, BidsExt, DelegationRate}, + AUCTION, +}, testing::TestRng, AccessRights, AccountConfig, AccountsConfig, ActivationPoint, AddressableEntityHash, AvailableBlockRange, Block, BlockHash, BlockHeader, BlockV2, CLValue, Chainspec, ChainspecRawBytes, ConsensusProtocolName, Deploy, EraId, Key, Motes, NextUpgrade, PricingMode, ProtocolVersion, PublicKey, Rewards, SecretKey, StoredValue, SystemEntityRegistry, TimeDiff, Timestamp, Transaction, TransactionHash, TransactionV1Builder, URef, ValidatorConfig, U512, HoldsEpoch}; use crate::{ components::{ @@ -432,8 +426,8 @@ impl TestFixture { /// /// Returns an error if the condition isn't met in time. async fn try_run_until(&mut self, condition: F, within: Duration) -> Result<(), Elapsed> - where - F: Fn(&Nodes) -> bool, + where + F: Fn(&Nodes) -> bool, { self.network .try_settle_on(&mut self.rng, condition, within) @@ -444,8 +438,8 @@ impl TestFixture { /// /// Panics if the condition isn't met in time. async fn run_until(&mut self, condition: F, within: Duration) - where - F: Fn(&Nodes) -> bool, + where + F: Fn(&Nodes) -> bool, { self.network .settle_on(&mut self.rng, condition, within) @@ -474,7 +468,7 @@ impl TestFixture { }, within, ) - .await + .await } /// Runs the network until all nodes reach the given completed block height. @@ -504,14 +498,14 @@ impl TestFixture { }, within, ) - .await - .unwrap_or_else(|_| { - panic!( - "should reach {} within {} seconds", - era_id, - within.as_secs_f64(), - ) - }) + .await + .unwrap_or_else(|_| { + panic!( + "should reach {} within {} seconds", + era_id, + within.as_secs_f64(), + ) + }) } /// Runs the network until all nodes' storage components have stored the switch block header for @@ -533,14 +527,14 @@ impl TestFixture { }, within, ) - .await - .unwrap_or_else(|_| { - panic!( - "should have stored switch block header for {} within {} seconds", - era_id, - within.as_secs_f64(), - ) - }) + .await + .unwrap_or_else(|_| { + panic!( + "should have stored switch block header for {} within {} seconds", + era_id, + within.as_secs_f64(), + ) + }) } /// Runs the network until all nodes have executed the given transaction and stored the @@ -564,14 +558,14 @@ impl TestFixture { }, within, ) - .await - .unwrap_or_else(|_| { - panic!( - "should have stored execution result for {} within {} seconds", - txn_hash, - within.as_secs_f64(), - ) - }) + .await + .unwrap_or_else(|_| { + panic!( + "should have stored execution result for {} within {} seconds", + txn_hash, + within.as_secs_f64(), + ) + }) } async fn schedule_upgrade_for_era_two(&mut self) { @@ -697,6 +691,52 @@ impl TestFixture { price.gas_price() } + #[track_caller] + fn check_account_balance_at_tip(&self, account_public_key: PublicKey) -> (URef, U512) { + let (_, runner) = self + .network + .nodes() + .iter() + .next() + .expect("must have runner"); + + let highest_block = runner + .main_reactor() + .storage + .read_highest_block() + .expect("should have block"); + + let block_time = highest_block.clone_header().timestamp(); + + let holds_epoch = + HoldsEpoch::from_timestamp(block_time, self.chainspec.core_config.balance_hold_interval); + + let balance_request = BalanceRequest::from_public_key( + *highest_block.state_root_hash(), + highest_block.protocol_version(), + account_public_key, + BalanceHandling::Available { holds_epoch }, + ); + + let balance_result = runner + .main_reactor() + .contract_runtime + .data_access_layer() + .balance(balance_request); + + if let BalanceResult::Success { + purse_addr, + available_balance, + .. + } = balance_result + { + let purse = URef::new(purse_addr, AccessRights::all()); + return (purse, available_balance); + } else { + panic!("failed balance result") + } + } + async fn inject_transaction(&mut self, txn: Transaction) { // saturate the network with the transactions via just making them all store and accept it // they're all validators so one of them should propose it @@ -741,11 +781,11 @@ impl TestFixture { { ExecutionResult::V1(_) => unreachable!(), ExecutionResult::V2(ExecutionResultV2 { - effects, - consumed: gas, - error_message, - .. - }) => { + effects, + consumed: gas, + error_message, + .. + }) => { if error_message.is_none() { effects.transforms().to_vec() } else { @@ -766,7 +806,7 @@ impl TestFixture { pub fn run_until_stopped( self, rng: TestRng, - ) -> impl futures::Future>, TestRng)> { + ) -> impl futures::Future>, TestRng)> { self.network.crank_until_stopped(rng) } } @@ -1437,10 +1477,10 @@ async fn empty_block_validation_regression() { .inner_mut() .set_filter(move |event| match event { MainEvent::Consensus(consensus::Event::NewBlockPayload(NewBlockPayload { - era_id, - block_payload: _, - block_context, - })) => { + era_id, + block_payload: _, + block_context, + })) => { info!("Accusing everyone else!"); // We hook into the NewBlockPayload event to replace the block being proposed with // an empty one that accuses all the validators, except the malicious validator. @@ -1833,10 +1873,13 @@ async fn rewards_are_calculated() { const STAKE: u128 = 1000000000; const PRIME_STAKES: [u128; 5] = [106907, 106921, 106937, 106949, 106957]; const ERA_COUNT: u64 = 3; -const ERA_DURATION: u64 = 20000; //milliseconds +const ERA_DURATION: u64 = 20000; +//milliseconds const MIN_HEIGHT: u64 = 6; -const BLOCK_TIME: u64 = 2000; //milliseconds -const TIME_OUT: u64 = 600; //seconds +const BLOCK_TIME: u64 = 2000; +//milliseconds +const TIME_OUT: u64 = 600; +//seconds const SEIGNIORAGE: (u64, u64) = (1u64, 100u64); const REPRESENTATIVE_NODE_INDEX: usize = 0; // Parameters we generally want to vary @@ -2009,16 +2052,16 @@ async fn run_rewards_network_scenario( let rewarded_blocks = &blocks[rewarded_range]; let block_reward = (Ratio::::one() - fixture - .chainspec - .core_config - .finality_signature_proportion - .into_u512()) + .chainspec + .core_config + .finality_signature_proportion + .into_u512()) * recomputed_total_supply[&(i - 1)] * fixture - .chainspec - .core_config - .round_seigniorage_rate - .into_u512(); + .chainspec + .core_config + .round_seigniorage_rate + .into_u512(); let signatures_reward = fixture .chainspec .core_config @@ -2026,10 +2069,10 @@ async fn run_rewards_network_scenario( .into_u512() * recomputed_total_supply[&(i - 1)] * fixture - .chainspec - .core_config - .round_seigniorage_rate - .into_u512(); + .chainspec + .core_config + .round_seigniorage_rate + .into_u512(); let previous_signatures_reward = if switch_blocks.headers[i - 1].is_genesis() { None } else { @@ -2041,10 +2084,10 @@ async fn run_rewards_network_scenario( .into_u512() * recomputed_total_supply[&(i - 2)] * fixture - .chainspec - .core_config - .round_seigniorage_rate - .into_u512(), + .chainspec + .core_config + .round_seigniorage_rate + .into_u512(), ) }; @@ -2192,8 +2235,8 @@ async fn run_rewards_network_scenario( .get(era) .expect("expected recalculated supply") - recomputed_total_supply - .get(&(era - 1)) - .expect("expected recalculated supply"), + .get(&(era - 1)) + .expect("expected recalculated supply"), "supply growth does not match rewards at era {}", era ) @@ -2222,7 +2265,7 @@ async fn run_reward_network_zug_all_finality_small_prime_five_eras() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2246,7 +2289,7 @@ async fn run_reward_network_zug_all_finality_small_prime_five_eras_no_lookback() ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2270,7 +2313,7 @@ async fn run_reward_network_zug_no_finality_small_nominal_five_eras() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2294,7 +2337,7 @@ async fn run_reward_network_zug_half_finality_half_finders_small_nominal_five_er ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2318,7 +2361,7 @@ async fn run_reward_network_zug_half_finality_half_finders_small_nominal_five_er ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2342,7 +2385,7 @@ async fn run_reward_network_zug_all_finality_half_finders_small_nominal_five_era ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2368,7 +2411,7 @@ async fn run_reward_network_zug_all_finality_half_finders() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2394,7 +2437,7 @@ async fn run_reward_network_zug_all_finality_half_finders_five_eras() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2420,7 +2463,7 @@ async fn run_reward_network_zug_all_finality_zero_finders() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2446,7 +2489,7 @@ async fn run_reward_network_highway_all_finality_zero_finders() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2472,7 +2515,7 @@ async fn run_reward_network_highway_no_finality() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2492,9 +2535,6 @@ async fn should_raise_gas_price_to_ceiling_and_reduce_to_floor() { minimum_era_height: 5, lower_threshold: 0, upper_threshold: 1, - max_standard_count: 1, - max_staking_count: 1, - max_install_count: 1, max_transfer_count: 1, max_gas_price, ..Default::default() @@ -2511,22 +2551,28 @@ async fn should_raise_gas_price_to_ceiling_and_reduce_to_floor() { let switch_block = fixture.switch_block(ERA_ONE); let mut current_era = switch_block.era_id(); + let chain_name = fixture.chainspec.network_config.name.clone(); + let (purse, _) = fixture.check_account_balance_at_tip(alice_public_key.clone()); // Run the network at load for at least 5 eras. for _ in 0..5 { let target_public_key = PublicKey::random(&mut fixture.rng); - let mut native_transfer = Deploy::native_transfer( - fixture.chainspec.network_config.name.clone(), - alice_public_key.clone(), + let fixed_native_mint_transaction = TransactionV1Builder::new_transfer( + 10_000_000_000u64, + Some(purse), target_public_key, None, - Timestamp::now(), - TimeDiff::from_seconds(1200), - max_gas_price as u64, - ); + ) + .expect("must get builder") + .with_chain_name(chain_name.clone()) + .with_secret_key(&alice_secret_key) + .with_pricing_mode(PricingMode::Fixed { + gas_price_tolerance: max_gas_price, + }) + .build() + .expect("must get transaction"); - native_transfer.sign(&alice_secret_key); - let txn = Transaction::Deploy(native_transfer); + let txn = Transaction::V1(fixed_native_mint_transaction); fixture.inject_transaction(txn).await; let next_era = current_era.successor(); fixture @@ -2538,6 +2584,35 @@ async fn should_raise_gas_price_to_ceiling_and_reduce_to_floor() { let expected_gas_price = fixture.chainspec.vacancy_config.max_gas_price; let actual_gas_price = fixture.get_current_era_price(); assert_eq!(actual_gas_price, expected_gas_price); + let target_public_key = PublicKey::random(&mut fixture.rng); + + let fixed_native_mint_transaction = + TransactionV1Builder::new_transfer(10_000_000_000u64, Some(purse), target_public_key, None) + .expect("must get builder") + .with_chain_name(chain_name) + .with_secret_key(&alice_secret_key) + .with_pricing_mode(PricingMode::Fixed { + gas_price_tolerance: max_gas_price, + }) + .build() + .expect("must get transaction"); + + let txn = Transaction::V1(fixed_native_mint_transaction); + let txn_hash = txn.hash(); + + let (_, balance_before) = fixture.check_account_balance_at_tip(alice_public_key.clone()); + + fixture.inject_transaction(txn).await; + fixture + .run_until_executed_transaction(&txn_hash, TEN_SECS) + .await; + + + let (_, balance_after) = fixture.check_account_balance_at_tip(alice_public_key.clone()); + + let current_gas_price = fixture.highest_complete_block().maybe_current_gas_price().expect("must have gas price"); + let cost = fixture.chainspec.system_costs_config.mint_costs().transfer * (current_gas_price as u32); + assert_eq!(balance_before, balance_after + U512::from(cost)); // Run the network at zero load and ensure the value falls back to the floor. for _ in 0..5 { diff --git a/node/src/types/block/executable_block.rs b/node/src/types/block/executable_block.rs index ded26c6c43..5272304c8f 100644 --- a/node/src/types/block/executable_block.rs +++ b/node/src/types/block/executable_block.rs @@ -73,8 +73,8 @@ impl ExecutableBlock { height: block.height(), proposer: Box::new(block.proposer().clone()), transactions, - mint: block.transfer().copied().collect(), - auction: block.staking().copied().collect(), + mint: block.mint().copied().collect(), + auction: block.auction().copied().collect(), install_upgrade: block.install_upgrade().copied().collect(), standard: block.standard().copied().collect(), rewards: block.era_end().map(|era_end| era_end.rewards().clone()), diff --git a/node/src/types/block/finalized_block.rs b/node/src/types/block/finalized_block.rs index b917fd000b..0cbef73e3e 100644 --- a/node/src/types/block/finalized_block.rs +++ b/node/src/types/block/finalized_block.rs @@ -149,8 +149,8 @@ impl FinalizedBlock { impl From for FinalizedBlock { fn from(block: BlockV2) -> Self { FinalizedBlock { - mint: block.transfer().copied().collect(), - auction: block.staking().copied().collect(), + mint: block.mint().copied().collect(), + auction: block.auction().copied().collect(), install_upgrade: block.install_upgrade().copied().collect(), standard: block.standard().copied().collect(), timestamp: block.timestamp(), diff --git a/types/src/block.rs b/types/src/block.rs index 273ed87da3..306c09b45e 100644 --- a/types/src/block.rs +++ b/types/src/block.rs @@ -29,6 +29,7 @@ use std::error::Error as StdError; #[cfg(feature = "datasize")] use datasize::DataSize; +use num_rational::Ratio; #[cfg(feature = "json-schema")] use schemars::JsonSchema; @@ -36,7 +37,7 @@ use schemars::JsonSchema; use crate::{ bytesrepr, bytesrepr::{FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, - Digest, EraId, ProtocolVersion, PublicKey, Timestamp, + Digest, EraId, ProtocolVersion, PublicKey, Timestamp, TransactionConfig, }; pub use available_block_range::AvailableBlockRange; pub use block_body::{BlockBody, BlockBodyV1, BlockBodyV2}; @@ -393,6 +394,40 @@ impl Block { } } + /// Returns the utilization of the block against a given chainspec. + pub fn block_utilization(&self, transaction_config: TransactionConfig) -> u64 { + match self { + Block::V1(_) => { + // We shouldnt be tracking this for legacy blocks + 0 + } + Block::V2(block_v2) => { + let has_hit_slot_limt = { + (block_v2.mint().count() as u32 >= transaction_config.block_max_mint_count) + || (block_v2.auction().count() as u32 + >= transaction_config.block_max_auction_count) + || (block_v2.standard().count() as u32 + >= transaction_config.block_max_standard_count) + || (block_v2.install_upgrade().count() as u32 + >= transaction_config.block_max_install_upgrade_count) + }; + + let per_block_capacity = (transaction_config.block_max_mint_count + + transaction_config.block_max_auction_count + + transaction_config.block_max_standard_count + + transaction_config.block_max_install_upgrade_count) + as u64; + + if has_hit_slot_limt { + 100u64 + } else { + let num = block_v2.all_transactions().count() as u64; + Ratio::new(num * 100, per_block_capacity).to_integer() + } + } + } + } + // This method is not intended to be used by third party crates. #[doc(hidden)] #[cfg(feature = "json-schema")] diff --git a/types/src/block/block_v2.rs b/types/src/block/block_v2.rs index 793b36f028..e8eeff694d 100644 --- a/types/src/block/block_v2.rs +++ b/types/src/block/block_v2.rs @@ -242,12 +242,12 @@ impl BlockV2 { } /// Returns the hashes of the transfer transactions within the block. - pub fn transfer(&self) -> impl Iterator { + pub fn mint(&self) -> impl Iterator { self.body.mint() } /// Returns the hashes of the non-transfer, native transactions within the block. - pub fn staking(&self) -> impl Iterator { + pub fn auction(&self) -> impl Iterator { self.body.auction() } From df49d5e8535214decadcf41458cc4d0b63015553 Mon Sep 17 00:00:00 2001 From: Karan Dhareshwar Date: Thu, 28 Mar 2024 11:27:24 -0500 Subject: [PATCH 55/70] Run make format --- .../components/contract_runtime/operations.rs | 18 +- node/src/components/contract_runtime/utils.rs | 35 ++-- node/src/components/storage.rs | 42 ++-- node/src/reactor/main_reactor/tests.rs | 185 ++++++++++-------- 4 files changed, 147 insertions(+), 133 deletions(-) diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 4101679567..62ff7514ea 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -651,9 +651,9 @@ pub fn execute_finalized_block( (None, None) => None, ( Some(InternalEraReport { - equivocators, - inactive_validators, - }), + equivocators, + inactive_validators, + }), Some((next_era_validator_weights, next_era_gas_price)), ) => Some(EraEndV2::new( equivocators, @@ -736,8 +736,8 @@ pub(super) fn speculatively_execute( block_header: BlockHeader, transaction: Transaction, ) -> SpeculativeExecutionResult - where - S: StateProvider, +where + S: StateProvider, { let state_root_hash = block_header.state_root_hash(); let block_time = block_header @@ -811,14 +811,14 @@ fn commit_step( /// serialized results are not greater than `ChunkWithProof::CHUNK_SIZE_BYTES`), or otherwise will /// be a Merkle root hash of the chunks derived from the serialized results. pub(crate) fn compute_execution_results_checksum<'a>( - execution_results_iter: impl Iterator + Clone, + execution_results_iter: impl Iterator + Clone, ) -> Result { // Serialize the execution results as if they were `Vec`. let serialized_length = U32_SERIALIZED_LENGTH + execution_results_iter - .clone() - .map(|exec_result| exec_result.serialized_length()) - .sum::(); + .clone() + .map(|exec_result| exec_result.serialized_length()) + .sum::(); let mut serialized = vec![]; serialized .try_reserve_exact(serialized_length) diff --git a/node/src/components/contract_runtime/utils.rs b/node/src/components/contract_runtime/utils.rs index 9a7b818bf8..8675cb3ec5 100644 --- a/node/src/components/contract_runtime/utils.rs +++ b/node/src/components/contract_runtime/utils.rs @@ -46,9 +46,9 @@ static INTENSIVE_TASKS_SEMAPHORE: Lazy = /// The task is a closure that takes no arguments and returns a value. /// This function returns a future for that value. pub(super) async fn run_intensive_task(task: T) -> V - where - T: 'static + Send + FnOnce() -> V, - V: 'static + Send + Debug, +where + T: 'static + Send + FnOnce() -> V, + V: 'static + Send + Debug, { // This will never panic since the semaphore is never closed. let _permit = INTENSIVE_TASKS_SEMAPHORE.acquire().await.unwrap(); @@ -78,11 +78,11 @@ pub(super) async fn exec_or_requeue( current_gas_price: u8, ) where REv: From - + From - + From - + From - + From - + Send, + + From + + From + + From + + From + + Send, { debug!("ContractRuntime: execute_finalized_block_or_requeue"); let contract_runtime_metrics = metrics.clone(); @@ -94,7 +94,7 @@ pub(super) async fn exec_or_requeue( chainspec.as_ref(), executable_block.clone(), ) - .await + .await { Ok(rewards) => rewards, Err(e) => { @@ -138,7 +138,7 @@ pub(super) async fn exec_or_requeue( || (executable_block.auction.len() as u32 >= block_max_auction_count) || (executable_block.standard.len() as u32 >= block_max_standard_count) || (executable_block.install_upgrade.len() as u32 - >= block_max_install_upgrade_count) + >= block_max_install_upgrade_count) }; if has_hit_slot_limt { @@ -161,7 +161,6 @@ pub(super) async fn exec_or_requeue( Some((utilization, block_count)) => { let era_score = { Ratio::new(utilization, block_count).to_integer() }; - let new_gas_price = if era_score >= go_up { let new_gas_price = current_gas_price + 1; if new_gas_price > max { @@ -206,7 +205,7 @@ pub(super) async fn exec_or_requeue( maybe_next_era_gas_price, ) }) - .await + .await { Ok(ret) => ret, Err(error) => { @@ -240,9 +239,9 @@ pub(super) async fn exec_or_requeue( let current_era_id = block.era_id(); if let Some(StepOutcome { - step_effects, - mut upcoming_era_validators, - }) = maybe_step_outcome + step_effects, + mut upcoming_era_validators, + }) = maybe_step_outcome { effect_builder .announce_commit_step_success(current_era_id, step_effects) @@ -324,9 +323,9 @@ pub(super) async fn exec_or_requeue( // We schedule the next block from the queue to be executed: if let Some(QueueItem { - executable_block, - meta_block_state, - }) = next_block + executable_block, + meta_block_state, + }) = next_block { metrics.exec_queue_size.dec(); debug!("ContractRuntime: next block enqueue_block_for_execution"); diff --git a/node/src/components/storage.rs b/node/src/components/storage.rs index 326dc46559..41849aaeb0 100644 --- a/node/src/components/storage.rs +++ b/node/src/components/storage.rs @@ -180,8 +180,8 @@ impl Display for HighestOrphanedBlockResult { } impl Component for Storage - where - REv: From + From> + Send, +where + REv: From + From> + Send, { type Event = Event; @@ -396,8 +396,8 @@ impl Storage { effect_builder: EffectBuilder, incoming: &NetRequestIncoming, ) -> Result, GetRequestError> - where - REv: From> + Send, + where + REv: From> + Send, { if self.enable_mem_deduplication { let unique_id = incoming.message.unique_id(); @@ -869,7 +869,7 @@ impl Storage { signature.era_id(), signature.chain_name_hash(), ) - .into(), + .into(), } }; match (&mut block_signatures, *signature) { @@ -1042,7 +1042,7 @@ impl Storage { #[allow(clippy::type_complexity)] fn get_transactions_with_finalized_approvals<'a>( &self, - transaction_hashes: impl Iterator, + transaction_hashes: impl Iterator, ) -> Result>)>; 1]>, FatalStorageError> { let mut ro_txn = self.block_store.checkout_ro()?; @@ -1270,8 +1270,8 @@ impl Storage { let mut transactions = vec![]; for (transaction, _) in (self .get_transactions_with_finalized_approvals(block.all_transactions())?) - .into_iter() - .flatten() + .into_iter() + .flatten() { transactions.push(transaction) } @@ -1633,7 +1633,7 @@ impl Storage { fn get_transaction_with_finalized_approvals( &self, txn: &mut (impl DataReader - + DataReader>), + + DataReader>), transaction_hash: &TransactionHash, ) -> Result>)>, FatalStorageError> { let maybe_transaction: Option = txn.read(*transaction_hash)?; @@ -1738,9 +1738,9 @@ impl Storage { serialized_id: &[u8], fetch_response: FetchResponse, ) -> Result, FatalStorageError> - where - REv: From> + Send, - T: FetchItem, + where + REv: From> + Send, + T: FetchItem, { let serialized = fetch_response .to_serialized() @@ -1863,7 +1863,7 @@ impl Storage { block.era_id(), self.chain_name_hash, ) - .into(), + .into(), } } @@ -1930,8 +1930,8 @@ impl Storage { fn get_execution_results_with_transaction_headers( &self, txn: &mut (impl DataReader - + DataReader - + DataReader), + + DataReader + + DataReader), block_hash: &BlockHash, ) -> Result>, FatalStorageError> { @@ -2001,8 +2001,8 @@ impl Storage { /// Decodes an item's ID, typically from an incoming request. fn decode_item_id(raw: &[u8]) -> Result - where - T: FetchItem, +where + T: FetchItem, { bincode::deserialize(raw).map_err(GetRequestError::MalformedIncomingItemId) } @@ -2081,10 +2081,10 @@ fn successful_transfers(execution_result: &ExecutionResult) -> Vec { } } ExecutionResult::V2(ExecutionResultV2 { - transfers, - error_message, - .. - }) => { + transfers, + error_message, + .. + }) => { if error_message.is_none() { for transfer in transfers { all_transfers.push(transfer.clone()); diff --git a/node/src/reactor/main_reactor/tests.rs b/node/src/reactor/main_reactor/tests.rs index 8951f2c1dd..8399debd1d 100644 --- a/node/src/reactor/main_reactor/tests.rs +++ b/node/src/reactor/main_reactor/tests.rs @@ -26,10 +26,20 @@ use casper_storage::{ }, global_state::state::{StateProvider, StateReader}, }; -use casper_types::{execution::{ExecutionResult, ExecutionResultV2, TransformKindV2, TransformV2}, system::{ - auction::{BidAddr, BidKind, BidsExt, DelegationRate}, - AUCTION, -}, testing::TestRng, AccessRights, AccountConfig, AccountsConfig, ActivationPoint, AddressableEntityHash, AvailableBlockRange, Block, BlockHash, BlockHeader, BlockV2, CLValue, Chainspec, ChainspecRawBytes, ConsensusProtocolName, Deploy, EraId, Key, Motes, NextUpgrade, PricingMode, ProtocolVersion, PublicKey, Rewards, SecretKey, StoredValue, SystemEntityRegistry, TimeDiff, Timestamp, Transaction, TransactionHash, TransactionV1Builder, URef, ValidatorConfig, U512, HoldsEpoch}; +use casper_types::{ + execution::{ExecutionResult, ExecutionResultV2, TransformKindV2, TransformV2}, + system::{ + auction::{BidAddr, BidKind, BidsExt, DelegationRate}, + AUCTION, + }, + testing::TestRng, + AccessRights, AccountConfig, AccountsConfig, ActivationPoint, AddressableEntityHash, + AvailableBlockRange, Block, BlockHash, BlockHeader, BlockV2, CLValue, Chainspec, + ChainspecRawBytes, ConsensusProtocolName, Deploy, EraId, HoldsEpoch, Key, Motes, NextUpgrade, + PricingMode, ProtocolVersion, PublicKey, Rewards, SecretKey, StoredValue, SystemEntityRegistry, + TimeDiff, Timestamp, Transaction, TransactionHash, TransactionV1Builder, URef, ValidatorConfig, + U512, +}; use crate::{ components::{ @@ -426,8 +436,8 @@ impl TestFixture { /// /// Returns an error if the condition isn't met in time. async fn try_run_until(&mut self, condition: F, within: Duration) -> Result<(), Elapsed> - where - F: Fn(&Nodes) -> bool, + where + F: Fn(&Nodes) -> bool, { self.network .try_settle_on(&mut self.rng, condition, within) @@ -438,8 +448,8 @@ impl TestFixture { /// /// Panics if the condition isn't met in time. async fn run_until(&mut self, condition: F, within: Duration) - where - F: Fn(&Nodes) -> bool, + where + F: Fn(&Nodes) -> bool, { self.network .settle_on(&mut self.rng, condition, within) @@ -468,7 +478,7 @@ impl TestFixture { }, within, ) - .await + .await } /// Runs the network until all nodes reach the given completed block height. @@ -498,14 +508,14 @@ impl TestFixture { }, within, ) - .await - .unwrap_or_else(|_| { - panic!( - "should reach {} within {} seconds", - era_id, - within.as_secs_f64(), - ) - }) + .await + .unwrap_or_else(|_| { + panic!( + "should reach {} within {} seconds", + era_id, + within.as_secs_f64(), + ) + }) } /// Runs the network until all nodes' storage components have stored the switch block header for @@ -527,14 +537,14 @@ impl TestFixture { }, within, ) - .await - .unwrap_or_else(|_| { - panic!( - "should have stored switch block header for {} within {} seconds", - era_id, - within.as_secs_f64(), - ) - }) + .await + .unwrap_or_else(|_| { + panic!( + "should have stored switch block header for {} within {} seconds", + era_id, + within.as_secs_f64(), + ) + }) } /// Runs the network until all nodes have executed the given transaction and stored the @@ -558,14 +568,14 @@ impl TestFixture { }, within, ) - .await - .unwrap_or_else(|_| { - panic!( - "should have stored execution result for {} within {} seconds", - txn_hash, - within.as_secs_f64(), - ) - }) + .await + .unwrap_or_else(|_| { + panic!( + "should have stored execution result for {} within {} seconds", + txn_hash, + within.as_secs_f64(), + ) + }) } async fn schedule_upgrade_for_era_two(&mut self) { @@ -708,8 +718,10 @@ impl TestFixture { let block_time = highest_block.clone_header().timestamp(); - let holds_epoch = - HoldsEpoch::from_timestamp(block_time, self.chainspec.core_config.balance_hold_interval); + let holds_epoch = HoldsEpoch::from_timestamp( + block_time, + self.chainspec.core_config.balance_hold_interval, + ); let balance_request = BalanceRequest::from_public_key( *highest_block.state_root_hash(), @@ -781,11 +793,11 @@ impl TestFixture { { ExecutionResult::V1(_) => unreachable!(), ExecutionResult::V2(ExecutionResultV2 { - effects, - consumed: gas, - error_message, - .. - }) => { + effects, + consumed: gas, + error_message, + .. + }) => { if error_message.is_none() { effects.transforms().to_vec() } else { @@ -806,7 +818,7 @@ impl TestFixture { pub fn run_until_stopped( self, rng: TestRng, - ) -> impl futures::Future>, TestRng)> { + ) -> impl futures::Future>, TestRng)> { self.network.crank_until_stopped(rng) } } @@ -1477,10 +1489,10 @@ async fn empty_block_validation_regression() { .inner_mut() .set_filter(move |event| match event { MainEvent::Consensus(consensus::Event::NewBlockPayload(NewBlockPayload { - era_id, - block_payload: _, - block_context, - })) => { + era_id, + block_payload: _, + block_context, + })) => { info!("Accusing everyone else!"); // We hook into the NewBlockPayload event to replace the block being proposed with // an empty one that accuses all the validators, except the malicious validator. @@ -2052,16 +2064,16 @@ async fn run_rewards_network_scenario( let rewarded_blocks = &blocks[rewarded_range]; let block_reward = (Ratio::::one() - fixture - .chainspec - .core_config - .finality_signature_proportion - .into_u512()) + .chainspec + .core_config + .finality_signature_proportion + .into_u512()) * recomputed_total_supply[&(i - 1)] * fixture - .chainspec - .core_config - .round_seigniorage_rate - .into_u512(); + .chainspec + .core_config + .round_seigniorage_rate + .into_u512(); let signatures_reward = fixture .chainspec .core_config @@ -2069,10 +2081,10 @@ async fn run_rewards_network_scenario( .into_u512() * recomputed_total_supply[&(i - 1)] * fixture - .chainspec - .core_config - .round_seigniorage_rate - .into_u512(); + .chainspec + .core_config + .round_seigniorage_rate + .into_u512(); let previous_signatures_reward = if switch_blocks.headers[i - 1].is_genesis() { None } else { @@ -2084,10 +2096,10 @@ async fn run_rewards_network_scenario( .into_u512() * recomputed_total_supply[&(i - 2)] * fixture - .chainspec - .core_config - .round_seigniorage_rate - .into_u512(), + .chainspec + .core_config + .round_seigniorage_rate + .into_u512(), ) }; @@ -2235,8 +2247,8 @@ async fn run_rewards_network_scenario( .get(era) .expect("expected recalculated supply") - recomputed_total_supply - .get(&(era - 1)) - .expect("expected recalculated supply"), + .get(&(era - 1)) + .expect("expected recalculated supply"), "supply growth does not match rewards at era {}", era ) @@ -2265,7 +2277,7 @@ async fn run_reward_network_zug_all_finality_small_prime_five_eras() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2289,7 +2301,7 @@ async fn run_reward_network_zug_all_finality_small_prime_five_eras_no_lookback() ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2313,7 +2325,7 @@ async fn run_reward_network_zug_no_finality_small_nominal_five_eras() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2337,7 +2349,7 @@ async fn run_reward_network_zug_half_finality_half_finders_small_nominal_five_er ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2361,7 +2373,7 @@ async fn run_reward_network_zug_half_finality_half_finders_small_nominal_five_er ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2385,7 +2397,7 @@ async fn run_reward_network_zug_all_finality_half_finders_small_nominal_five_era ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2411,7 +2423,7 @@ async fn run_reward_network_zug_all_finality_half_finders() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2437,7 +2449,7 @@ async fn run_reward_network_zug_all_finality_half_finders_five_eras() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2463,7 +2475,7 @@ async fn run_reward_network_zug_all_finality_zero_finders() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2489,7 +2501,7 @@ async fn run_reward_network_highway_all_finality_zero_finders() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2515,7 +2527,7 @@ async fn run_reward_network_highway_no_finality() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2563,14 +2575,14 @@ async fn should_raise_gas_price_to_ceiling_and_reduce_to_floor() { target_public_key, None, ) - .expect("must get builder") - .with_chain_name(chain_name.clone()) - .with_secret_key(&alice_secret_key) - .with_pricing_mode(PricingMode::Fixed { - gas_price_tolerance: max_gas_price, - }) - .build() - .expect("must get transaction"); + .expect("must get builder") + .with_chain_name(chain_name.clone()) + .with_secret_key(&alice_secret_key) + .with_pricing_mode(PricingMode::Fixed { + gas_price_tolerance: max_gas_price, + }) + .build() + .expect("must get transaction"); let txn = Transaction::V1(fixed_native_mint_transaction); fixture.inject_transaction(txn).await; @@ -2607,11 +2619,14 @@ async fn should_raise_gas_price_to_ceiling_and_reduce_to_floor() { .run_until_executed_transaction(&txn_hash, TEN_SECS) .await; - let (_, balance_after) = fixture.check_account_balance_at_tip(alice_public_key.clone()); - let current_gas_price = fixture.highest_complete_block().maybe_current_gas_price().expect("must have gas price"); - let cost = fixture.chainspec.system_costs_config.mint_costs().transfer * (current_gas_price as u32); + let current_gas_price = fixture + .highest_complete_block() + .maybe_current_gas_price() + .expect("must have gas price"); + let cost = + fixture.chainspec.system_costs_config.mint_costs().transfer * (current_gas_price as u32); assert_eq!(balance_before, balance_after + U512::from(cost)); // Run the network at zero load and ensure the value falls back to the floor. From 62127157a18d166f473436a8e25ecea02f0d77bb Mon Sep 17 00:00:00 2001 From: Karan Dhareshwar Date: Thu, 28 Mar 2024 11:37:02 -0500 Subject: [PATCH 56/70] Run make format --- node/src/reactor/main_reactor.rs | 2 +- node/src/reactor/main_reactor/tests.rs | 2 +- types/src/block.rs | 7 ++++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/node/src/reactor/main_reactor.rs b/node/src/reactor/main_reactor.rs index f9255e9926..f03845a735 100644 --- a/node/src/reactor/main_reactor.rs +++ b/node/src/reactor/main_reactor.rs @@ -1111,7 +1111,7 @@ impl reactor::Reactor for MainReactor { chainspec.core_config.recent_era_count(), Some(registry), config.node.force_resync, - chainspec.transaction_config.clone(), + chainspec.transaction_config, )?; let contract_runtime = ContractRuntime::new( diff --git a/node/src/reactor/main_reactor/tests.rs b/node/src/reactor/main_reactor/tests.rs index 8399debd1d..64a7b2f0d3 100644 --- a/node/src/reactor/main_reactor/tests.rs +++ b/node/src/reactor/main_reactor/tests.rs @@ -743,7 +743,7 @@ impl TestFixture { } = balance_result { let purse = URef::new(purse_addr, AccessRights::all()); - return (purse, available_balance); + (purse, available_balance) } else { panic!("failed balance result") } diff --git a/types/src/block.rs b/types/src/block.rs index 306c09b45e..e2cf94b39e 100644 --- a/types/src/block.rs +++ b/types/src/block.rs @@ -29,15 +29,19 @@ use std::error::Error as StdError; #[cfg(feature = "datasize")] use datasize::DataSize; +#[cfg(feature = "std")] use num_rational::Ratio; #[cfg(feature = "json-schema")] use schemars::JsonSchema; +#[cfg(feature = "std")] +use crate::TransactionConfig; + use crate::{ bytesrepr, bytesrepr::{FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, - Digest, EraId, ProtocolVersion, PublicKey, Timestamp, TransactionConfig, + Digest, EraId, ProtocolVersion, PublicKey, Timestamp, }; pub use available_block_range::AvailableBlockRange; pub use block_body::{BlockBody, BlockBodyV1, BlockBodyV2}; @@ -395,6 +399,7 @@ impl Block { } /// Returns the utilization of the block against a given chainspec. + #[cfg(feature = "std")] pub fn block_utilization(&self, transaction_config: TransactionConfig) -> u64 { match self { Block::V1(_) => { From 62cdd7ce5d726a1fa53e456db0140189d3ddc5bd Mon Sep 17 00:00:00 2001 From: Alexandru Sardan Date: Thu, 28 Mar 2024 17:29:15 +0000 Subject: [PATCH 57/70] node/tests: add some transaction tests Also fix issue where transfer id was not optional anymore. Signed-off-by: Alexandru Sardan --- node/src/reactor/main_reactor/tests.rs | 96 +++++- .../main_reactor/tests/transactions.rs | 286 ++++++++++++++++++ storage/src/system/transfer.rs | 10 +- 3 files changed, 382 insertions(+), 10 deletions(-) create mode 100644 node/src/reactor/main_reactor/tests/transactions.rs diff --git a/node/src/reactor/main_reactor/tests.rs b/node/src/reactor/main_reactor/tests.rs index 16187cd9b8..891fb116fc 100644 --- a/node/src/reactor/main_reactor/tests.rs +++ b/node/src/reactor/main_reactor/tests.rs @@ -1,4 +1,5 @@ mod binary_port; +mod transactions; use std::{ collections::{BTreeMap, BTreeSet}, @@ -20,10 +21,16 @@ use tokio::time::{self, error::Elapsed}; use tracing::{error, info}; use casper_storage::{ - data_access_layer::{BidsRequest, BidsResult, TotalSupplyRequest, TotalSupplyResult}, + data_access_layer::{ + balance::{BalanceHandling, BalanceResult}, + AddressableEntityRequest, AddressableEntityResult, BalanceRequest, BidsRequest, BidsResult, + TotalSupplyRequest, TotalSupplyResult, + }, global_state::state::{StateProvider, StateReader}, }; use casper_types::{ + account::AccountHash, + crypto, execution::{ExecutionResult, ExecutionResultV2, TransformKindV2, TransformV2}, system::{ auction::{BidAddr, BidKind, BidsExt, DelegationRate}, @@ -32,9 +39,10 @@ use casper_types::{ testing::TestRng, AccountConfig, AccountsConfig, ActivationPoint, AddressableEntityHash, AvailableBlockRange, Block, BlockHash, BlockHeader, BlockV2, CLValue, Chainspec, ChainspecRawBytes, - ConsensusProtocolName, Deploy, EraId, Key, Motes, NextUpgrade, ProtocolVersion, PublicKey, - Rewards, SecretKey, StoredValue, SystemEntityRegistry, TimeDiff, Timestamp, Transaction, - TransactionHash, ValidatorConfig, U512, + ConsensusProtocolName, Deploy, EraId, FeeHandling, Gas, HoldsEpoch, Key, Motes, NextUpgrade, + PricingHandling, PricingMode, ProtocolVersion, PublicKey, RefundHandling, Rewards, SecretKey, + StoredValue, SystemEntityRegistry, TimeDiff, Timestamp, Transaction, TransactionHash, + TransactionV1Builder, ValidatorConfig, U512, }; use crate::{ @@ -104,6 +112,39 @@ struct ConfigsOverride { min_gas_price: u8, upper_threshold: u64, lower_threshold: u64, + refund_handling_override: Option, + fee_handling_override: Option, + pricing_handling_override: Option, + allow_reservations_override: Option, + balance_hold_interval_override: Option, +} + +impl ConfigsOverride { + fn with_refund_handling(mut self, refund_handling: RefundHandling) -> Self { + self.refund_handling_override = Some(refund_handling); + self + } + + fn with_fee_handling(mut self, fee_handling: FeeHandling) -> Self { + self.fee_handling_override = Some(fee_handling); + self + } + + fn with_pricing_handling(mut self, pricing_handling: PricingHandling) -> Self { + self.pricing_handling_override = Some(pricing_handling); + self + } + + #[allow(unused)] + fn with_allow_reservations(mut self, allow_reservations: bool) -> Self { + self.allow_reservations_override = Some(allow_reservations); + self + } + + fn with_balance_hold_interval(mut self, balance_hold_interval: TimeDiff) -> Self { + self.balance_hold_interval_override = Some(balance_hold_interval); + self + } } impl Default for ConfigsOverride { @@ -127,6 +168,11 @@ impl Default for ConfigsOverride { min_gas_price: 1, upper_threshold: 90, lower_threshold: 50, + refund_handling_override: None, + fee_handling_override: None, + pricing_handling_override: None, + allow_reservations_override: None, + balance_hold_interval_override: None, } } } @@ -240,6 +286,11 @@ impl TestFixture { min_gas_price: min, upper_threshold: go_up, lower_threshold: go_down, + refund_handling_override, + fee_handling_override, + pricing_handling_override, + allow_reservations_override, + balance_hold_interval_override, } = spec_override.unwrap_or_default(); if era_duration != TimeDiff::from_millis(0) { chainspec.core_config.era_duration = era_duration; @@ -265,6 +316,22 @@ impl TestFixture { chainspec.core_config.minimum_block_time * 2; chainspec.core_config.signature_rewards_max_delay = signature_rewards_max_delay; + if let Some(refund_handling) = refund_handling_override { + chainspec.core_config.refund_handling = refund_handling; + } + if let Some(fee_handling) = fee_handling_override { + chainspec.core_config.fee_handling = fee_handling; + } + if let Some(pricing_handling) = pricing_handling_override { + chainspec.core_config.pricing_handling = pricing_handling; + } + if let Some(allow_reservations) = allow_reservations_override { + chainspec.core_config.allow_reservations = allow_reservations; + } + if let Some(balance_hold_interval) = balance_hold_interval_override { + chainspec.core_config.balance_hold_interval = balance_hold_interval; + } + let mut fixture = TestFixture { rng, node_contexts: vec![], @@ -555,11 +622,30 @@ impl TestFixture { self.try_run_until( move |nodes: &Nodes| { nodes.values().all(|runner| { - runner + if runner .main_reactor() .storage() .read_execution_result(txn_hash) .is_some() + { + let exec_info = runner + .main_reactor() + .storage() + .read_execution_info(*txn_hash); + + if let Some(exec_info) = exec_info { + runner + .main_reactor() + .storage() + .read_block_header_by_height(exec_info.block_height, true) + .unwrap() + .is_some() + } else { + false + } + } else { + false + } }) }, within, diff --git a/node/src/reactor/main_reactor/tests/transactions.rs b/node/src/reactor/main_reactor/tests/transactions.rs new file mode 100644 index 0000000000..c4a8c3993c --- /dev/null +++ b/node/src/reactor/main_reactor/tests/transactions.rs @@ -0,0 +1,286 @@ +use super::*; + +use casper_types::execution::ExecutionResultV1; + +async fn transfer_to_account>( + fixture: &mut TestFixture, + amount: A, + to: PublicKey, + from: &SecretKey, + pricing: PricingMode, + transfer_id: Option, +) -> (TransactionHash, u64, ExecutionResult) { + let chain_name = fixture.chainspec.network_config.name.clone(); + + let mut txn = Transaction::from( + TransactionV1Builder::new_transfer(amount, None, to, transfer_id) + .unwrap() + .with_initiator_addr(PublicKey::from(from)) + .with_pricing_mode(pricing) + .with_chain_name(chain_name) + .build() + .unwrap(), + ); + + txn.sign(from); + let txn_hash = txn.hash(); + + fixture.inject_transaction(txn).await; + fixture + .run_until_executed_transaction(&txn_hash, TEN_SECS) + .await; + + let (_node_id, runner) = fixture.network.nodes().iter().next().unwrap(); + let exec_info = runner + .main_reactor() + .storage() + .read_execution_info(txn_hash) + .expect("Expected transaction to be included in a block."); + + ( + txn_hash, + exec_info.block_height, + exec_info + .execution_result + .expect("Exec result should have been stored."), + ) +} + +fn get_balance( + fixture: &mut TestFixture, + account_key: &PublicKey, + block_height: Option, + get_total: bool, +) -> BalanceResult { + let (_node_id, runner) = fixture.network.nodes().iter().next().unwrap(); + let protocol_version = fixture.chainspec.protocol_version(); + let block_height = block_height.unwrap_or( + runner + .main_reactor() + .storage() + .highest_complete_block_height() + .expect("missing highest completed block"), + ); + let block_header = runner + .main_reactor() + .storage() + .read_block_header_by_height(block_height, true) + .expect("failure to read block header") + .unwrap(); + let state_hash = *block_header.state_root_hash(); + let balance_handling = if get_total { + BalanceHandling::Total + } else { + let block_time = block_header.timestamp().into(); + BalanceHandling::Available { + holds_epoch: HoldsEpoch::from_block_time( + block_time, + fixture.chainspec.core_config.balance_hold_interval, + ), + } + }; + runner + .main_reactor() + .contract_runtime() + .data_access_layer() + .balance(BalanceRequest::from_public_key( + state_hash, + protocol_version, + account_key.clone(), + balance_handling, + )) +} + +#[allow(unused)] +fn get_entity(fixture: &mut TestFixture, account_key: PublicKey) -> AddressableEntityResult { + let (_node_id, runner) = fixture.network.nodes().iter().next().unwrap(); + let highest_completed_height = runner + .main_reactor() + .storage() + .highest_complete_block_height() + .expect("missing highest completed block"); + let state_hash = *runner + .main_reactor() + .storage() + .read_block_header_by_height(highest_completed_height, true) + .expect("failure to read block header") + .unwrap() + .state_root_hash(); + runner + .main_reactor() + .contract_runtime() + .data_access_layer() + .addressable_entity(AddressableEntityRequest::new( + state_hash, + AccountHash::from_public_key(&account_key, crypto::blake2b).into(), + )) +} + +fn assert_exec_result_fixed_cost( + exec_result: ExecutionResult, + expected_cost: U512, + expected_consumed_gas: Gas, +) { + match exec_result { + ExecutionResult::V2(exec_result_v2) => { + assert_eq!(exec_result_v2.cost, expected_cost); + assert_eq!(exec_result_v2.consumed, expected_consumed_gas); + } + _ => { + panic!("Unexpected exec result version.") + } + } +} + +// Returns `true` is the execution result is a success. +pub fn exec_result_is_success(exec_result: &ExecutionResult) -> bool { + match exec_result { + ExecutionResult::V2(execution_result_v2) => execution_result_v2.error_message.is_none(), + ExecutionResult::V1(ExecutionResultV1::Success { .. }) => true, + ExecutionResult::V1(ExecutionResultV1::Failure { .. }) => false, + } +} + +#[tokio::test] +async fn transfer_cost_fixed_price_no_fee_no_refund() { + const TRANSFER_AMOUNT: u64 = 30_000_000_000; + + let initial_stakes = InitialStakes::FromVec(vec![u128::MAX, 1]); + + let config = ConfigsOverride::default() + .with_pricing_handling(PricingHandling::Fixed) + .with_refund_handling(RefundHandling::NoRefund) + .with_fee_handling(FeeHandling::NoFee) + .with_balance_hold_interval(TimeDiff::from_seconds(5)); + + let mut fixture = TestFixture::new(initial_stakes, Some(config)).await; + + let alice_secret_key = Arc::clone(&fixture.node_contexts[0].secret_key); + let alice_public_key = PublicKey::from(&*alice_secret_key); + let charlie_secret_key = Arc::new(SecretKey::random(&mut fixture.rng)); + let charlie_public_key = PublicKey::from(&*charlie_secret_key); + + // Wait for all nodes to complete era 0. + fixture.run_until_consensus_in_era(ERA_ONE, ONE_MIN).await; + + let alice_initial_balance = *get_balance(&mut fixture, &alice_public_key, None, true) + .motes() + .expect("Expected Alice to have a balance."); + + let (_txn_hash, block_height, exec_result) = transfer_to_account( + &mut fixture, + TRANSFER_AMOUNT, + PublicKey::from(&*charlie_secret_key), + &alice_secret_key, + PricingMode::Fixed { + gas_price_tolerance: 1, + }, + Some(0xDEADBEEF), + ) + .await; + + let expected_transfer_gas = fixture + .chainspec + .system_costs_config + .mint_costs() + .transfer + .into(); + let expected_transfer_cost = expected_transfer_gas; // since we set gas_price_tolerance to 1. + + assert_exec_result_fixed_cost( + exec_result, + expected_transfer_cost, + Gas::new(expected_transfer_gas), + ); + + let alice_available_balance = + get_balance(&mut fixture, &alice_public_key, Some(block_height), false); + let alice_total_balance = + get_balance(&mut fixture, &alice_public_key, Some(block_height), true); + + // since FeeHandling is set to NoFee, we expect that there's a hold on Alice's balance for the + // cost of the transfer. The total balance of Alice now should be the initial balance - the + // amount transfered to Charlie. + let alice_expected_total_balance = alice_initial_balance - TRANSFER_AMOUNT; + // The available balance is the initial balance - the amount transferred to Charlie - the hold + // for the transfer cost. + let alice_expected_available_balance = alice_expected_total_balance - expected_transfer_cost; + + assert_eq!( + alice_total_balance + .motes() + .expect("Expected Alice to have a balance") + .clone(), + alice_expected_total_balance + ); + assert_eq!( + alice_available_balance + .motes() + .expect("Expected Alice to have a balance") + .clone(), + alice_expected_available_balance + ); + + let charlie_balance = get_balance(&mut fixture, &charlie_public_key, Some(block_height), false); + assert_eq!( + charlie_balance + .motes() + .expect("Expected Alice to have a balance") + .clone(), + TRANSFER_AMOUNT.into() + ); + + // Check if the hold is released. + let hold_release_block_height = block_height + 8; // Block time is 1s. + fixture + .run_until_block_height(hold_release_block_height, ONE_MIN) + .await; + + let alice_available_balance = get_balance( + &mut fixture, + &alice_public_key, + Some(hold_release_block_height), + false, + ); + let alice_total_balance = get_balance( + &mut fixture, + &alice_public_key, + Some(hold_release_block_height), + true, + ); + + assert_eq!(alice_available_balance.motes(), alice_total_balance.motes()); +} + +#[tokio::test] +async fn should_accept_transfer_without_id() { + let initial_stakes = InitialStakes::FromVec(vec![u128::MAX, 1]); + + let config = ConfigsOverride::default().with_pricing_handling(PricingHandling::Fixed); + let mut fixture = TestFixture::new(initial_stakes, Some(config)).await; + let transfer_amount = fixture + .chainspec + .transaction_config + .native_transfer_minimum_motes + + 100; + + let alice_secret_key = Arc::clone(&fixture.node_contexts[0].secret_key); + let charlie_secret_key = Arc::new(SecretKey::random(&mut fixture.rng)); + + // Wait for all nodes to complete era 0. + fixture.run_until_consensus_in_era(ERA_ONE, ONE_MIN).await; + + let (_, _, result) = transfer_to_account( + &mut fixture, + transfer_amount, + PublicKey::from(&*charlie_secret_key), + &alice_secret_key, + PricingMode::Fixed { + gas_price_tolerance: 1, + }, + None, + ) + .await; + + assert!(exec_result_is_success(&result)) +} diff --git a/storage/src/system/transfer.rs b/storage/src/system/transfer.rs index 78e319a434..f54db564fd 100644 --- a/storage/src/system/transfer.rs +++ b/storage/src/system/transfer.rs @@ -401,11 +401,11 @@ impl TransferRuntimeArgsBuilder { } fn resolve_id(&self) -> Result, TransferError> { - let id_value = self - .inner - .get(mint::ARG_ID) - .ok_or_else(|| TransferError::MissingArgument)?; - let id: Option = self.map_cl_value(id_value)?; + let id: Option = if let Some(id_value) = self.inner.get(mint::ARG_ID) { + self.map_cl_value(id_value)? + } else { + None + }; Ok(id) } From 0cdda7e5c70afaffd8adf175237c5a00489ee9f5 Mon Sep 17 00:00:00 2001 From: Karan Dhareshwar Date: Thu, 28 Mar 2024 14:33:04 -0500 Subject: [PATCH 58/70] Fix test to check balance hold --- node/src/components/storage.rs | 46 +- node/src/effect.rs | 672 ++++++++++++------------- node/src/effect/requests.rs | 29 +- node/src/reactor/main_reactor/tests.rs | 199 ++++---- 4 files changed, 475 insertions(+), 471 deletions(-) diff --git a/node/src/components/storage.rs b/node/src/components/storage.rs index 41849aaeb0..1731f5be45 100644 --- a/node/src/components/storage.rs +++ b/node/src/components/storage.rs @@ -180,8 +180,8 @@ impl Display for HighestOrphanedBlockResult { } impl Component for Storage -where - REv: From + From> + Send, + where + REv: From + From> + Send, { type Event = Event; @@ -396,8 +396,8 @@ impl Storage { effect_builder: EffectBuilder, incoming: &NetRequestIncoming, ) -> Result, GetRequestError> - where - REv: From> + Send, + where + REv: From> + Send, { if self.enable_mem_deduplication { let unique_id = incoming.message.unique_id(); @@ -869,7 +869,7 @@ impl Storage { signature.era_id(), signature.chain_name_hash(), ) - .into(), + .into(), } }; match (&mut block_signatures, *signature) { @@ -1006,11 +1006,11 @@ impl Storage { StorageRequest::GetBlockUtilizationScore { era_id, block_height, - transaction_count, + switch_block_utilization: switch_block_utilization, responder, } => { let utilization = - self.get_block_utilization_score(era_id, block_height, transaction_count); + self.get_block_utilization_score(era_id, block_height, switch_block_utilization); responder.respond(utilization).ignore() } @@ -1042,7 +1042,7 @@ impl Storage { #[allow(clippy::type_complexity)] fn get_transactions_with_finalized_approvals<'a>( &self, - transaction_hashes: impl Iterator, + transaction_hashes: impl Iterator, ) -> Result>)>; 1]>, FatalStorageError> { let mut ro_txn = self.block_store.checkout_ro()?; @@ -1270,8 +1270,8 @@ impl Storage { let mut transactions = vec![]; for (transaction, _) in (self .get_transactions_with_finalized_approvals(block.all_transactions())?) - .into_iter() - .flatten() + .into_iter() + .flatten() { transactions.push(transaction) } @@ -1633,7 +1633,7 @@ impl Storage { fn get_transaction_with_finalized_approvals( &self, txn: &mut (impl DataReader - + DataReader>), + + DataReader>), transaction_hash: &TransactionHash, ) -> Result>)>, FatalStorageError> { let maybe_transaction: Option = txn.read(*transaction_hash)?; @@ -1738,9 +1738,9 @@ impl Storage { serialized_id: &[u8], fetch_response: FetchResponse, ) -> Result, FatalStorageError> - where - REv: From> + Send, - T: FetchItem, + where + REv: From> + Send, + T: FetchItem, { let serialized = fetch_response .to_serialized() @@ -1863,7 +1863,7 @@ impl Storage { block.era_id(), self.chain_name_hash, ) - .into(), + .into(), } } @@ -1930,8 +1930,8 @@ impl Storage { fn get_execution_results_with_transaction_headers( &self, txn: &mut (impl DataReader - + DataReader - + DataReader), + + DataReader + + DataReader), block_hash: &BlockHash, ) -> Result>, FatalStorageError> { @@ -2001,8 +2001,8 @@ impl Storage { /// Decodes an item's ID, typically from an incoming request. fn decode_item_id(raw: &[u8]) -> Result -where - T: FetchItem, + where + T: FetchItem, { bincode::deserialize(raw).map_err(GetRequestError::MalformedIncomingItemId) } @@ -2081,10 +2081,10 @@ fn successful_transfers(execution_result: &ExecutionResult) -> Vec { } } ExecutionResult::V2(ExecutionResultV2 { - transfers, - error_message, - .. - }) => { + transfers, + error_message, + .. + }) => { if error_message.is_none() { for transfer in transfers { all_transfers.push(transfer.clone()); diff --git a/node/src/effect.rs b/node/src/effect.rs index 5de0c3b25e..79c3f89ced 100644 --- a/node/src/effect.rs +++ b/node/src/effect.rs @@ -322,13 +322,13 @@ impl Responder { impl Debug for Responder { fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { - write!(formatter, "Responder<{}>", type_name::(),) + write!(formatter, "Responder<{}>", type_name::(), ) } } impl Display for Responder { fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { - write!(formatter, "responder({})", type_name::(),) + write!(formatter, "responder({})", type_name::(), ) } } @@ -371,21 +371,21 @@ pub(crate) trait EffectExt: Future + Send { /// /// The function `f` is used to translate the returned value from an effect into an event. fn event(self, f: F) -> Effects - where - F: FnOnce(Self::Output) -> U + 'static + Send, - U: 'static, - Self: Sized; + where + F: FnOnce(Self::Output) -> U + 'static + Send, + U: 'static, + Self: Sized; /// Finalizes a future into an effect that returns an iterator of events. /// /// The function `f` is used to translate the returned value from an effect into an iterator of /// events. fn events(self, f: F) -> Effects - where - F: FnOnce(Self::Output) -> I + 'static + Send, - U: 'static, - I: Iterator, - Self: Sized; + where + F: FnOnce(Self::Output) -> I + 'static + Send, + U: 'static, + I: Iterator, + Self: Sized; /// Finalizes a future into an effect that runs but drops the result. fn ignore(self) -> Effects; @@ -404,10 +404,10 @@ pub(crate) trait EffectResultExt { /// The function `f_ok` is used to translate the returned value from an effect into an event, /// while the function `f_err` does the same for a potential error. fn result(self, f_ok: F, f_err: G) -> Effects - where - F: FnOnce(Self::Value) -> U + 'static + Send, - G: FnOnce(Self::Error) -> U + 'static + Send, - U: 'static; + where + F: FnOnce(Self::Value) -> U + 'static + Send, + G: FnOnce(Self::Error) -> U + 'static + Send, + U: 'static; } /// Effect extension for futures, used to convert futures returning an `Option` into two different @@ -421,38 +421,38 @@ pub(crate) trait EffectOptionExt { /// The function `f_some` is used to translate the returned value from an effect into an event, /// while the function `f_none` does the same for a returned `None`. fn map_or_else(self, f_some: F, f_none: G) -> Effects - where - F: FnOnce(Self::Value) -> U + 'static + Send, - G: FnOnce() -> U + 'static + Send, - U: 'static; + where + F: FnOnce(Self::Value) -> U + 'static + Send, + G: FnOnce() -> U + 'static + Send, + U: 'static; /// Finalizes a future returning an `Option` into two different effects. /// /// The function `f` is used to translate the returned value from an effect into an event, /// In the case of `None`, empty vector of effects is returned. fn map_some(self, f: F) -> Effects - where - F: FnOnce(Self::Value) -> U + 'static + Send, - U: 'static; + where + F: FnOnce(Self::Value) -> U + 'static + Send, + U: 'static; } impl EffectExt for T -where - T: Future + Send + 'static + Sized, + where + T: Future + Send + 'static + Sized, { fn event(self, f: F) -> Effects - where - F: FnOnce(Self::Output) -> U + 'static + Send, - U: 'static, + where + F: FnOnce(Self::Output) -> U + 'static + Send, + U: 'static, { smallvec![self.map(f).map(|item| smallvec![item]).boxed()] } fn events(self, f: F) -> Effects - where - F: FnOnce(Self::Output) -> I + 'static + Send, - U: 'static, - I: Iterator, + where + F: FnOnce(Self::Output) -> I + 'static + Send, + U: 'static, + I: Iterator, { smallvec![self.map(f).map(|iter| iter.collect()).boxed()] } @@ -463,18 +463,18 @@ where } impl EffectResultExt for T -where - T: Future> + Send + 'static + Sized, - T: ?Sized, + where + T: Future> + Send + 'static + Sized, + T: ?Sized, { type Value = V; type Error = E; fn result(self, f_ok: F, f_err: G) -> Effects - where - F: FnOnce(V) -> U + 'static + Send, - G: FnOnce(E) -> U + 'static + Send, - U: 'static, + where + F: FnOnce(V) -> U + 'static + Send, + G: FnOnce(E) -> U + 'static + Send, + U: 'static, { smallvec![self .map(|result| result.map_or_else(f_err, f_ok)) @@ -484,17 +484,17 @@ where } impl EffectOptionExt for T -where - T: Future> + Send + 'static + Sized, - T: ?Sized, + where + T: Future> + Send + 'static + Sized, + T: ?Sized, { type Value = V; fn map_or_else(self, f_some: F, f_none: G) -> Effects - where - F: FnOnce(V) -> U + 'static + Send, - G: FnOnce() -> U + 'static + Send, - U: 'static, + where + F: FnOnce(V) -> U + 'static + Send, + G: FnOnce() -> U + 'static + Send, + U: 'static, { smallvec![self .map(|option| option.map_or_else(f_none, f_some)) @@ -507,9 +507,9 @@ where /// The function `f` is used to translate the returned value from an effect into an event, /// In the case of `None`, empty vector is returned. fn map_some(self, f: F) -> Effects - where - F: FnOnce(Self::Value) -> U + 'static + Send, - U: 'static, + where + F: FnOnce(Self::Value) -> U + 'static + Send, + U: 'static, { smallvec![self .map(|option| option @@ -570,10 +570,10 @@ impl EffectBuilder { /// This future is cancellation safe: If it is dropped without being polled, it merely indicates /// the original requester is not longer interested in the result, which will be discarded. pub(crate) async fn make_request(self, f: F, queue_kind: QueueKind) -> T - where - T: Send + 'static, - Q: Into, - F: FnOnce(Responder) -> Q, + where + T: Send + 'static, + Q: Into, + F: FnOnce(Responder) -> Q, { let (event, wait_future) = self.create_request_parts(f); @@ -589,11 +589,11 @@ impl EffectBuilder { /// creates both of them without processing or spawning either. /// /// Usually you will want to call the higher level `make_request` function. - pub(crate) fn create_request_parts(self, f: F) -> (REv, impl Future) - where - T: Send + 'static, - Q: Into, - F: FnOnce(Responder) -> Q, + pub(crate) fn create_request_parts(self, f: F) -> (REv, impl Future) + where + T: Send + 'static, + Q: Into, + F: FnOnce(Responder) -> Q, { // Prepare a channel. let (sender, receiver) = oneshot::channel(); @@ -637,7 +637,7 @@ impl EffectBuilder { /// "do nothing", as it will still cause a task to be spawned. #[inline(always)] #[allow(clippy::manual_async_fn)] - pub(crate) fn immediately(self) -> impl Future + Send { + pub(crate) fn immediately(self) -> impl Future + Send { // Note: This function is implemented manually without `async` sugar because the `Send` // inference seems to not work in all cases otherwise. async {} @@ -647,8 +647,8 @@ impl EffectBuilder { /// /// Usually causes the node to cease operations quickly and exit/crash. pub(crate) async fn fatal(self, file: &'static str, line: u32, msg: String) - where - REv: From, + where + REv: From, { self.event_queue .schedule(FatalAnnouncement { file, line, msg }, QueueKind::Control) @@ -666,14 +666,14 @@ impl EffectBuilder { /// /// If an error occurred producing the metrics, `None` is returned. pub(crate) async fn get_metrics(self) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| MetricsRequest::RenderNodeMetricsText { responder }, QueueKind::Api, ) - .await + .await } /// Sends a network message. @@ -681,8 +681,8 @@ impl EffectBuilder { /// The message is queued and sent, but no delivery guaranteed. Will return after the message /// has been buffered in the outgoing kernel buffer and thus is subject to backpressure. pub(crate) async fn send_message

(self, dest: NodeId, payload: P) - where - REv: From>, + where + REv: From>, { self.make_request( |responder| NetworkRequest::SendMessage { @@ -693,7 +693,7 @@ impl EffectBuilder { }, QueueKind::Network, ) - .await; + .await; } /// Enqueues a network message. @@ -701,8 +701,8 @@ impl EffectBuilder { /// The message is queued in "fire-and-forget" fashion, there is no guarantee that the peer /// will receive it. Returns as soon as the message is queued inside the networking component. pub(crate) async fn enqueue_message

(self, dest: NodeId, payload: P) - where - REv: From>, + where + REv: From>, { self.make_request( |responder| NetworkRequest::SendMessage { @@ -713,13 +713,13 @@ impl EffectBuilder { }, QueueKind::Network, ) - .await; + .await; } /// Broadcasts a network message to validator peers in the given era. pub(crate) async fn broadcast_message_to_validators

(self, payload: P, era_id: EraId) - where - REv: From>, + where + REv: From>, { self.make_request( |responder| { @@ -732,7 +732,7 @@ impl EffectBuilder { }, QueueKind::Network, ) - .await; + .await; } /// Gossips a network message. @@ -748,9 +748,9 @@ impl EffectBuilder { count: usize, exclude: HashSet, ) -> HashSet - where - REv: From>, - P: Send, + where + REv: From>, + P: Send, { self.make_request( |responder| NetworkRequest::Gossip { @@ -762,50 +762,50 @@ impl EffectBuilder { }, QueueKind::Network, ) - .await - .unwrap_or_default() + .await + .unwrap_or_default() } /// Gets a structure describing the current network status. pub(crate) async fn get_network_insights(self) -> NetworkInsights - where - REv: From, + where + REv: From, { self.make_request( |responder| NetworkInfoRequest::Insight { responder }, QueueKind::Regular, ) - .await + .await } /// Gets a map of the current network peers to their socket addresses. pub(crate) async fn network_peers(self) -> BTreeMap - where - REv: From, + where + REv: From, { self.make_request( |responder| NetworkInfoRequest::Peers { responder }, QueueKind::Api, ) - .await + .await } /// Gets up to `count` fully-connected network peers in random order. pub async fn get_fully_connected_peers(self, count: usize) -> Vec - where - REv: From, + where + REv: From, { self.make_request( |responder| NetworkInfoRequest::FullyConnectedPeers { count, responder }, QueueKind::NetworkInfo, ) - .await + .await } /// Announces which transactions have expired. pub(crate) async fn announce_expired_transactions(self, hashes: Vec) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -817,8 +817,8 @@ impl EffectBuilder { /// Announces an incoming network message. pub(crate) async fn announce_incoming

(self, sender: NodeId, payload: P) - where - REv: FromIncoming

, + where + REv: FromIncoming

, { self.event_queue .schedule( @@ -830,8 +830,8 @@ impl EffectBuilder { /// Announces that a gossiper has received a new item, where the item's ID is the complete item. pub(crate) async fn announce_complete_item_received_via_gossip(self, item: T::Id) - where - REv: From>, + where + REv: From>, { assert!( T::ID_IS_COMPLETE_ITEM, @@ -886,8 +886,8 @@ impl EffectBuilder { self, block_hash: BlockHash, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| MakeBlockExecutableRequest { @@ -896,7 +896,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Request that a block with a specific height be marked completed. @@ -905,8 +905,8 @@ impl EffectBuilder { /// have been persisted to storage and its global state root hash is missing no dependencies /// in the global state. pub(crate) async fn mark_block_completed(self, block_height: u64) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| MarkBlockCompletedRequest { @@ -915,7 +915,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Try to accept a transaction received from the JSON-RPC server. @@ -924,8 +924,8 @@ impl EffectBuilder { transaction: Transaction, is_speculative: bool, ) -> Result<(), transaction_acceptor::Error> - where - REv: From, + where + REv: From, { self.make_request( |responder| AcceptTransactionRequest { @@ -935,7 +935,7 @@ impl EffectBuilder { }, QueueKind::Api, ) - .await + .await } /// Announces that a transaction not previously stored has now been accepted and stored. @@ -943,9 +943,9 @@ impl EffectBuilder { self, transaction: Arc, source: Source, - ) -> impl Future - where - REv: From, + ) -> impl Future + where + REv: From, { self.event_queue.schedule( TransactionAcceptorAnnouncement::AcceptedNewTransaction { @@ -959,9 +959,9 @@ impl EffectBuilder { /// Announces that we have received a gossip message from this peer, /// implying the peer holds the indicated item. pub(crate) async fn announce_gossip_received(self, item_id: T::Id, sender: NodeId) - where - REv: From>, - T: GossipItem, + where + REv: From>, + T: GossipItem, { self.event_queue .schedule( @@ -973,9 +973,9 @@ impl EffectBuilder { /// Announces that we have finished gossiping the indicated item. pub(crate) async fn announce_finished_gossiping(self, item_id: T::Id) - where - REv: From>, - T: GossipItem, + where + REv: From>, + T: GossipItem, { self.event_queue .schedule( @@ -989,9 +989,9 @@ impl EffectBuilder { self, transaction: Transaction, source: Source, - ) -> impl Future - where - REv: From, + ) -> impl Future + where + REv: From, { self.event_queue.schedule( TransactionAcceptorAnnouncement::InvalidTransaction { @@ -1004,8 +1004,8 @@ impl EffectBuilder { /// Announces upgrade activation point read. pub(crate) async fn announce_upgrade_activation_point_read(self, next_upgrade: NextUpgrade) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -1017,8 +1017,8 @@ impl EffectBuilder { /// Announces a committed Step success. pub(crate) async fn announce_commit_step_success(self, era_id: EraId, effects: ExecutionEffects) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -1048,8 +1048,8 @@ impl EffectBuilder { } pub(crate) async fn announce_new_era_gas_price(self, era_id: EraId, next_era_gas_price: u8) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -1064,9 +1064,9 @@ impl EffectBuilder { /// Begins gossiping an item. pub(crate) async fn begin_gossip(self, item_id: T::Id, source: Source, target: GossipTarget) - where - T: GossipItem, - REv: From>, + where + T: GossipItem, + REv: From>, { self.make_request( |responder| BeginGossipRequest { @@ -1077,19 +1077,19 @@ impl EffectBuilder { }, QueueKind::Gossip, ) - .await + .await } /// Puts the given block into the linear block store. pub(crate) async fn put_block_to_storage(self, block: Arc) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::PutBlock { block, responder }, QueueKind::ToStorage, ) - .await + .await } /// Puts the given approvals hashes into the linear block store. @@ -1097,8 +1097,8 @@ impl EffectBuilder { self, approvals_hashes: Box, ) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::PutApprovalsHashes { @@ -1107,7 +1107,7 @@ impl EffectBuilder { }, QueueKind::ToStorage, ) - .await + .await } /// Puts the given block and approvals hashes into the linear block store. @@ -1117,8 +1117,8 @@ impl EffectBuilder { approvals_hashes: Box, execution_results: HashMap, ) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::PutExecutedBlock { @@ -1129,13 +1129,13 @@ impl EffectBuilder { }, QueueKind::ToStorage, ) - .await + .await } /// Gets the requested block from the linear block store. pub(crate) async fn get_block_from_storage(self, block_hash: BlockHash) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetBlock { @@ -1144,7 +1144,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn get_block_utilization( @@ -1153,24 +1153,24 @@ impl EffectBuilder { block_height: u64, transaction_count: u64, ) -> Option<(u64, u64)> - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetBlockUtilizationScore { era_id, block_height, - transaction_count, + switch_block_utilization: transaction_count, responder, }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn is_block_stored(self, block_hash: BlockHash) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::IsBlockStored { @@ -1179,7 +1179,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Gets the requested `ApprovalsHashes` from storage. @@ -1187,8 +1187,8 @@ impl EffectBuilder { self, block_hash: BlockHash, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetApprovalsHashes { @@ -1197,7 +1197,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn get_raw_data( @@ -1205,8 +1205,8 @@ impl EffectBuilder { record_id: RecordId, key: Vec, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetRawData { @@ -1216,7 +1216,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Gets the requested block header from the linear block store. @@ -1225,8 +1225,8 @@ impl EffectBuilder { block_hash: BlockHash, only_from_available_block_range: bool, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetBlockHeader { @@ -1236,7 +1236,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn get_block_header_at_height_from_storage( @@ -1244,8 +1244,8 @@ impl EffectBuilder { block_height: u64, only_from_available_block_range: bool, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetBlockHeaderByHeight { @@ -1255,32 +1255,32 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn get_latest_switch_block_header_from_storage(self) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetLatestSwitchBlockHeader { responder }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn get_switch_block_header_by_era_id_from_storage( self, era_id: EraId, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetSwitchBlockHeaderByEra { era_id, responder }, QueueKind::FromStorage, ) - .await + .await } /// Gets the requested signature for a given block hash. @@ -1289,8 +1289,8 @@ impl EffectBuilder { block_hash: BlockHash, public_key: PublicKey, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetBlockSignature { @@ -1300,15 +1300,15 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn get_execution_results_from_storage( self, block_hash: BlockHash, ) -> Option> - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetExecutionResults { @@ -1317,13 +1317,13 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Puts a block header to storage. pub(crate) async fn put_block_header_to_storage(self, block_header: Box) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::PutBlockHeader { @@ -1332,7 +1332,7 @@ impl EffectBuilder { }, QueueKind::ToStorage, ) - .await + .await } /// Puts the requested block signatures into storage. @@ -1340,8 +1340,8 @@ impl EffectBuilder { /// If `signatures.proofs` is empty, no attempt to store will be made, an error will be logged, /// and this function will return `false`. pub(crate) async fn put_signatures_to_storage(self, signatures: BlockSignatures) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::PutBlockSignatures { @@ -1350,15 +1350,15 @@ impl EffectBuilder { }, QueueKind::ToStorage, ) - .await + .await } pub(crate) async fn put_finality_signature_to_storage( self, signature: FinalitySignature, ) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::PutFinalitySignature { @@ -1367,7 +1367,7 @@ impl EffectBuilder { }, QueueKind::ToStorage, ) - .await + .await } /// Gets the requested block's transfers from storage. @@ -1375,8 +1375,8 @@ impl EffectBuilder { self, block_hash: BlockHash, ) -> Option> - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetBlockTransfers { @@ -1385,7 +1385,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Returns the era IDs of the blocks in which the given transactions were executed. If none @@ -1394,8 +1394,8 @@ impl EffectBuilder { self, transaction_hashes: HashSet, ) -> HashSet - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetTransactionsEraIds { @@ -1404,43 +1404,43 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Requests the highest complete block. pub(crate) async fn get_highest_complete_block_from_storage(self) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetHighestCompleteBlock { responder }, QueueKind::FromStorage, ) - .await + .await } /// Requests the highest complete block header. pub(crate) async fn get_highest_complete_block_header_from_storage(self) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetHighestCompleteBlockHeader { responder }, QueueKind::FromStorage, ) - .await + .await } /// Requests the height range of fully available blocks (not just block headers). pub(crate) async fn get_available_block_range_from_storage(self) -> AvailableBlockRange - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetAvailableBlockRange { responder }, QueueKind::FromStorage, ) - .await + .await } /// Synchronize global state under the given root hash. @@ -1449,8 +1449,8 @@ impl EffectBuilder { block_hash: BlockHash, state_root_hash: Digest, ) -> Result - where - REv: From, + where + REv: From, { self.make_request( |responder| SyncGlobalStateRequest { @@ -1460,85 +1460,85 @@ impl EffectBuilder { }, QueueKind::SyncGlobalState, ) - .await + .await } /// Get a trie or chunk by its ID. pub(crate) async fn get_trie(self, request: TrieRequest) -> TrieResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::GetTrie { request, responder }, QueueKind::ContractRuntime, ) - .await + .await } pub(crate) async fn get_reactor_state(self) -> ReactorState - where - REv: From, + where + REv: From, { self.make_request( |responder| ReactorInfoRequest::ReactorState { responder }, QueueKind::Regular, ) - .await + .await } pub(crate) async fn get_last_progress(self) -> LastProgress - where - REv: From, + where + REv: From, { self.make_request( |responder| ReactorInfoRequest::LastProgress { responder }, QueueKind::Regular, ) - .await + .await } pub(crate) async fn get_uptime(self) -> Uptime - where - REv: From, + where + REv: From, { self.make_request( |responder| ReactorInfoRequest::Uptime { responder }, QueueKind::Regular, ) - .await + .await } pub(crate) async fn get_network_name(self) -> NetworkName - where - REv: From, + where + REv: From, { self.make_request( |responder| ReactorInfoRequest::NetworkName { responder }, QueueKind::Regular, ) - .await + .await } pub(crate) async fn get_protocol_version(self) -> ProtocolVersion - where - REv: From, + where + REv: From, { self.make_request( |responder| ReactorInfoRequest::ProtocolVersion { responder }, QueueKind::Regular, ) - .await + .await } pub(crate) async fn get_block_synchronizer_status(self) -> BlockSynchronizerStatus - where - REv: From, + where + REv: From, { self.make_request( |responder| BlockSynchronizerRequest::Status { responder }, QueueKind::Regular, ) - .await + .await } /// Puts a trie into the trie store; succeeds only if all the children of the trie are already @@ -1548,30 +1548,30 @@ impl EffectBuilder { self, request: PutTrieRequest, ) -> PutTrieResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::PutTrie { request, responder }, QueueKind::ContractRuntime, ) - .await + .await } pub(crate) async fn get_current_gas_price(self, era_id: EraId) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::GetEraGasPrice { era_id, responder }, QueueKind::ContractRuntime, ) - .await + .await } pub(crate) async fn put_transaction_to_storage(self, transaction: Transaction) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::PutTransaction { @@ -1580,7 +1580,7 @@ impl EffectBuilder { }, QueueKind::ToStorage, ) - .await + .await } /// Gets the requested transactions from storage. @@ -1591,8 +1591,8 @@ impl EffectBuilder { self, transaction_hashes: Vec, ) -> SmallVec<[Option<(Transaction, Option>)>; 1]> - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetTransactions { @@ -1601,7 +1601,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Gets the requested transaction and its execution info from storage by TransactionHash. @@ -1610,8 +1610,8 @@ impl EffectBuilder { transaction_hash: TransactionHash, with_finalized_approvals: bool, ) -> Option<(Transaction, Option)> - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetTransactionAndExecutionInfo { @@ -1621,7 +1621,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Gets the requested deploy from the deploy store by DeployHash only. @@ -1632,8 +1632,8 @@ impl EffectBuilder { self, deploy_hash: DeployHash, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetLegacyDeploy { @@ -1642,7 +1642,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Gets the requested transaction from storage by TransactionId. @@ -1653,8 +1653,8 @@ impl EffectBuilder { self, transaction_id: TransactionId, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetTransaction { @@ -1663,12 +1663,12 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn is_transaction_stored(self, transaction_id: TransactionId) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::IsTransactionStored { @@ -1677,7 +1677,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Stores the given execution results for the transactions in the given block in the linear @@ -1701,7 +1701,7 @@ impl EffectBuilder { }, QueueKind::ToStorage, ) - .await + .await } /// Gets the requested block and its finality signatures. @@ -1710,8 +1710,8 @@ impl EffectBuilder { block_height: u64, only_from_available_block_range: bool, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetBlockAndMetadataByHeight { @@ -1721,7 +1721,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn collect_past_blocks_with_metadata( @@ -1729,8 +1729,8 @@ impl EffectBuilder { range: std::ops::Range, only_from_available_block_range: bool, ) -> Vec> - where - REv: From, + where + REv: From, { futures::future::join_all(range.into_iter().map(|block_height| { self.get_block_at_height_with_metadata_from_storage( @@ -1738,9 +1738,9 @@ impl EffectBuilder { only_from_available_block_range, ) })) - .await - .into_iter() - .collect() + .await + .into_iter() + .collect() } /// Gets the requested finality signature from storage. @@ -1748,25 +1748,25 @@ impl EffectBuilder { self, id: Box, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetFinalitySignature { id, responder }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn is_finality_signature_stored(self, id: Box) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::IsFinalitySignatureStored { id, responder }, QueueKind::FromStorage, ) - .await + .await } /// Fetches an item from a fetcher. @@ -1776,9 +1776,9 @@ impl EffectBuilder { peer: NodeId, validation_metadata: Box, ) -> FetchResult - where - REv: From>, - T: FetchItem + 'static, + where + REv: From>, + T: FetchItem + 'static, { self.make_request( |responder| FetcherRequest { @@ -1789,7 +1789,7 @@ impl EffectBuilder { }, QueueKind::Fetch, ) - .await + .await } pub(crate) async fn fetch_trie( @@ -1797,8 +1797,8 @@ impl EffectBuilder { hash: Digest, peers: Vec, ) -> Result - where - REv: From, + where + REv: From, { self.make_request( |responder| TrieAccumulatorRequest { @@ -1808,7 +1808,7 @@ impl EffectBuilder { }, QueueKind::SyncGlobalState, ) - .await + .await } /// Passes the timestamp of a future block for which transactions are to be proposed. @@ -1817,8 +1817,8 @@ impl EffectBuilder { timestamp: Timestamp, era_id: EraId, ) -> AppendableBlock - where - REv: From, + where + REv: From, { self.make_request( |responder| TransactionBufferRequest::GetAppendableBlock { @@ -1828,7 +1828,7 @@ impl EffectBuilder { }, QueueKind::Consensus, ) - .await + .await } /// Enqueues a finalized block execution. @@ -1872,8 +1872,8 @@ impl EffectBuilder { proposed_block_height: u64, block: ProposedBlock, ) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| BlockValidationRequest { @@ -1884,13 +1884,13 @@ impl EffectBuilder { }, QueueKind::Regular, ) - .await + .await } /// Announces that a block has been proposed. pub(crate) async fn announce_proposed_block(self, proposed_block: ProposedBlock) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -1902,8 +1902,8 @@ impl EffectBuilder { /// Announces that a block has been finalized. pub(crate) async fn announce_finalized_block(self, finalized_block: FinalizedBlock) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -1915,8 +1915,8 @@ impl EffectBuilder { /// Announces that a meta block has been created or its state has changed. pub(crate) async fn announce_meta_block(self, meta_block: MetaBlock) - where - REv: From, + where + REv: From, { self.event_queue .schedule(MetaBlockAnnouncement(meta_block), QueueKind::Regular) @@ -1926,8 +1926,8 @@ impl EffectBuilder { /// Announces that a finalized block has been created, but it was not /// executed. pub(crate) async fn announce_unexecuted_block(self, block_height: u64) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -1982,8 +1982,8 @@ impl EffectBuilder { /// Gets the next scheduled upgrade, if any. pub(crate) async fn get_next_upgrade(self) -> Option - where - REv: From + Send, + where + REv: From + Send, { self.make_request(UpgradeWatcherRequest, QueueKind::Control) .await @@ -1991,14 +1991,14 @@ impl EffectBuilder { /// Requests a query be executed on the Contract Runtime component. pub(crate) async fn query_global_state(self, request: QueryRequest) -> QueryResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::Query { request, responder }, QueueKind::ContractRuntime, ) - .await + .await } /// Retrieves an `AddressableEntity` from under the given key in global state if present. @@ -2007,8 +2007,8 @@ impl EffectBuilder { state_root_hash: Digest, key: Key, ) -> AddressableEntityResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::GetAddressableEntity { @@ -2018,13 +2018,13 @@ impl EffectBuilder { }, QueueKind::ContractRuntime, ) - .await + .await } /// Retrieves a `Package` from under the given key in global state if present. pub(crate) async fn get_package(self, state_root_hash: Digest, key: Key) -> Option> - where - REv: From, + where + REv: From, { let query_request = QueryRequest::new(state_root_hash, key, vec![]); @@ -2037,14 +2037,14 @@ impl EffectBuilder { /// Requests a query be executed on the Contract Runtime component. pub(crate) async fn get_balance(self, request: BalanceRequest) -> BalanceResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::GetBalance { request, responder }, QueueKind::ContractRuntime, ) - .await + .await } /// Returns a map of validators weights for all eras as known from `root_hash`. @@ -2054,28 +2054,28 @@ impl EffectBuilder { self, request: EraValidatorsRequest, ) -> EraValidatorsResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::GetEraValidators { request, responder }, QueueKind::ContractRuntime, ) - .await + .await } /// Returns the total supply from the given `root_hash`. /// /// This operation is read only. pub(crate) async fn get_total_supply(self, request: TotalSupplyRequest) -> TotalSupplyResult - where - REv: From, + where + REv: From, { self.make_request( move |responder| ContractRuntimeRequest::GetTotalSupply { request, responder }, QueueKind::ContractRuntime, ) - .await + .await } /// Returns the seigniorage rate from the given `root_hash`. @@ -2085,26 +2085,26 @@ impl EffectBuilder { self, request: RoundSeigniorageRateRequest, ) -> RoundSeigniorageRateResult - where - REv: From, + where + REv: From, { self.make_request( move |responder| ContractRuntimeRequest::GetRoundSeigniorageRate { request, responder }, QueueKind::ContractRuntime, ) - .await + .await } /// Requests a query be executed on the Contract Runtime component. pub(crate) async fn get_tagged_values(self, request: TaggedValuesRequest) -> TaggedValuesResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::GetTaggedValues { request, responder }, QueueKind::ContractRuntime, ) - .await + .await } /// Returns the value of the execution results checksum stored in the ChecksumRegistry for the @@ -2113,8 +2113,8 @@ impl EffectBuilder { self, state_root_hash: Digest, ) -> ExecutionResultsChecksumResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::GetExecutionResultsChecksum { @@ -2123,13 +2123,13 @@ impl EffectBuilder { }, QueueKind::ContractRuntime, ) - .await + .await } /// Get our public key from consensus, and if we're a validator, the next round length. pub(crate) async fn consensus_status(self) -> Option - where - REv: From, + where + REv: From, { self.make_request(ConsensusRequest::Status, QueueKind::Consensus) .await @@ -2137,8 +2137,8 @@ impl EffectBuilder { /// Returns a list of validator status changes, by public key. pub(crate) async fn get_consensus_validator_changes(self) -> ConsensusValidatorChanges - where - REv: From, + where + REv: From, { self.make_request(ConsensusRequest::ValidatorChanges, QueueKind::Consensus) .await @@ -2151,8 +2151,8 @@ impl EffectBuilder { era_id: Option, serialize: fn(&EraDump<'_>) -> Result, Cow<'static, str>>, ) -> Result, Cow<'static, str>> - where - REv: From, + where + REv: From, { self.make_request( |responder| DumpConsensusStateRequest { @@ -2162,13 +2162,13 @@ impl EffectBuilder { }, QueueKind::Control, ) - .await + .await } /// Dump the event queue contents to the diagnostics port, using the given serializer. pub(crate) async fn diagnostics_port_dump_queue(self, dump_format: QueueDumpFormat) - where - REv: From, + where + REv: From, { self.make_request( |responder| ControlAnnouncement::QueueDumpRequest { @@ -2177,13 +2177,13 @@ impl EffectBuilder { }, QueueKind::Control, ) - .await + .await } /// Activates/deactivates a failpoint from a given activation. pub(crate) async fn activate_failpoint(self, activation: FailpointActivation) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -2195,8 +2195,8 @@ impl EffectBuilder { /// Announce that the node be shut down due to a request from a user. pub(crate) async fn announce_user_shutdown_request(self) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -2209,8 +2209,8 @@ impl EffectBuilder { /// Announce that a block which wasn't previously stored on this node has been fetched and /// stored. pub(crate) async fn announce_fetched_new_block(self, block: Arc, peer: NodeId) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -2243,14 +2243,14 @@ impl EffectBuilder { /// Get the bytes for the chainspec file and genesis_accounts /// and global_state bytes if the files are present. pub(crate) async fn get_chainspec_raw_bytes(self) -> Arc - where - REv: From + Send, + where + REv: From + Send, { self.make_request( ChainspecRawBytesRequest::GetChainspecRawBytes, QueueKind::NetworkInfo, ) - .await + .await } /// Stores a set of given finalized approvals in storage. @@ -2261,8 +2261,8 @@ impl EffectBuilder { transaction_hash: TransactionHash, finalized_approvals: BTreeSet, ) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::StoreFinalizedApprovals { @@ -2272,7 +2272,7 @@ impl EffectBuilder { }, QueueKind::ToStorage, ) - .await + .await } /// Requests execution of a single transaction, without committing its effects. Intended to be @@ -2282,8 +2282,8 @@ impl EffectBuilder { block_header: Box, transaction: Box, ) -> SpeculativeExecutionResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::SpeculativelyExecute { @@ -2293,7 +2293,7 @@ impl EffectBuilder { }, QueueKind::ContractRuntime, ) - .await + .await } /// Reads block execution results (or chunk) from Storage component. @@ -2301,14 +2301,14 @@ impl EffectBuilder { self, id: BlockExecutionResultsOrChunkId, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetBlockExecutionResultsOrChunk { id, responder }, QueueKind::FromStorage, ) - .await + .await } /// Gets peers for a given block from the block accumulator. @@ -2316,8 +2316,8 @@ impl EffectBuilder { self, block_hash: BlockHash, ) -> Option> - where - REv: From, + where + REv: From, { self.make_request( |responder| BlockAccumulatorRequest::GetPeersForBlock { @@ -2326,21 +2326,21 @@ impl EffectBuilder { }, QueueKind::NetworkInfo, ) - .await + .await } /// Set a new stopping point for the node. /// /// Returns a potentially previously set stop-at spec. pub(crate) async fn set_node_stop_at(self, stop_at: Option) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| SetNodeStopRequest { stop_at, responder }, QueueKind::Control, ) - .await + .await } } diff --git a/node/src/effect/requests.rs b/node/src/effect/requests.rs index 033aab0a0f..c483e46cd8 100644 --- a/node/src/effect/requests.rs +++ b/node/src/effect/requests.rs @@ -134,8 +134,8 @@ impl

NetworkRequest

{ /// /// This is a replacement for a `From` conversion that is not possible without specialization. pub(crate) fn map_payload(self, wrap_payload: F) -> NetworkRequest - where - F: FnOnce(P) -> P2, + where + F: FnOnce(P) -> P2, { match self { NetworkRequest::SendMessage { @@ -176,8 +176,8 @@ impl

NetworkRequest

{ } impl

Display for NetworkRequest

-where - P: Display, + where + P: Display, { fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { match self { @@ -242,8 +242,8 @@ impl Display for NetworkInfoRequest { #[derive(Debug, Serialize)] #[must_use] pub(crate) struct BeginGossipRequest -where - T: GossipItem, + where + T: GossipItem, { pub(crate) item_id: T::Id, pub(crate) source: Source, @@ -252,8 +252,8 @@ where } impl Display for BeginGossipRequest -where - T: GossipItem, + where + T: GossipItem, { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "begin gossip of {} from {}", self.item_id, self.source) @@ -493,10 +493,15 @@ pub(crate) enum StorageRequest { }, /// Retrieve the height of the final block of the previous protocol version, if known. GetKeyBlockHeightForActivationPoint { responder: Responder> }, + /// Retrieve the block utilization score. GetBlockUtilizationScore { + /// The era id. era_id: EraId, + /// The block height of the switch block block_height: u64, - transaction_count: u64, + /// The utilization within the switch block. + switch_block_utilization: u64, + /// Responder, responded once the utilization for the era has been determined. responder: Responder>, }, } @@ -624,7 +629,7 @@ impl Display for StorageRequest { write!(formatter, "put block header: {}", block_header) } StorageRequest::GetAvailableBlockRange { .. } => { - write!(formatter, "get available block range",) + write!(formatter, "get available block range", ) } StorageRequest::StoreFinalizedApprovals { transaction_hash, .. @@ -636,7 +641,7 @@ impl Display for StorageRequest { ) } StorageRequest::PutExecutedBlock { block, .. } => { - write!(formatter, "put executed block {}", block.hash(),) + write!(formatter, "put executed block {}", block.hash(), ) } StorageRequest::GetKeyBlockHeightForActivationPoint { .. } => { write!( @@ -985,7 +990,7 @@ pub(crate) struct SyncGlobalStateRequest { pub(crate) state_root_hash: Digest, #[serde(skip)] pub(crate) responder: - Responder>, + Responder>, } impl Display for SyncGlobalStateRequest { diff --git a/node/src/reactor/main_reactor/tests.rs b/node/src/reactor/main_reactor/tests.rs index d83e0e8215..f2b18b43fe 100644 --- a/node/src/reactor/main_reactor/tests.rs +++ b/node/src/reactor/main_reactor/tests.rs @@ -12,6 +12,7 @@ use std::{ }; use either::Either; +use itertools::Itertools; use num::Zero; use num_rational::Ratio; use num_traits::One; @@ -37,12 +38,12 @@ use casper_types::{ AUCTION, }, testing::TestRng, - AccountConfig, AccountsConfig, ActivationPoint, AddressableEntityHash, AvailableBlockRange, - Block, BlockHash, BlockHeader, BlockV2, CLValue, Chainspec, ChainspecRawBytes, - ConsensusProtocolName, Deploy, EraId, FeeHandling, Gas, HoldsEpoch, Key, Motes, NextUpgrade, - PricingHandling, PricingMode, ProtocolVersion, PublicKey, RefundHandling, Rewards, SecretKey, - StoredValue, SystemEntityRegistry, TimeDiff, Timestamp, Transaction, TransactionHash, - TransactionV1Builder, ValidatorConfig, U512, + AccountConfig, AccountsConfig, ActivationPoint, AddressableEntityHash, + AvailableBlockRange, Block, BlockHash, BlockHeader, BlockV2, CLValue, Chainspec, + ChainspecRawBytes, ConsensusProtocolName, Deploy, EraId, FeeHandling, Gas, HoldsEpoch, Key, + Motes, NextUpgrade, PricingHandling, PricingMode, ProtocolVersion, PublicKey, RefundHandling, + Rewards, SecretKey, StoredValue, SystemEntityRegistry, TimeDiff, Timestamp, Transaction, + TransactionHash, TransactionV1Builder, ValidatorConfig, U512, }; use crate::{ @@ -499,8 +500,8 @@ impl TestFixture { /// /// Returns an error if the condition isn't met in time. async fn try_run_until(&mut self, condition: F, within: Duration) -> Result<(), Elapsed> - where - F: Fn(&Nodes) -> bool, + where + F: Fn(&Nodes) -> bool, { self.network .try_settle_on(&mut self.rng, condition, within) @@ -511,8 +512,8 @@ impl TestFixture { /// /// Panics if the condition isn't met in time. async fn run_until(&mut self, condition: F, within: Duration) - where - F: Fn(&Nodes) -> bool, + where + F: Fn(&Nodes) -> bool, { self.network .settle_on(&mut self.rng, condition, within) @@ -541,7 +542,7 @@ impl TestFixture { }, within, ) - .await + .await } /// Runs the network until all nodes reach the given completed block height. @@ -571,14 +572,14 @@ impl TestFixture { }, within, ) - .await - .unwrap_or_else(|_| { - panic!( - "should reach {} within {} seconds", - era_id, - within.as_secs_f64(), - ) - }) + .await + .unwrap_or_else(|_| { + panic!( + "should reach {} within {} seconds", + era_id, + within.as_secs_f64(), + ) + }) } /// Runs the network until all nodes' storage components have stored the switch block header for @@ -600,14 +601,14 @@ impl TestFixture { }, within, ) - .await - .unwrap_or_else(|_| { - panic!( - "should have stored switch block header for {} within {} seconds", - era_id, - within.as_secs_f64(), - ) - }) + .await + .unwrap_or_else(|_| { + panic!( + "should have stored switch block header for {} within {} seconds", + era_id, + within.as_secs_f64(), + ) + }) } /// Runs the network until all nodes have executed the given transaction and stored the @@ -650,14 +651,14 @@ impl TestFixture { }, within, ) - .await - .unwrap_or_else(|_| { - panic!( - "should have stored execution result for {} within {} seconds", - txn_hash, - within.as_secs_f64(), - ) - }) + .await + .unwrap_or_else(|_| { + panic!( + "should have stored execution result for {} within {} seconds", + txn_hash, + within.as_secs_f64(), + ) + }) } async fn schedule_upgrade_for_era_two(&mut self) { @@ -784,7 +785,7 @@ impl TestFixture { } #[track_caller] - fn check_account_balance_at_tip(&self, account_public_key: PublicKey) -> (URef, U512) { + fn check_account_balance_hold_at_tip(&self, account_public_key: PublicKey) -> U512 { let (_, runner) = self .network .nodes() @@ -819,13 +820,15 @@ impl TestFixture { .balance(balance_request); if let BalanceResult::Success { - purse_addr, - available_balance, - .. + balance_holds, .. } = balance_result { - let purse = URef::new(purse_addr, AccessRights::all()); - (purse, available_balance) + balance_holds + .values() + .flat_map(|holds| holds.values().map(|(v, _)| *v)) + .collect_vec() + .into_iter() + .sum() } else { panic!("failed balance result") } @@ -875,11 +878,11 @@ impl TestFixture { { ExecutionResult::V1(_) => unreachable!(), ExecutionResult::V2(ExecutionResultV2 { - effects, - consumed: gas, - error_message, - .. - }) => { + effects, + consumed: gas, + error_message, + .. + }) => { if error_message.is_none() { effects.transforms().to_vec() } else { @@ -900,7 +903,7 @@ impl TestFixture { pub fn run_until_stopped( self, rng: TestRng, - ) -> impl futures::Future>, TestRng)> { + ) -> impl futures::Future>, TestRng)> { self.network.crank_until_stopped(rng) } } @@ -1571,10 +1574,10 @@ async fn empty_block_validation_regression() { .inner_mut() .set_filter(move |event| match event { MainEvent::Consensus(consensus::Event::NewBlockPayload(NewBlockPayload { - era_id, - block_payload: _, - block_context, - })) => { + era_id, + block_payload: _, + block_context, + })) => { info!("Accusing everyone else!"); // We hook into the NewBlockPayload event to replace the block being proposed with // an empty one that accuses all the validators, except the malicious validator. @@ -2146,16 +2149,16 @@ async fn run_rewards_network_scenario( let rewarded_blocks = &blocks[rewarded_range]; let block_reward = (Ratio::::one() - fixture - .chainspec - .core_config - .finality_signature_proportion - .into_u512()) + .chainspec + .core_config + .finality_signature_proportion + .into_u512()) * recomputed_total_supply[&(i - 1)] * fixture - .chainspec - .core_config - .round_seigniorage_rate - .into_u512(); + .chainspec + .core_config + .round_seigniorage_rate + .into_u512(); let signatures_reward = fixture .chainspec .core_config @@ -2163,10 +2166,10 @@ async fn run_rewards_network_scenario( .into_u512() * recomputed_total_supply[&(i - 1)] * fixture - .chainspec - .core_config - .round_seigniorage_rate - .into_u512(); + .chainspec + .core_config + .round_seigniorage_rate + .into_u512(); let previous_signatures_reward = if switch_blocks.headers[i - 1].is_genesis() { None } else { @@ -2178,10 +2181,10 @@ async fn run_rewards_network_scenario( .into_u512() * recomputed_total_supply[&(i - 2)] * fixture - .chainspec - .core_config - .round_seigniorage_rate - .into_u512(), + .chainspec + .core_config + .round_seigniorage_rate + .into_u512(), ) }; @@ -2329,8 +2332,8 @@ async fn run_rewards_network_scenario( .get(era) .expect("expected recalculated supply") - recomputed_total_supply - .get(&(era - 1)) - .expect("expected recalculated supply"), + .get(&(era - 1)) + .expect("expected recalculated supply"), "supply growth does not match rewards at era {}", era ) @@ -2359,7 +2362,7 @@ async fn run_reward_network_zug_all_finality_small_prime_five_eras() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2383,7 +2386,7 @@ async fn run_reward_network_zug_all_finality_small_prime_five_eras_no_lookback() ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2407,7 +2410,7 @@ async fn run_reward_network_zug_no_finality_small_nominal_five_eras() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2431,7 +2434,7 @@ async fn run_reward_network_zug_half_finality_half_finders_small_nominal_five_er ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2455,7 +2458,7 @@ async fn run_reward_network_zug_half_finality_half_finders_small_nominal_five_er ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2479,7 +2482,7 @@ async fn run_reward_network_zug_all_finality_half_finders_small_nominal_five_era ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2505,7 +2508,7 @@ async fn run_reward_network_zug_all_finality_half_finders() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2531,7 +2534,7 @@ async fn run_reward_network_zug_all_finality_half_finders_five_eras() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2557,7 +2560,7 @@ async fn run_reward_network_zug_all_finality_zero_finders() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2583,7 +2586,7 @@ async fn run_reward_network_highway_all_finality_zero_finders() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2609,7 +2612,7 @@ async fn run_reward_network_highway_no_finality() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2646,25 +2649,20 @@ async fn should_raise_gas_price_to_ceiling_and_reduce_to_floor() { let mut current_era = switch_block.era_id(); let chain_name = fixture.chainspec.network_config.name.clone(); - let (purse, _) = fixture.check_account_balance_at_tip(alice_public_key.clone()); // Run the network at load for at least 5 eras. for _ in 0..5 { let target_public_key = PublicKey::random(&mut fixture.rng); - let fixed_native_mint_transaction = TransactionV1Builder::new_transfer( - 10_000_000_000u64, - Some(purse), - target_public_key, - None, - ) - .expect("must get builder") - .with_chain_name(chain_name.clone()) - .with_secret_key(&alice_secret_key) - .with_pricing_mode(PricingMode::Fixed { - gas_price_tolerance: max_gas_price, - }) - .build() - .expect("must get transaction"); + let fixed_native_mint_transaction = + TransactionV1Builder::new_transfer(10_000_000_000u64, None, target_public_key, None) + .expect("must get builder") + .with_chain_name(chain_name.clone()) + .with_secret_key(&alice_secret_key) + .with_pricing_mode(PricingMode::Fixed { + gas_price_tolerance: max_gas_price, + }) + .build() + .expect("must get transaction"); let txn = Transaction::V1(fixed_native_mint_transaction); fixture.inject_transaction(txn).await; @@ -2680,8 +2678,11 @@ async fn should_raise_gas_price_to_ceiling_and_reduce_to_floor() { assert_eq!(actual_gas_price, expected_gas_price); let target_public_key = PublicKey::random(&mut fixture.rng); + let holds_before = fixture.check_account_balance_hold_at_tip(alice_public_key.clone()); + let amount = 10_000_000_000u64; + let fixed_native_mint_transaction = - TransactionV1Builder::new_transfer(10_000_000_000u64, Some(purse), target_public_key, None) + TransactionV1Builder::new_transfer(amount, None, target_public_key, None) .expect("must get builder") .with_chain_name(chain_name) .with_secret_key(&alice_secret_key) @@ -2694,14 +2695,12 @@ async fn should_raise_gas_price_to_ceiling_and_reduce_to_floor() { let txn = Transaction::V1(fixed_native_mint_transaction); let txn_hash = txn.hash(); - let (_, balance_before) = fixture.check_account_balance_at_tip(alice_public_key.clone()); - fixture.inject_transaction(txn).await; fixture .run_until_executed_transaction(&txn_hash, TEN_SECS) .await; - let (_, balance_after) = fixture.check_account_balance_at_tip(alice_public_key.clone()); + let holds_after = fixture.check_account_balance_hold_at_tip(alice_public_key.clone()); let current_gas_price = fixture .highest_complete_block() @@ -2709,7 +2708,7 @@ async fn should_raise_gas_price_to_ceiling_and_reduce_to_floor() { .expect("must have gas price"); let cost = fixture.chainspec.system_costs_config.mint_costs().transfer * (current_gas_price as u32); - assert_eq!(balance_before, balance_after + U512::from(cost)); + assert_eq!(holds_after, holds_before + U512::from(cost)); // Run the network at zero load and ensure the value falls back to the floor. for _ in 0..5 { From 5936c1540c307a76e8bd78d032399f7ec466386e Mon Sep 17 00:00:00 2001 From: Karan Dhareshwar Date: Thu, 28 Mar 2024 14:36:17 -0500 Subject: [PATCH 59/70] Run make format --- node/src/components/storage.rs | 49 +- node/src/effect.rs | 670 ++++++++++++------------- node/src/effect/requests.rs | 22 +- node/src/reactor/main_reactor/tests.rs | 153 +++--- 4 files changed, 447 insertions(+), 447 deletions(-) diff --git a/node/src/components/storage.rs b/node/src/components/storage.rs index 1731f5be45..0dd90e58e9 100644 --- a/node/src/components/storage.rs +++ b/node/src/components/storage.rs @@ -180,8 +180,8 @@ impl Display for HighestOrphanedBlockResult { } impl Component for Storage - where - REv: From + From> + Send, +where + REv: From + From> + Send, { type Event = Event; @@ -396,8 +396,8 @@ impl Storage { effect_builder: EffectBuilder, incoming: &NetRequestIncoming, ) -> Result, GetRequestError> - where - REv: From> + Send, + where + REv: From> + Send, { if self.enable_mem_deduplication { let unique_id = incoming.message.unique_id(); @@ -869,7 +869,7 @@ impl Storage { signature.era_id(), signature.chain_name_hash(), ) - .into(), + .into(), } }; match (&mut block_signatures, *signature) { @@ -1009,8 +1009,11 @@ impl Storage { switch_block_utilization: switch_block_utilization, responder, } => { - let utilization = - self.get_block_utilization_score(era_id, block_height, switch_block_utilization); + let utilization = self.get_block_utilization_score( + era_id, + block_height, + switch_block_utilization, + ); responder.respond(utilization).ignore() } @@ -1042,7 +1045,7 @@ impl Storage { #[allow(clippy::type_complexity)] fn get_transactions_with_finalized_approvals<'a>( &self, - transaction_hashes: impl Iterator, + transaction_hashes: impl Iterator, ) -> Result>)>; 1]>, FatalStorageError> { let mut ro_txn = self.block_store.checkout_ro()?; @@ -1270,8 +1273,8 @@ impl Storage { let mut transactions = vec![]; for (transaction, _) in (self .get_transactions_with_finalized_approvals(block.all_transactions())?) - .into_iter() - .flatten() + .into_iter() + .flatten() { transactions.push(transaction) } @@ -1633,7 +1636,7 @@ impl Storage { fn get_transaction_with_finalized_approvals( &self, txn: &mut (impl DataReader - + DataReader>), + + DataReader>), transaction_hash: &TransactionHash, ) -> Result>)>, FatalStorageError> { let maybe_transaction: Option = txn.read(*transaction_hash)?; @@ -1738,9 +1741,9 @@ impl Storage { serialized_id: &[u8], fetch_response: FetchResponse, ) -> Result, FatalStorageError> - where - REv: From> + Send, - T: FetchItem, + where + REv: From> + Send, + T: FetchItem, { let serialized = fetch_response .to_serialized() @@ -1863,7 +1866,7 @@ impl Storage { block.era_id(), self.chain_name_hash, ) - .into(), + .into(), } } @@ -1930,8 +1933,8 @@ impl Storage { fn get_execution_results_with_transaction_headers( &self, txn: &mut (impl DataReader - + DataReader - + DataReader), + + DataReader + + DataReader), block_hash: &BlockHash, ) -> Result>, FatalStorageError> { @@ -2001,8 +2004,8 @@ impl Storage { /// Decodes an item's ID, typically from an incoming request. fn decode_item_id(raw: &[u8]) -> Result - where - T: FetchItem, +where + T: FetchItem, { bincode::deserialize(raw).map_err(GetRequestError::MalformedIncomingItemId) } @@ -2081,10 +2084,10 @@ fn successful_transfers(execution_result: &ExecutionResult) -> Vec { } } ExecutionResult::V2(ExecutionResultV2 { - transfers, - error_message, - .. - }) => { + transfers, + error_message, + .. + }) => { if error_message.is_none() { for transfer in transfers { all_transfers.push(transfer.clone()); diff --git a/node/src/effect.rs b/node/src/effect.rs index 79c3f89ced..be16469130 100644 --- a/node/src/effect.rs +++ b/node/src/effect.rs @@ -322,13 +322,13 @@ impl Responder { impl Debug for Responder { fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { - write!(formatter, "Responder<{}>", type_name::(), ) + write!(formatter, "Responder<{}>", type_name::(),) } } impl Display for Responder { fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { - write!(formatter, "responder({})", type_name::(), ) + write!(formatter, "responder({})", type_name::(),) } } @@ -371,21 +371,21 @@ pub(crate) trait EffectExt: Future + Send { /// /// The function `f` is used to translate the returned value from an effect into an event. fn event(self, f: F) -> Effects - where - F: FnOnce(Self::Output) -> U + 'static + Send, - U: 'static, - Self: Sized; + where + F: FnOnce(Self::Output) -> U + 'static + Send, + U: 'static, + Self: Sized; /// Finalizes a future into an effect that returns an iterator of events. /// /// The function `f` is used to translate the returned value from an effect into an iterator of /// events. fn events(self, f: F) -> Effects - where - F: FnOnce(Self::Output) -> I + 'static + Send, - U: 'static, - I: Iterator, - Self: Sized; + where + F: FnOnce(Self::Output) -> I + 'static + Send, + U: 'static, + I: Iterator, + Self: Sized; /// Finalizes a future into an effect that runs but drops the result. fn ignore(self) -> Effects; @@ -404,10 +404,10 @@ pub(crate) trait EffectResultExt { /// The function `f_ok` is used to translate the returned value from an effect into an event, /// while the function `f_err` does the same for a potential error. fn result(self, f_ok: F, f_err: G) -> Effects - where - F: FnOnce(Self::Value) -> U + 'static + Send, - G: FnOnce(Self::Error) -> U + 'static + Send, - U: 'static; + where + F: FnOnce(Self::Value) -> U + 'static + Send, + G: FnOnce(Self::Error) -> U + 'static + Send, + U: 'static; } /// Effect extension for futures, used to convert futures returning an `Option` into two different @@ -421,38 +421,38 @@ pub(crate) trait EffectOptionExt { /// The function `f_some` is used to translate the returned value from an effect into an event, /// while the function `f_none` does the same for a returned `None`. fn map_or_else(self, f_some: F, f_none: G) -> Effects - where - F: FnOnce(Self::Value) -> U + 'static + Send, - G: FnOnce() -> U + 'static + Send, - U: 'static; + where + F: FnOnce(Self::Value) -> U + 'static + Send, + G: FnOnce() -> U + 'static + Send, + U: 'static; /// Finalizes a future returning an `Option` into two different effects. /// /// The function `f` is used to translate the returned value from an effect into an event, /// In the case of `None`, empty vector of effects is returned. fn map_some(self, f: F) -> Effects - where - F: FnOnce(Self::Value) -> U + 'static + Send, - U: 'static; + where + F: FnOnce(Self::Value) -> U + 'static + Send, + U: 'static; } impl EffectExt for T - where - T: Future + Send + 'static + Sized, +where + T: Future + Send + 'static + Sized, { fn event(self, f: F) -> Effects - where - F: FnOnce(Self::Output) -> U + 'static + Send, - U: 'static, + where + F: FnOnce(Self::Output) -> U + 'static + Send, + U: 'static, { smallvec![self.map(f).map(|item| smallvec![item]).boxed()] } fn events(self, f: F) -> Effects - where - F: FnOnce(Self::Output) -> I + 'static + Send, - U: 'static, - I: Iterator, + where + F: FnOnce(Self::Output) -> I + 'static + Send, + U: 'static, + I: Iterator, { smallvec![self.map(f).map(|iter| iter.collect()).boxed()] } @@ -463,18 +463,18 @@ impl EffectExt for T } impl EffectResultExt for T - where - T: Future> + Send + 'static + Sized, - T: ?Sized, +where + T: Future> + Send + 'static + Sized, + T: ?Sized, { type Value = V; type Error = E; fn result(self, f_ok: F, f_err: G) -> Effects - where - F: FnOnce(V) -> U + 'static + Send, - G: FnOnce(E) -> U + 'static + Send, - U: 'static, + where + F: FnOnce(V) -> U + 'static + Send, + G: FnOnce(E) -> U + 'static + Send, + U: 'static, { smallvec![self .map(|result| result.map_or_else(f_err, f_ok)) @@ -484,17 +484,17 @@ impl EffectResultExt for T } impl EffectOptionExt for T - where - T: Future> + Send + 'static + Sized, - T: ?Sized, +where + T: Future> + Send + 'static + Sized, + T: ?Sized, { type Value = V; fn map_or_else(self, f_some: F, f_none: G) -> Effects - where - F: FnOnce(V) -> U + 'static + Send, - G: FnOnce() -> U + 'static + Send, - U: 'static, + where + F: FnOnce(V) -> U + 'static + Send, + G: FnOnce() -> U + 'static + Send, + U: 'static, { smallvec![self .map(|option| option.map_or_else(f_none, f_some)) @@ -507,9 +507,9 @@ impl EffectOptionExt for T /// The function `f` is used to translate the returned value from an effect into an event, /// In the case of `None`, empty vector is returned. fn map_some(self, f: F) -> Effects - where - F: FnOnce(Self::Value) -> U + 'static + Send, - U: 'static, + where + F: FnOnce(Self::Value) -> U + 'static + Send, + U: 'static, { smallvec![self .map(|option| option @@ -570,10 +570,10 @@ impl EffectBuilder { /// This future is cancellation safe: If it is dropped without being polled, it merely indicates /// the original requester is not longer interested in the result, which will be discarded. pub(crate) async fn make_request(self, f: F, queue_kind: QueueKind) -> T - where - T: Send + 'static, - Q: Into, - F: FnOnce(Responder) -> Q, + where + T: Send + 'static, + Q: Into, + F: FnOnce(Responder) -> Q, { let (event, wait_future) = self.create_request_parts(f); @@ -589,11 +589,11 @@ impl EffectBuilder { /// creates both of them without processing or spawning either. /// /// Usually you will want to call the higher level `make_request` function. - pub(crate) fn create_request_parts(self, f: F) -> (REv, impl Future) - where - T: Send + 'static, - Q: Into, - F: FnOnce(Responder) -> Q, + pub(crate) fn create_request_parts(self, f: F) -> (REv, impl Future) + where + T: Send + 'static, + Q: Into, + F: FnOnce(Responder) -> Q, { // Prepare a channel. let (sender, receiver) = oneshot::channel(); @@ -637,7 +637,7 @@ impl EffectBuilder { /// "do nothing", as it will still cause a task to be spawned. #[inline(always)] #[allow(clippy::manual_async_fn)] - pub(crate) fn immediately(self) -> impl Future + Send { + pub(crate) fn immediately(self) -> impl Future + Send { // Note: This function is implemented manually without `async` sugar because the `Send` // inference seems to not work in all cases otherwise. async {} @@ -647,8 +647,8 @@ impl EffectBuilder { /// /// Usually causes the node to cease operations quickly and exit/crash. pub(crate) async fn fatal(self, file: &'static str, line: u32, msg: String) - where - REv: From, + where + REv: From, { self.event_queue .schedule(FatalAnnouncement { file, line, msg }, QueueKind::Control) @@ -666,14 +666,14 @@ impl EffectBuilder { /// /// If an error occurred producing the metrics, `None` is returned. pub(crate) async fn get_metrics(self) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| MetricsRequest::RenderNodeMetricsText { responder }, QueueKind::Api, ) - .await + .await } /// Sends a network message. @@ -681,8 +681,8 @@ impl EffectBuilder { /// The message is queued and sent, but no delivery guaranteed. Will return after the message /// has been buffered in the outgoing kernel buffer and thus is subject to backpressure. pub(crate) async fn send_message

(self, dest: NodeId, payload: P) - where - REv: From>, + where + REv: From>, { self.make_request( |responder| NetworkRequest::SendMessage { @@ -693,7 +693,7 @@ impl EffectBuilder { }, QueueKind::Network, ) - .await; + .await; } /// Enqueues a network message. @@ -701,8 +701,8 @@ impl EffectBuilder { /// The message is queued in "fire-and-forget" fashion, there is no guarantee that the peer /// will receive it. Returns as soon as the message is queued inside the networking component. pub(crate) async fn enqueue_message

(self, dest: NodeId, payload: P) - where - REv: From>, + where + REv: From>, { self.make_request( |responder| NetworkRequest::SendMessage { @@ -713,13 +713,13 @@ impl EffectBuilder { }, QueueKind::Network, ) - .await; + .await; } /// Broadcasts a network message to validator peers in the given era. pub(crate) async fn broadcast_message_to_validators

(self, payload: P, era_id: EraId) - where - REv: From>, + where + REv: From>, { self.make_request( |responder| { @@ -732,7 +732,7 @@ impl EffectBuilder { }, QueueKind::Network, ) - .await; + .await; } /// Gossips a network message. @@ -748,9 +748,9 @@ impl EffectBuilder { count: usize, exclude: HashSet, ) -> HashSet - where - REv: From>, - P: Send, + where + REv: From>, + P: Send, { self.make_request( |responder| NetworkRequest::Gossip { @@ -762,50 +762,50 @@ impl EffectBuilder { }, QueueKind::Network, ) - .await - .unwrap_or_default() + .await + .unwrap_or_default() } /// Gets a structure describing the current network status. pub(crate) async fn get_network_insights(self) -> NetworkInsights - where - REv: From, + where + REv: From, { self.make_request( |responder| NetworkInfoRequest::Insight { responder }, QueueKind::Regular, ) - .await + .await } /// Gets a map of the current network peers to their socket addresses. pub(crate) async fn network_peers(self) -> BTreeMap - where - REv: From, + where + REv: From, { self.make_request( |responder| NetworkInfoRequest::Peers { responder }, QueueKind::Api, ) - .await + .await } /// Gets up to `count` fully-connected network peers in random order. pub async fn get_fully_connected_peers(self, count: usize) -> Vec - where - REv: From, + where + REv: From, { self.make_request( |responder| NetworkInfoRequest::FullyConnectedPeers { count, responder }, QueueKind::NetworkInfo, ) - .await + .await } /// Announces which transactions have expired. pub(crate) async fn announce_expired_transactions(self, hashes: Vec) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -817,8 +817,8 @@ impl EffectBuilder { /// Announces an incoming network message. pub(crate) async fn announce_incoming

(self, sender: NodeId, payload: P) - where - REv: FromIncoming

, + where + REv: FromIncoming

, { self.event_queue .schedule( @@ -830,8 +830,8 @@ impl EffectBuilder { /// Announces that a gossiper has received a new item, where the item's ID is the complete item. pub(crate) async fn announce_complete_item_received_via_gossip(self, item: T::Id) - where - REv: From>, + where + REv: From>, { assert!( T::ID_IS_COMPLETE_ITEM, @@ -886,8 +886,8 @@ impl EffectBuilder { self, block_hash: BlockHash, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| MakeBlockExecutableRequest { @@ -896,7 +896,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Request that a block with a specific height be marked completed. @@ -905,8 +905,8 @@ impl EffectBuilder { /// have been persisted to storage and its global state root hash is missing no dependencies /// in the global state. pub(crate) async fn mark_block_completed(self, block_height: u64) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| MarkBlockCompletedRequest { @@ -915,7 +915,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Try to accept a transaction received from the JSON-RPC server. @@ -924,8 +924,8 @@ impl EffectBuilder { transaction: Transaction, is_speculative: bool, ) -> Result<(), transaction_acceptor::Error> - where - REv: From, + where + REv: From, { self.make_request( |responder| AcceptTransactionRequest { @@ -935,7 +935,7 @@ impl EffectBuilder { }, QueueKind::Api, ) - .await + .await } /// Announces that a transaction not previously stored has now been accepted and stored. @@ -943,9 +943,9 @@ impl EffectBuilder { self, transaction: Arc, source: Source, - ) -> impl Future - where - REv: From, + ) -> impl Future + where + REv: From, { self.event_queue.schedule( TransactionAcceptorAnnouncement::AcceptedNewTransaction { @@ -959,9 +959,9 @@ impl EffectBuilder { /// Announces that we have received a gossip message from this peer, /// implying the peer holds the indicated item. pub(crate) async fn announce_gossip_received(self, item_id: T::Id, sender: NodeId) - where - REv: From>, - T: GossipItem, + where + REv: From>, + T: GossipItem, { self.event_queue .schedule( @@ -973,9 +973,9 @@ impl EffectBuilder { /// Announces that we have finished gossiping the indicated item. pub(crate) async fn announce_finished_gossiping(self, item_id: T::Id) - where - REv: From>, - T: GossipItem, + where + REv: From>, + T: GossipItem, { self.event_queue .schedule( @@ -989,9 +989,9 @@ impl EffectBuilder { self, transaction: Transaction, source: Source, - ) -> impl Future - where - REv: From, + ) -> impl Future + where + REv: From, { self.event_queue.schedule( TransactionAcceptorAnnouncement::InvalidTransaction { @@ -1004,8 +1004,8 @@ impl EffectBuilder { /// Announces upgrade activation point read. pub(crate) async fn announce_upgrade_activation_point_read(self, next_upgrade: NextUpgrade) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -1017,8 +1017,8 @@ impl EffectBuilder { /// Announces a committed Step success. pub(crate) async fn announce_commit_step_success(self, era_id: EraId, effects: ExecutionEffects) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -1048,8 +1048,8 @@ impl EffectBuilder { } pub(crate) async fn announce_new_era_gas_price(self, era_id: EraId, next_era_gas_price: u8) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -1064,9 +1064,9 @@ impl EffectBuilder { /// Begins gossiping an item. pub(crate) async fn begin_gossip(self, item_id: T::Id, source: Source, target: GossipTarget) - where - T: GossipItem, - REv: From>, + where + T: GossipItem, + REv: From>, { self.make_request( |responder| BeginGossipRequest { @@ -1077,19 +1077,19 @@ impl EffectBuilder { }, QueueKind::Gossip, ) - .await + .await } /// Puts the given block into the linear block store. pub(crate) async fn put_block_to_storage(self, block: Arc) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::PutBlock { block, responder }, QueueKind::ToStorage, ) - .await + .await } /// Puts the given approvals hashes into the linear block store. @@ -1097,8 +1097,8 @@ impl EffectBuilder { self, approvals_hashes: Box, ) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::PutApprovalsHashes { @@ -1107,7 +1107,7 @@ impl EffectBuilder { }, QueueKind::ToStorage, ) - .await + .await } /// Puts the given block and approvals hashes into the linear block store. @@ -1117,8 +1117,8 @@ impl EffectBuilder { approvals_hashes: Box, execution_results: HashMap, ) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::PutExecutedBlock { @@ -1129,13 +1129,13 @@ impl EffectBuilder { }, QueueKind::ToStorage, ) - .await + .await } /// Gets the requested block from the linear block store. pub(crate) async fn get_block_from_storage(self, block_hash: BlockHash) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetBlock { @@ -1144,7 +1144,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn get_block_utilization( @@ -1153,8 +1153,8 @@ impl EffectBuilder { block_height: u64, transaction_count: u64, ) -> Option<(u64, u64)> - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetBlockUtilizationScore { @@ -1165,12 +1165,12 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn is_block_stored(self, block_hash: BlockHash) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::IsBlockStored { @@ -1179,7 +1179,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Gets the requested `ApprovalsHashes` from storage. @@ -1187,8 +1187,8 @@ impl EffectBuilder { self, block_hash: BlockHash, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetApprovalsHashes { @@ -1197,7 +1197,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn get_raw_data( @@ -1205,8 +1205,8 @@ impl EffectBuilder { record_id: RecordId, key: Vec, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetRawData { @@ -1216,7 +1216,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Gets the requested block header from the linear block store. @@ -1225,8 +1225,8 @@ impl EffectBuilder { block_hash: BlockHash, only_from_available_block_range: bool, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetBlockHeader { @@ -1236,7 +1236,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn get_block_header_at_height_from_storage( @@ -1244,8 +1244,8 @@ impl EffectBuilder { block_height: u64, only_from_available_block_range: bool, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetBlockHeaderByHeight { @@ -1255,32 +1255,32 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn get_latest_switch_block_header_from_storage(self) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetLatestSwitchBlockHeader { responder }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn get_switch_block_header_by_era_id_from_storage( self, era_id: EraId, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetSwitchBlockHeaderByEra { era_id, responder }, QueueKind::FromStorage, ) - .await + .await } /// Gets the requested signature for a given block hash. @@ -1289,8 +1289,8 @@ impl EffectBuilder { block_hash: BlockHash, public_key: PublicKey, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetBlockSignature { @@ -1300,15 +1300,15 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn get_execution_results_from_storage( self, block_hash: BlockHash, ) -> Option> - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetExecutionResults { @@ -1317,13 +1317,13 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Puts a block header to storage. pub(crate) async fn put_block_header_to_storage(self, block_header: Box) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::PutBlockHeader { @@ -1332,7 +1332,7 @@ impl EffectBuilder { }, QueueKind::ToStorage, ) - .await + .await } /// Puts the requested block signatures into storage. @@ -1340,8 +1340,8 @@ impl EffectBuilder { /// If `signatures.proofs` is empty, no attempt to store will be made, an error will be logged, /// and this function will return `false`. pub(crate) async fn put_signatures_to_storage(self, signatures: BlockSignatures) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::PutBlockSignatures { @@ -1350,15 +1350,15 @@ impl EffectBuilder { }, QueueKind::ToStorage, ) - .await + .await } pub(crate) async fn put_finality_signature_to_storage( self, signature: FinalitySignature, ) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::PutFinalitySignature { @@ -1367,7 +1367,7 @@ impl EffectBuilder { }, QueueKind::ToStorage, ) - .await + .await } /// Gets the requested block's transfers from storage. @@ -1375,8 +1375,8 @@ impl EffectBuilder { self, block_hash: BlockHash, ) -> Option> - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetBlockTransfers { @@ -1385,7 +1385,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Returns the era IDs of the blocks in which the given transactions were executed. If none @@ -1394,8 +1394,8 @@ impl EffectBuilder { self, transaction_hashes: HashSet, ) -> HashSet - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetTransactionsEraIds { @@ -1404,43 +1404,43 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Requests the highest complete block. pub(crate) async fn get_highest_complete_block_from_storage(self) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetHighestCompleteBlock { responder }, QueueKind::FromStorage, ) - .await + .await } /// Requests the highest complete block header. pub(crate) async fn get_highest_complete_block_header_from_storage(self) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetHighestCompleteBlockHeader { responder }, QueueKind::FromStorage, ) - .await + .await } /// Requests the height range of fully available blocks (not just block headers). pub(crate) async fn get_available_block_range_from_storage(self) -> AvailableBlockRange - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetAvailableBlockRange { responder }, QueueKind::FromStorage, ) - .await + .await } /// Synchronize global state under the given root hash. @@ -1449,8 +1449,8 @@ impl EffectBuilder { block_hash: BlockHash, state_root_hash: Digest, ) -> Result - where - REv: From, + where + REv: From, { self.make_request( |responder| SyncGlobalStateRequest { @@ -1460,85 +1460,85 @@ impl EffectBuilder { }, QueueKind::SyncGlobalState, ) - .await + .await } /// Get a trie or chunk by its ID. pub(crate) async fn get_trie(self, request: TrieRequest) -> TrieResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::GetTrie { request, responder }, QueueKind::ContractRuntime, ) - .await + .await } pub(crate) async fn get_reactor_state(self) -> ReactorState - where - REv: From, + where + REv: From, { self.make_request( |responder| ReactorInfoRequest::ReactorState { responder }, QueueKind::Regular, ) - .await + .await } pub(crate) async fn get_last_progress(self) -> LastProgress - where - REv: From, + where + REv: From, { self.make_request( |responder| ReactorInfoRequest::LastProgress { responder }, QueueKind::Regular, ) - .await + .await } pub(crate) async fn get_uptime(self) -> Uptime - where - REv: From, + where + REv: From, { self.make_request( |responder| ReactorInfoRequest::Uptime { responder }, QueueKind::Regular, ) - .await + .await } pub(crate) async fn get_network_name(self) -> NetworkName - where - REv: From, + where + REv: From, { self.make_request( |responder| ReactorInfoRequest::NetworkName { responder }, QueueKind::Regular, ) - .await + .await } pub(crate) async fn get_protocol_version(self) -> ProtocolVersion - where - REv: From, + where + REv: From, { self.make_request( |responder| ReactorInfoRequest::ProtocolVersion { responder }, QueueKind::Regular, ) - .await + .await } pub(crate) async fn get_block_synchronizer_status(self) -> BlockSynchronizerStatus - where - REv: From, + where + REv: From, { self.make_request( |responder| BlockSynchronizerRequest::Status { responder }, QueueKind::Regular, ) - .await + .await } /// Puts a trie into the trie store; succeeds only if all the children of the trie are already @@ -1548,30 +1548,30 @@ impl EffectBuilder { self, request: PutTrieRequest, ) -> PutTrieResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::PutTrie { request, responder }, QueueKind::ContractRuntime, ) - .await + .await } pub(crate) async fn get_current_gas_price(self, era_id: EraId) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::GetEraGasPrice { era_id, responder }, QueueKind::ContractRuntime, ) - .await + .await } pub(crate) async fn put_transaction_to_storage(self, transaction: Transaction) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::PutTransaction { @@ -1580,7 +1580,7 @@ impl EffectBuilder { }, QueueKind::ToStorage, ) - .await + .await } /// Gets the requested transactions from storage. @@ -1591,8 +1591,8 @@ impl EffectBuilder { self, transaction_hashes: Vec, ) -> SmallVec<[Option<(Transaction, Option>)>; 1]> - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetTransactions { @@ -1601,7 +1601,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Gets the requested transaction and its execution info from storage by TransactionHash. @@ -1610,8 +1610,8 @@ impl EffectBuilder { transaction_hash: TransactionHash, with_finalized_approvals: bool, ) -> Option<(Transaction, Option)> - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetTransactionAndExecutionInfo { @@ -1621,7 +1621,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Gets the requested deploy from the deploy store by DeployHash only. @@ -1632,8 +1632,8 @@ impl EffectBuilder { self, deploy_hash: DeployHash, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetLegacyDeploy { @@ -1642,7 +1642,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Gets the requested transaction from storage by TransactionId. @@ -1653,8 +1653,8 @@ impl EffectBuilder { self, transaction_id: TransactionId, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetTransaction { @@ -1663,12 +1663,12 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn is_transaction_stored(self, transaction_id: TransactionId) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::IsTransactionStored { @@ -1677,7 +1677,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } /// Stores the given execution results for the transactions in the given block in the linear @@ -1701,7 +1701,7 @@ impl EffectBuilder { }, QueueKind::ToStorage, ) - .await + .await } /// Gets the requested block and its finality signatures. @@ -1710,8 +1710,8 @@ impl EffectBuilder { block_height: u64, only_from_available_block_range: bool, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetBlockAndMetadataByHeight { @@ -1721,7 +1721,7 @@ impl EffectBuilder { }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn collect_past_blocks_with_metadata( @@ -1729,8 +1729,8 @@ impl EffectBuilder { range: std::ops::Range, only_from_available_block_range: bool, ) -> Vec> - where - REv: From, + where + REv: From, { futures::future::join_all(range.into_iter().map(|block_height| { self.get_block_at_height_with_metadata_from_storage( @@ -1738,9 +1738,9 @@ impl EffectBuilder { only_from_available_block_range, ) })) - .await - .into_iter() - .collect() + .await + .into_iter() + .collect() } /// Gets the requested finality signature from storage. @@ -1748,25 +1748,25 @@ impl EffectBuilder { self, id: Box, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetFinalitySignature { id, responder }, QueueKind::FromStorage, ) - .await + .await } pub(crate) async fn is_finality_signature_stored(self, id: Box) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::IsFinalitySignatureStored { id, responder }, QueueKind::FromStorage, ) - .await + .await } /// Fetches an item from a fetcher. @@ -1776,9 +1776,9 @@ impl EffectBuilder { peer: NodeId, validation_metadata: Box, ) -> FetchResult - where - REv: From>, - T: FetchItem + 'static, + where + REv: From>, + T: FetchItem + 'static, { self.make_request( |responder| FetcherRequest { @@ -1789,7 +1789,7 @@ impl EffectBuilder { }, QueueKind::Fetch, ) - .await + .await } pub(crate) async fn fetch_trie( @@ -1797,8 +1797,8 @@ impl EffectBuilder { hash: Digest, peers: Vec, ) -> Result - where - REv: From, + where + REv: From, { self.make_request( |responder| TrieAccumulatorRequest { @@ -1808,7 +1808,7 @@ impl EffectBuilder { }, QueueKind::SyncGlobalState, ) - .await + .await } /// Passes the timestamp of a future block for which transactions are to be proposed. @@ -1817,8 +1817,8 @@ impl EffectBuilder { timestamp: Timestamp, era_id: EraId, ) -> AppendableBlock - where - REv: From, + where + REv: From, { self.make_request( |responder| TransactionBufferRequest::GetAppendableBlock { @@ -1828,7 +1828,7 @@ impl EffectBuilder { }, QueueKind::Consensus, ) - .await + .await } /// Enqueues a finalized block execution. @@ -1872,8 +1872,8 @@ impl EffectBuilder { proposed_block_height: u64, block: ProposedBlock, ) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| BlockValidationRequest { @@ -1884,13 +1884,13 @@ impl EffectBuilder { }, QueueKind::Regular, ) - .await + .await } /// Announces that a block has been proposed. pub(crate) async fn announce_proposed_block(self, proposed_block: ProposedBlock) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -1902,8 +1902,8 @@ impl EffectBuilder { /// Announces that a block has been finalized. pub(crate) async fn announce_finalized_block(self, finalized_block: FinalizedBlock) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -1915,8 +1915,8 @@ impl EffectBuilder { /// Announces that a meta block has been created or its state has changed. pub(crate) async fn announce_meta_block(self, meta_block: MetaBlock) - where - REv: From, + where + REv: From, { self.event_queue .schedule(MetaBlockAnnouncement(meta_block), QueueKind::Regular) @@ -1926,8 +1926,8 @@ impl EffectBuilder { /// Announces that a finalized block has been created, but it was not /// executed. pub(crate) async fn announce_unexecuted_block(self, block_height: u64) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -1982,8 +1982,8 @@ impl EffectBuilder { /// Gets the next scheduled upgrade, if any. pub(crate) async fn get_next_upgrade(self) -> Option - where - REv: From + Send, + where + REv: From + Send, { self.make_request(UpgradeWatcherRequest, QueueKind::Control) .await @@ -1991,14 +1991,14 @@ impl EffectBuilder { /// Requests a query be executed on the Contract Runtime component. pub(crate) async fn query_global_state(self, request: QueryRequest) -> QueryResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::Query { request, responder }, QueueKind::ContractRuntime, ) - .await + .await } /// Retrieves an `AddressableEntity` from under the given key in global state if present. @@ -2007,8 +2007,8 @@ impl EffectBuilder { state_root_hash: Digest, key: Key, ) -> AddressableEntityResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::GetAddressableEntity { @@ -2018,13 +2018,13 @@ impl EffectBuilder { }, QueueKind::ContractRuntime, ) - .await + .await } /// Retrieves a `Package` from under the given key in global state if present. pub(crate) async fn get_package(self, state_root_hash: Digest, key: Key) -> Option> - where - REv: From, + where + REv: From, { let query_request = QueryRequest::new(state_root_hash, key, vec![]); @@ -2037,14 +2037,14 @@ impl EffectBuilder { /// Requests a query be executed on the Contract Runtime component. pub(crate) async fn get_balance(self, request: BalanceRequest) -> BalanceResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::GetBalance { request, responder }, QueueKind::ContractRuntime, ) - .await + .await } /// Returns a map of validators weights for all eras as known from `root_hash`. @@ -2054,28 +2054,28 @@ impl EffectBuilder { self, request: EraValidatorsRequest, ) -> EraValidatorsResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::GetEraValidators { request, responder }, QueueKind::ContractRuntime, ) - .await + .await } /// Returns the total supply from the given `root_hash`. /// /// This operation is read only. pub(crate) async fn get_total_supply(self, request: TotalSupplyRequest) -> TotalSupplyResult - where - REv: From, + where + REv: From, { self.make_request( move |responder| ContractRuntimeRequest::GetTotalSupply { request, responder }, QueueKind::ContractRuntime, ) - .await + .await } /// Returns the seigniorage rate from the given `root_hash`. @@ -2085,26 +2085,26 @@ impl EffectBuilder { self, request: RoundSeigniorageRateRequest, ) -> RoundSeigniorageRateResult - where - REv: From, + where + REv: From, { self.make_request( move |responder| ContractRuntimeRequest::GetRoundSeigniorageRate { request, responder }, QueueKind::ContractRuntime, ) - .await + .await } /// Requests a query be executed on the Contract Runtime component. pub(crate) async fn get_tagged_values(self, request: TaggedValuesRequest) -> TaggedValuesResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::GetTaggedValues { request, responder }, QueueKind::ContractRuntime, ) - .await + .await } /// Returns the value of the execution results checksum stored in the ChecksumRegistry for the @@ -2113,8 +2113,8 @@ impl EffectBuilder { self, state_root_hash: Digest, ) -> ExecutionResultsChecksumResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::GetExecutionResultsChecksum { @@ -2123,13 +2123,13 @@ impl EffectBuilder { }, QueueKind::ContractRuntime, ) - .await + .await } /// Get our public key from consensus, and if we're a validator, the next round length. pub(crate) async fn consensus_status(self) -> Option - where - REv: From, + where + REv: From, { self.make_request(ConsensusRequest::Status, QueueKind::Consensus) .await @@ -2137,8 +2137,8 @@ impl EffectBuilder { /// Returns a list of validator status changes, by public key. pub(crate) async fn get_consensus_validator_changes(self) -> ConsensusValidatorChanges - where - REv: From, + where + REv: From, { self.make_request(ConsensusRequest::ValidatorChanges, QueueKind::Consensus) .await @@ -2151,8 +2151,8 @@ impl EffectBuilder { era_id: Option, serialize: fn(&EraDump<'_>) -> Result, Cow<'static, str>>, ) -> Result, Cow<'static, str>> - where - REv: From, + where + REv: From, { self.make_request( |responder| DumpConsensusStateRequest { @@ -2162,13 +2162,13 @@ impl EffectBuilder { }, QueueKind::Control, ) - .await + .await } /// Dump the event queue contents to the diagnostics port, using the given serializer. pub(crate) async fn diagnostics_port_dump_queue(self, dump_format: QueueDumpFormat) - where - REv: From, + where + REv: From, { self.make_request( |responder| ControlAnnouncement::QueueDumpRequest { @@ -2177,13 +2177,13 @@ impl EffectBuilder { }, QueueKind::Control, ) - .await + .await } /// Activates/deactivates a failpoint from a given activation. pub(crate) async fn activate_failpoint(self, activation: FailpointActivation) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -2195,8 +2195,8 @@ impl EffectBuilder { /// Announce that the node be shut down due to a request from a user. pub(crate) async fn announce_user_shutdown_request(self) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -2209,8 +2209,8 @@ impl EffectBuilder { /// Announce that a block which wasn't previously stored on this node has been fetched and /// stored. pub(crate) async fn announce_fetched_new_block(self, block: Arc, peer: NodeId) - where - REv: From, + where + REv: From, { self.event_queue .schedule( @@ -2243,14 +2243,14 @@ impl EffectBuilder { /// Get the bytes for the chainspec file and genesis_accounts /// and global_state bytes if the files are present. pub(crate) async fn get_chainspec_raw_bytes(self) -> Arc - where - REv: From + Send, + where + REv: From + Send, { self.make_request( ChainspecRawBytesRequest::GetChainspecRawBytes, QueueKind::NetworkInfo, ) - .await + .await } /// Stores a set of given finalized approvals in storage. @@ -2261,8 +2261,8 @@ impl EffectBuilder { transaction_hash: TransactionHash, finalized_approvals: BTreeSet, ) -> bool - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::StoreFinalizedApprovals { @@ -2272,7 +2272,7 @@ impl EffectBuilder { }, QueueKind::ToStorage, ) - .await + .await } /// Requests execution of a single transaction, without committing its effects. Intended to be @@ -2282,8 +2282,8 @@ impl EffectBuilder { block_header: Box, transaction: Box, ) -> SpeculativeExecutionResult - where - REv: From, + where + REv: From, { self.make_request( |responder| ContractRuntimeRequest::SpeculativelyExecute { @@ -2293,7 +2293,7 @@ impl EffectBuilder { }, QueueKind::ContractRuntime, ) - .await + .await } /// Reads block execution results (or chunk) from Storage component. @@ -2301,14 +2301,14 @@ impl EffectBuilder { self, id: BlockExecutionResultsOrChunkId, ) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| StorageRequest::GetBlockExecutionResultsOrChunk { id, responder }, QueueKind::FromStorage, ) - .await + .await } /// Gets peers for a given block from the block accumulator. @@ -2316,8 +2316,8 @@ impl EffectBuilder { self, block_hash: BlockHash, ) -> Option> - where - REv: From, + where + REv: From, { self.make_request( |responder| BlockAccumulatorRequest::GetPeersForBlock { @@ -2326,21 +2326,21 @@ impl EffectBuilder { }, QueueKind::NetworkInfo, ) - .await + .await } /// Set a new stopping point for the node. /// /// Returns a potentially previously set stop-at spec. pub(crate) async fn set_node_stop_at(self, stop_at: Option) -> Option - where - REv: From, + where + REv: From, { self.make_request( |responder| SetNodeStopRequest { stop_at, responder }, QueueKind::Control, ) - .await + .await } } diff --git a/node/src/effect/requests.rs b/node/src/effect/requests.rs index c483e46cd8..c1dac727cd 100644 --- a/node/src/effect/requests.rs +++ b/node/src/effect/requests.rs @@ -134,8 +134,8 @@ impl

NetworkRequest

{ /// /// This is a replacement for a `From` conversion that is not possible without specialization. pub(crate) fn map_payload(self, wrap_payload: F) -> NetworkRequest - where - F: FnOnce(P) -> P2, + where + F: FnOnce(P) -> P2, { match self { NetworkRequest::SendMessage { @@ -176,8 +176,8 @@ impl

NetworkRequest

{ } impl

Display for NetworkRequest

- where - P: Display, +where + P: Display, { fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { match self { @@ -242,8 +242,8 @@ impl Display for NetworkInfoRequest { #[derive(Debug, Serialize)] #[must_use] pub(crate) struct BeginGossipRequest - where - T: GossipItem, +where + T: GossipItem, { pub(crate) item_id: T::Id, pub(crate) source: Source, @@ -252,8 +252,8 @@ pub(crate) struct BeginGossipRequest } impl Display for BeginGossipRequest - where - T: GossipItem, +where + T: GossipItem, { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "begin gossip of {} from {}", self.item_id, self.source) @@ -629,7 +629,7 @@ impl Display for StorageRequest { write!(formatter, "put block header: {}", block_header) } StorageRequest::GetAvailableBlockRange { .. } => { - write!(formatter, "get available block range", ) + write!(formatter, "get available block range",) } StorageRequest::StoreFinalizedApprovals { transaction_hash, .. @@ -641,7 +641,7 @@ impl Display for StorageRequest { ) } StorageRequest::PutExecutedBlock { block, .. } => { - write!(formatter, "put executed block {}", block.hash(), ) + write!(formatter, "put executed block {}", block.hash(),) } StorageRequest::GetKeyBlockHeightForActivationPoint { .. } => { write!( @@ -990,7 +990,7 @@ pub(crate) struct SyncGlobalStateRequest { pub(crate) state_root_hash: Digest, #[serde(skip)] pub(crate) responder: - Responder>, + Responder>, } impl Display for SyncGlobalStateRequest { diff --git a/node/src/reactor/main_reactor/tests.rs b/node/src/reactor/main_reactor/tests.rs index f2b18b43fe..a5e7b7bd30 100644 --- a/node/src/reactor/main_reactor/tests.rs +++ b/node/src/reactor/main_reactor/tests.rs @@ -38,12 +38,12 @@ use casper_types::{ AUCTION, }, testing::TestRng, - AccountConfig, AccountsConfig, ActivationPoint, AddressableEntityHash, - AvailableBlockRange, Block, BlockHash, BlockHeader, BlockV2, CLValue, Chainspec, - ChainspecRawBytes, ConsensusProtocolName, Deploy, EraId, FeeHandling, Gas, HoldsEpoch, Key, - Motes, NextUpgrade, PricingHandling, PricingMode, ProtocolVersion, PublicKey, RefundHandling, - Rewards, SecretKey, StoredValue, SystemEntityRegistry, TimeDiff, Timestamp, Transaction, - TransactionHash, TransactionV1Builder, ValidatorConfig, U512, + AccountConfig, AccountsConfig, ActivationPoint, AddressableEntityHash, AvailableBlockRange, + Block, BlockHash, BlockHeader, BlockV2, CLValue, Chainspec, ChainspecRawBytes, + ConsensusProtocolName, Deploy, EraId, FeeHandling, Gas, HoldsEpoch, Key, Motes, NextUpgrade, + PricingHandling, PricingMode, ProtocolVersion, PublicKey, RefundHandling, Rewards, SecretKey, + StoredValue, SystemEntityRegistry, TimeDiff, Timestamp, Transaction, TransactionHash, + TransactionV1Builder, ValidatorConfig, U512, }; use crate::{ @@ -500,8 +500,8 @@ impl TestFixture { /// /// Returns an error if the condition isn't met in time. async fn try_run_until(&mut self, condition: F, within: Duration) -> Result<(), Elapsed> - where - F: Fn(&Nodes) -> bool, + where + F: Fn(&Nodes) -> bool, { self.network .try_settle_on(&mut self.rng, condition, within) @@ -512,8 +512,8 @@ impl TestFixture { /// /// Panics if the condition isn't met in time. async fn run_until(&mut self, condition: F, within: Duration) - where - F: Fn(&Nodes) -> bool, + where + F: Fn(&Nodes) -> bool, { self.network .settle_on(&mut self.rng, condition, within) @@ -542,7 +542,7 @@ impl TestFixture { }, within, ) - .await + .await } /// Runs the network until all nodes reach the given completed block height. @@ -572,14 +572,14 @@ impl TestFixture { }, within, ) - .await - .unwrap_or_else(|_| { - panic!( - "should reach {} within {} seconds", - era_id, - within.as_secs_f64(), - ) - }) + .await + .unwrap_or_else(|_| { + panic!( + "should reach {} within {} seconds", + era_id, + within.as_secs_f64(), + ) + }) } /// Runs the network until all nodes' storage components have stored the switch block header for @@ -601,14 +601,14 @@ impl TestFixture { }, within, ) - .await - .unwrap_or_else(|_| { - panic!( - "should have stored switch block header for {} within {} seconds", - era_id, - within.as_secs_f64(), - ) - }) + .await + .unwrap_or_else(|_| { + panic!( + "should have stored switch block header for {} within {} seconds", + era_id, + within.as_secs_f64(), + ) + }) } /// Runs the network until all nodes have executed the given transaction and stored the @@ -651,14 +651,14 @@ impl TestFixture { }, within, ) - .await - .unwrap_or_else(|_| { - panic!( - "should have stored execution result for {} within {} seconds", - txn_hash, - within.as_secs_f64(), - ) - }) + .await + .unwrap_or_else(|_| { + panic!( + "should have stored execution result for {} within {} seconds", + txn_hash, + within.as_secs_f64(), + ) + }) } async fn schedule_upgrade_for_era_two(&mut self) { @@ -819,10 +819,7 @@ impl TestFixture { .data_access_layer() .balance(balance_request); - if let BalanceResult::Success { - balance_holds, .. - } = balance_result - { + if let BalanceResult::Success { balance_holds, .. } = balance_result { balance_holds .values() .flat_map(|holds| holds.values().map(|(v, _)| *v)) @@ -878,11 +875,11 @@ impl TestFixture { { ExecutionResult::V1(_) => unreachable!(), ExecutionResult::V2(ExecutionResultV2 { - effects, - consumed: gas, - error_message, - .. - }) => { + effects, + consumed: gas, + error_message, + .. + }) => { if error_message.is_none() { effects.transforms().to_vec() } else { @@ -903,7 +900,7 @@ impl TestFixture { pub fn run_until_stopped( self, rng: TestRng, - ) -> impl futures::Future>, TestRng)> { + ) -> impl futures::Future>, TestRng)> { self.network.crank_until_stopped(rng) } } @@ -1574,10 +1571,10 @@ async fn empty_block_validation_regression() { .inner_mut() .set_filter(move |event| match event { MainEvent::Consensus(consensus::Event::NewBlockPayload(NewBlockPayload { - era_id, - block_payload: _, - block_context, - })) => { + era_id, + block_payload: _, + block_context, + })) => { info!("Accusing everyone else!"); // We hook into the NewBlockPayload event to replace the block being proposed with // an empty one that accuses all the validators, except the malicious validator. @@ -2149,16 +2146,16 @@ async fn run_rewards_network_scenario( let rewarded_blocks = &blocks[rewarded_range]; let block_reward = (Ratio::::one() - fixture - .chainspec - .core_config - .finality_signature_proportion - .into_u512()) + .chainspec + .core_config + .finality_signature_proportion + .into_u512()) * recomputed_total_supply[&(i - 1)] * fixture - .chainspec - .core_config - .round_seigniorage_rate - .into_u512(); + .chainspec + .core_config + .round_seigniorage_rate + .into_u512(); let signatures_reward = fixture .chainspec .core_config @@ -2166,10 +2163,10 @@ async fn run_rewards_network_scenario( .into_u512() * recomputed_total_supply[&(i - 1)] * fixture - .chainspec - .core_config - .round_seigniorage_rate - .into_u512(); + .chainspec + .core_config + .round_seigniorage_rate + .into_u512(); let previous_signatures_reward = if switch_blocks.headers[i - 1].is_genesis() { None } else { @@ -2181,10 +2178,10 @@ async fn run_rewards_network_scenario( .into_u512() * recomputed_total_supply[&(i - 2)] * fixture - .chainspec - .core_config - .round_seigniorage_rate - .into_u512(), + .chainspec + .core_config + .round_seigniorage_rate + .into_u512(), ) }; @@ -2332,8 +2329,8 @@ async fn run_rewards_network_scenario( .get(era) .expect("expected recalculated supply") - recomputed_total_supply - .get(&(era - 1)) - .expect("expected recalculated supply"), + .get(&(era - 1)) + .expect("expected recalculated supply"), "supply growth does not match rewards at era {}", era ) @@ -2362,7 +2359,7 @@ async fn run_reward_network_zug_all_finality_small_prime_five_eras() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2386,7 +2383,7 @@ async fn run_reward_network_zug_all_finality_small_prime_five_eras_no_lookback() ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2410,7 +2407,7 @@ async fn run_reward_network_zug_no_finality_small_nominal_five_eras() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2434,7 +2431,7 @@ async fn run_reward_network_zug_half_finality_half_finders_small_nominal_five_er ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2458,7 +2455,7 @@ async fn run_reward_network_zug_half_finality_half_finders_small_nominal_five_er ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2482,7 +2479,7 @@ async fn run_reward_network_zug_all_finality_half_finders_small_nominal_five_era ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2508,7 +2505,7 @@ async fn run_reward_network_zug_all_finality_half_finders() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2534,7 +2531,7 @@ async fn run_reward_network_zug_all_finality_half_finders_five_eras() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2560,7 +2557,7 @@ async fn run_reward_network_zug_all_finality_zero_finders() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2586,7 +2583,7 @@ async fn run_reward_network_highway_all_finality_zero_finders() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] @@ -2612,7 +2609,7 @@ async fn run_reward_network_highway_no_finality() { ..Default::default() }, ) - .await; + .await; } #[tokio::test] From b161b458e5723be490ab486a04573d7b4fd23b8a Mon Sep 17 00:00:00 2001 From: Karan Dhareshwar Date: Thu, 28 Mar 2024 14:48:58 -0500 Subject: [PATCH 60/70] Appease linter --- node/src/components/storage.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/src/components/storage.rs b/node/src/components/storage.rs index 0dd90e58e9..1f480ee6b1 100644 --- a/node/src/components/storage.rs +++ b/node/src/components/storage.rs @@ -1006,7 +1006,7 @@ impl Storage { StorageRequest::GetBlockUtilizationScore { era_id, block_height, - switch_block_utilization: switch_block_utilization, + switch_block_utilization, responder, } => { let utilization = self.get_block_utilization_score( From 05becbff63a13de828dce88f985d07957d81bafd Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Thu, 28 Mar 2024 18:26:03 -0700 Subject: [PATCH 61/70] eliminating unnecessary leftover types & logic --- .../src/engine_state/execution_result.rs | 534 ------------------ execution_engine/src/engine_state/mod.rs | 7 +- execution_engine/src/engine_state/wasm_v1.rs | 54 +- execution_engine/src/execution/executor.rs | 43 +- 4 files changed, 47 insertions(+), 591 deletions(-) delete mode 100644 execution_engine/src/engine_state/execution_result.rs diff --git a/execution_engine/src/engine_state/execution_result.rs b/execution_engine/src/engine_state/execution_result.rs deleted file mode 100644 index cbc6bd5111..0000000000 --- a/execution_engine/src/engine_state/execution_result.rs +++ /dev/null @@ -1,534 +0,0 @@ -//! Outcome of an `ExecutionRequest`. - -use std::collections::VecDeque; - -use tracing::{debug, trace}; - -use casper_storage::data_access_layer::BiddingResult; -use casper_types::{ - contract_messages::Messages, - execution::{Effects, TransformKindV2, TransformV2}, - CLValue, Gas, Key, Motes, StoredValue, Transfer, -}; - -use super::Error; -use crate::execution::ExecError; - -/// Represents the result of an execution. -#[derive(Clone, Debug)] -pub enum ExecutionResult { - /// An error condition that happened during execution - Failure { - /// Error causing this `Failure` variant. - error: Error, - /// List of transfers that happened during execution up to the point of the failure. - transfers: Vec, - /// Gas consumed up to the point of the failure. - gas: Gas, - /// Execution effects. - effects: Effects, - /// Messages emitted during execution. - messages: Messages, - }, - /// Execution was finished successfully - Success { - /// List of transfers. - transfers: Vec, - /// Gas consumed. - gas: Gas, - /// Execution effects. - effects: Effects, - /// Messages emitted during execution. - messages: Messages, - }, -} - -impl ExecutionResult { - /// Constructs [ExecutionResult::Failure] that has 0 cost and no effects. - /// This is the case for failures that we can't (or don't want to) charge - /// for, like `PreprocessingError` or `InvalidNonce`. - pub fn precondition_failure(error: Error) -> ExecutionResult { - ExecutionResult::Failure { - error, - transfers: Vec::default(), - gas: Gas::zero(), - effects: Effects::new(), - messages: Vec::default(), - } - } - - /// Returns `true` if this is a successful variant. - pub fn is_success(&self) -> bool { - match self { - ExecutionResult::Failure { .. } => false, - ExecutionResult::Success { .. } => true, - } - } - - /// Returns `true` if this is a failure variant. - pub fn is_failure(&self) -> bool { - match self { - ExecutionResult::Failure { .. } => true, - ExecutionResult::Success { .. } => false, - } - } - - /// Returns `true` if this is a precondition failure. - /// - /// Precondition variant is further described as an execution failure which does not have any - /// effects, and has a gas cost of 0. - pub fn has_precondition_failure(&self) -> bool { - match self { - ExecutionResult::Failure { gas, effects, .. } => { - *gas == Gas::zero() && effects.is_empty() - } - ExecutionResult::Success { .. } => false, - } - } - - /// Returns gas used during execution regardless of variant. - pub fn gas(&self) -> Gas { - match self { - ExecutionResult::Failure { gas, .. } | ExecutionResult::Success { gas, .. } => *gas, - } - } - - /// Returns list of transfers regardless of variant. - pub fn transfers(&self) -> &Vec { - match self { - ExecutionResult::Failure { transfers, .. } => transfers, - ExecutionResult::Success { transfers, .. } => transfers, - } - } - - /// The ordered execution effects regardless of variant. - pub fn effects(&self) -> &Effects { - match self { - ExecutionResult::Failure { effects, .. } | ExecutionResult::Success { effects, .. } => { - effects - } - } - } - - /// Returns a new execution result with updated gas. - /// - /// This method preserves the [`ExecutionResult`] variant and updates the gas field only. - pub fn with_gas(self, gas: Gas) -> Self { - match self { - ExecutionResult::Failure { - error, - transfers, - effects, - messages, - .. - } => ExecutionResult::Failure { - error, - transfers, - gas, - effects, - messages, - }, - ExecutionResult::Success { - transfers, - effects, - messages, - .. - } => ExecutionResult::Success { - transfers, - gas, - effects, - messages, - }, - } - } - - /// Returns a new execution result with updated transfers field. - /// - /// This method preserves the [`ExecutionResult`] variant and updates the - /// `transfers` field only. - pub fn with_transfers(self, transfers: Vec) -> Self { - match self { - ExecutionResult::Failure { - error, - gas, - effects, - messages, - .. - } => ExecutionResult::Failure { - error, - transfers, - gas, - effects, - messages, - }, - ExecutionResult::Success { - gas, - effects, - messages, - .. - } => ExecutionResult::Success { - transfers, - gas, - effects, - messages, - }, - } - } - - /// Returns a new execution result with updated execution effects. - /// - /// This method preserves the [`ExecutionResult`] variant and updates the - /// `effects` field only. - pub fn with_effects(self, effects: Effects) -> Self { - match self { - ExecutionResult::Failure { - error, - transfers, - gas, - effects: _, - messages, - } => ExecutionResult::Failure { - error, - transfers, - gas, - effects, - messages, - }, - ExecutionResult::Success { - transfers, - gas, - effects: _, - messages, - } => ExecutionResult::Success { - transfers, - gas, - effects, - messages, - }, - } - } - - /// Returns error value, if possible. - /// - /// Returns a reference to a wrapped [`Error`] instance if the object is a failure - /// variant. - pub fn as_error(&self) -> Option<&Error> { - match self { - ExecutionResult::Failure { error, .. } => Some(error), - ExecutionResult::Success { .. } => None, - } - } - - /// Consumes [`ExecutionResult`] instance and optionally returns [`Error`] instance for - /// [`ExecutionResult::Failure`] variant. - pub fn take_error(self) -> Option { - match self { - ExecutionResult::Failure { error, .. } => Some(error), - ExecutionResult::Success { .. } => None, - } - } - - /// Checks the transfer status of a payment code. - /// - /// This method converts the gas cost of the execution result into motes using supplied - /// `gas_price`, and then a check is made to ensure that user deposited enough funds in the - /// payment purse (in motes) to cover the execution of a payment code. - /// - /// Returns `None` if user deposited enough funds in payment purse and the execution result was - /// a success variant, otherwise a wrapped [`ForcedTransferResult`] that indicates an error - /// condition. - pub fn check_forced_transfer( - &self, - payment_purse_balance: Motes, - gas_price: u8, - ) -> Option { - let payment_result_cost = match Motes::from_gas(self.gas(), gas_price) { - Some(cost) => cost, - None => return Some(ForcedTransferResult::GasConversionOverflow), - }; - // payment_code_spec_3_b_ii: if (balance of handle payment pay purse) < (gas spent during - // payment code execution) * gas_price, no session - let insufficient_balance_to_continue = payment_purse_balance < payment_result_cost; - - match self { - ExecutionResult::Success { .. } if insufficient_balance_to_continue => { - // payment_code_spec_4: insufficient payment - Some(ForcedTransferResult::InsufficientPayment) - } - ExecutionResult::Success { .. } => { - // payment_code_spec_3_b_ii: continue execution - None - } - ExecutionResult::Failure { .. } => { - // payment_code_spec_3_a: report payment error in the deploy response - Some(ForcedTransferResult::PaymentFailure) - } - } - } - - /// Creates a new payment code error. - /// - /// The method below creates an [`ExecutionResult`] with precomputed effects of a - /// "finalize_payment". - /// - /// The effects that are produced as part of this process would subract `max_payment_cost` from - /// account's main purse, and add `max_payment_cost` to proposer account's balance. - pub fn new_payment_code_error( - error: Error, - max_payment_cost: Motes, - account_main_purse_balance: Motes, - gas: Gas, - account_main_purse_balance_key: Key, - proposer_main_purse_balance_key: Key, - ) -> Result { - let new_balance = account_main_purse_balance - .checked_sub(max_payment_cost) - .ok_or(Error::InsufficientPayment)?; - let new_balance_value = - StoredValue::CLValue(CLValue::from_t(new_balance.value()).map_err(ExecError::from)?); - let mut effects = Effects::new(); - effects.push(TransformV2::new( - account_main_purse_balance_key.normalize(), - TransformKindV2::Write(new_balance_value), - )); - effects.push(TransformV2::new( - proposer_main_purse_balance_key.normalize(), - TransformKindV2::AddUInt512(max_payment_cost.value()), - )); - let transfers = Vec::default(); - Ok(ExecutionResult::Failure { - error, - effects, - transfers, - gas, - messages: Vec::default(), - }) - } - - /// Converts a bidding result to an execution result. - pub fn from_bidding_result(bidding_result: BiddingResult, gas: Gas) -> Option { - match bidding_result { - BiddingResult::RootNotFound => None, - BiddingResult::Success { effects, .. } => Some(ExecutionResult::Success { - transfers: vec![], - gas, - effects, - messages: Messages::default(), - }), - BiddingResult::Failure(te) => { - Some(ExecutionResult::Failure { - error: Error::TrackingCopy(te), - transfers: vec![], - gas, - effects: Effects::default(), // currently not returning effects on failure - messages: Messages::default(), - }) - } - } - } - - /// Logs execution results. - pub fn log_execution_result(&self, preamble: &'static str) { - trace!("{}: {:?}", preamble, self); - match self { - ExecutionResult::Success { - transfers, - gas, - effects, - messages, - } => { - debug!( - %gas, - transfer_count = %transfers.len(), - transforms_count = %effects.len(), - messages_count = %messages.len(), - "{}: execution success", - preamble - ); - } - ExecutionResult::Failure { - error, - transfers, - gas, - effects, - messages, - } => { - debug!( - %error, - %gas, - transfer_count = %transfers.len(), - transforms_count = %effects.len(), - messages_count = %messages.len(), - "{}: execution failure", - preamble - ); - } - } - } -} - -/// A type alias that represents multiple execution results. -pub type ExecutionResults = VecDeque; - -/// Indicates the outcome of a transfer payment check. -pub enum ForcedTransferResult { - /// Payment code ran out of gas during execution - InsufficientPayment, - /// Gas conversion overflow - GasConversionOverflow, - /// Payment code execution resulted in an error - PaymentFailure, -} - -/// Represents error conditions of an execution result builder. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum ExecutionResultBuilderError { - /// Missing a payment execution result. - MissingPaymentExecutionResult, - /// Missing a session execution result. - MissingSessionExecutionResult, - /// Missing a finalize execution result. - MissingFinalizeExecutionResult, -} - -/// Builder object that will construct a final [`ExecutionResult`] given payment, session and -/// finalize [`ExecutionResult`]s. -#[derive(Default)] -pub struct ExecutionResultBuilder { - payment_execution_result: Option, - session_execution_result: Option, - finalize_execution_result: Option, -} - -impl ExecutionResultBuilder { - /// Creates new execution result builder. - pub fn new() -> ExecutionResultBuilder { - ExecutionResultBuilder::default() - } - - /// Sets a payment execution result. - pub fn set_payment_execution_result(&mut self, payment_result: ExecutionResult) -> &mut Self { - self.payment_execution_result = Some(payment_result); - self - } - - /// Sets a session execution result. - pub fn set_session_execution_result( - &mut self, - session_execution_result: ExecutionResult, - ) -> &mut ExecutionResultBuilder { - self.session_execution_result = Some(session_execution_result); - self - } - - /// Sets a finalize execution result. - pub fn set_finalize_execution_result( - &mut self, - finalize_execution_result: ExecutionResult, - ) -> &mut ExecutionResultBuilder { - self.finalize_execution_result = Some(finalize_execution_result); - self - } - - /// Calculates the total gas cost of the execution result. - /// - /// Takes a payment execution result, and a session execution result and returns a sum. If - /// either a payment or session code is not specified then a 0 is used. - pub fn gas_used(&self) -> Gas { - let payment_gas = self - .payment_execution_result - .as_ref() - .map(ExecutionResult::gas) - .unwrap_or_default(); - let session_gas = self - .session_execution_result - .as_ref() - .map(ExecutionResult::gas) - .unwrap_or_default(); - // TODO: Make sure this code isn't in production, as, even though it's highly unlikely - // to happen, an integer overflow would be silently ignored in release builds. - // NOTE: This code should have been removed in the fix of #1968, where arithmetic - // operations on the Gas type were disabled. - payment_gas + session_gas - } - - /// Returns transfers from a session's execution result. - /// - /// If the session's execution result is not supplied then an empty [`Vec`] is returned. - pub fn transfers(&self) -> Vec { - self.session_execution_result - .as_ref() - .map(ExecutionResult::transfers) - .cloned() - .unwrap_or_default() - } - - /// Builds a final [`ExecutionResult`] based on session result, payment result and a - /// finalization result. - pub fn build(self) -> Result { - let mut error: Option = None; - let mut transfers = self.transfers(); - let gas = self.gas_used(); - - let (mut all_effects, mut all_messages) = match self.payment_execution_result { - Some(result @ ExecutionResult::Failure { .. }) => return Ok(result), - Some(ExecutionResult::Success { - effects, messages, .. - }) => (effects, messages), - None => return Err(ExecutionResultBuilderError::MissingPaymentExecutionResult), - }; - - // session_code_spec_3: only include session exec effects if there is no session - // exec error - match self.session_execution_result { - Some(ExecutionResult::Failure { - error: session_error, - transfers: session_transfers, - effects: _, - gas: _, - messages, - }) => { - error = Some(session_error); - transfers = session_transfers; - all_messages.extend(messages); - } - Some(ExecutionResult::Success { - effects, messages, .. - }) => { - all_effects.append(effects); - all_messages.extend(messages); - } - None => return Err(ExecutionResultBuilderError::MissingSessionExecutionResult), - }; - - match self.finalize_execution_result { - Some(ExecutionResult::Failure { .. }) => { - // payment_code_spec_5_a: Finalization Error should only ever be raised here - return Ok(ExecutionResult::precondition_failure(Error::Finalization)); - } - Some(ExecutionResult::Success { - effects, messages, .. - }) => { - all_effects.append(effects); - all_messages.extend(messages); - } - None => return Err(ExecutionResultBuilderError::MissingFinalizeExecutionResult), - } - - match error { - None => Ok(ExecutionResult::Success { - transfers, - gas, - effects: all_effects, - messages: all_messages, - }), - Some(error) => Ok(ExecutionResult::Failure { - error, - transfers, - gas, - effects: all_effects, - messages: all_messages, - }), - } - } -} diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index b09938807c..fb7a0bec2a 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -3,7 +3,6 @@ pub mod deploy_item; pub mod engine_config; mod error; pub(crate) mod execution_kind; -pub mod execution_result; mod wasm_v1; use std::{cell::RefCell, rc::Rc}; @@ -24,7 +23,6 @@ pub use engine_config::{ }; pub use error::Error; use execution_kind::ExecutionKind; -pub use execution_result::{ExecutionResult, ForcedTransferResult}; pub use wasm_v1::{ExecutableItem, InvalidRequest, WasmV1Request, WasmV1Result}; /// The maximum amount of motes that payment code execution can cost. @@ -126,7 +124,7 @@ impl ExecutionEngineV1 { Err(ese) => return WasmV1Result::precondition_failure(gas_limit, ese), }; let access_rights = entity.extract_access_rights(entity_hash, &named_keys); - let execution_result = Executor::new(self.config().clone()).exec( + Executor::new(self.config().clone()).exec( execution_kind, args, entity_hash, @@ -145,7 +143,6 @@ impl ExecutionEngineV1 { account_hash, self.config.max_runtime_call_stack_height() as usize, ), - ); - WasmV1Result::from_execution_result(gas_limit, execution_result) + ) } } diff --git a/execution_engine/src/engine_state/wasm_v1.rs b/execution_engine/src/engine_state/wasm_v1.rs index 4766c4873d..c0e7d43805 100644 --- a/execution_engine/src/engine_state/wasm_v1.rs +++ b/execution_engine/src/engine_state/wasm_v1.rs @@ -12,7 +12,7 @@ use casper_types::{ TransactionV1, Transfer, U512, }; -use crate::engine_state::{DeployItem, Error as EngineError, ExecutionResult}; +use crate::engine_state::{DeployItem, Error as EngineError}; const DEFAULT_ENTRY_POINT: &str = "call"; @@ -230,6 +230,25 @@ pub struct WasmV1Result { } impl WasmV1Result { + /// Creates a new instance. + pub fn new( + limit: Gas, + consumed: Gas, + effects: Effects, + transfers: Vec, + messages: Messages, + error: Option, + ) -> Self { + WasmV1Result { + limit, + consumed, + effects, + transfers, + messages, + error, + } + } + /// Error, if any. pub fn error(&self) -> Option<&EngineError> { self.error.as_ref() @@ -304,39 +323,6 @@ impl WasmV1Result { self.error.is_some() && self.consumed == Gas::zero() && self.effects.is_empty() } - /// From an execution result. - pub fn from_execution_result(gas_limit: Gas, execution_result: ExecutionResult) -> Self { - match execution_result { - ExecutionResult::Failure { - error, - transfers, - gas, - effects, - messages, - } => WasmV1Result { - error: Some(error), - transfers, - effects, - messages, - limit: gas_limit, - consumed: gas, - }, - ExecutionResult::Success { - transfers, - gas, - effects, - messages, - } => WasmV1Result { - transfers, - effects, - messages, - limit: gas_limit, - consumed: gas, - error: None, - }, - } - } - /// Converts a transfer result to an execution result. pub fn from_transfer_result(transfer_result: TransferResult, consumed: Gas) -> Option { // NOTE: for native / wasmless operations limit and consumed are always equal, and diff --git a/execution_engine/src/execution/executor.rs b/execution_engine/src/execution/executor.rs index d59ab3bc49..846732760b 100644 --- a/execution_engine/src/execution/executor.rs +++ b/execution_engine/src/execution/executor.rs @@ -5,14 +5,16 @@ use casper_storage::{ tracking_copy::TrackingCopy, AddressGenerator, }; +use casper_types::execution::Effects; use casper_types::{ account::AccountHash, addressable_entity::NamedKeys, AddressableEntity, AddressableEntityHash, BlockTime, ContextAccessRights, EntryPointType, Gas, Key, Phase, ProtocolVersion, RuntimeArgs, StoredValue, Tagged, TransactionHash, U512, }; +use crate::engine_state::WasmV1Result; use crate::{ - engine_state::{execution_kind::ExecutionKind, EngineConfig, ExecutionResult}, + engine_state::{execution_kind::ExecutionKind, EngineConfig}, execution::ExecError, runtime::{Runtime, RuntimeStack}, runtime_context::{CallingAddContractVersion, RuntimeContext}, @@ -59,14 +61,21 @@ impl Executor { tracking_copy: Rc>>, phase: Phase, stack: RuntimeStack, - ) -> ExecutionResult + ) -> WasmV1Result where R: StateReader, { let spending_limit: U512 = match try_get_amount(&args) { Ok(spending_limit) => spending_limit, Err(error) => { - return ExecutionResult::precondition_failure(error.into()); + return WasmV1Result::new( + gas_limit, + Gas::zero(), + Effects::default(), + Vec::default(), + Vec::default(), + Some(error.into()), + ); } }; @@ -128,21 +137,19 @@ impl Executor { } }; - match result { - Ok(_) => ExecutionResult::Success { - effects: runtime.context().effects(), - transfers: runtime.context().transfers().to_owned(), - gas: runtime.context().gas_counter(), - messages: runtime.context().messages(), - }, - Err(error) => ExecutionResult::Failure { - error: error.into(), - effects: runtime.context().effects(), - transfers: runtime.context().transfers().to_owned(), - gas: runtime.context().gas_counter(), - messages: runtime.context().messages(), - }, - } + let err = match result { + Ok(_) => None, + Err(error) => Some(error.into()), + }; + + return WasmV1Result::new( + gas_limit, + runtime.context().gas_counter(), + runtime.context().effects(), + runtime.context().transfers().to_owned(), + runtime.context().messages(), + err, + ); } /// Creates new runtime context. From 1c53766b0370f0e7a357b380636608dfb69f2fdc Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Mon, 1 Apr 2024 02:11:43 -0700 Subject: [PATCH 62/70] restoring entry_point to payment execution --- .../src/engine_state/execution_kind.rs | 19 +- execution_engine/src/engine_state/mod.rs | 2 +- execution_engine/src/engine_state/wasm_v1.rs | 340 +++++++++++------- execution_engine/src/execution/executor.rs | 10 +- .../test_support/src/chainspec_config.rs | 24 +- .../src/execute_request_builder.rs | 53 +-- .../test_support/src/wasm_test_builder.rs | 41 ++- .../src/test/contract_api/get_call_stack.rs | 25 +- .../tests/src/test/contract_api/transfer.rs | 128 +++++-- .../src/test/deploy/non_standard_payment.rs | 60 +++- .../tests/src/test/deploy/stored_contracts.rs | 2 +- .../tests/src/test/explorer/faucet.rs | 8 +- .../src/test/explorer/faucet_test_helpers.rs | 24 +- .../tests/src/test/get_balance.rs | 12 +- .../tests/src/test/regression/ee_966.rs | 4 +- ...host_function_metrics_size_and_gas_cost.rs | 2 +- .../test/regression/regression_20210707.rs | 2 +- .../components/transaction_acceptor/tests.rs | 2 +- resources/test/sse_data_schema.json | 6 +- storage/src/data_access_layer/balance.rs | 8 + types/src/transaction/deploy/deploy_header.rs | 2 +- types/src/transaction/pricing_mode.rs | 16 +- types/src/transaction/transaction_v1.rs | 4 +- .../transaction_v1/transaction_v1_header.rs | 5 +- 24 files changed, 488 insertions(+), 311 deletions(-) diff --git a/execution_engine/src/engine_state/execution_kind.rs b/execution_engine/src/engine_state/execution_kind.rs index 06062663a9..a37f241f50 100644 --- a/execution_engine/src/engine_state/execution_kind.rs +++ b/execution_engine/src/engine_state/execution_kind.rs @@ -49,36 +49,31 @@ impl<'a> ExecutionKind<'a> { R: StateReader, { match executable_item { - ExecutableItem::Stored(target) => Self::new_stored( + ExecutableItem::Invocation(target) => Self::new_stored( tracking_copy, named_keys, target, entry_point, protocol_version, ), - ExecutableItem::CustomPayment(module_bytes) - | ExecutableItem::SessionModuleBytes { + ExecutableItem::PaymentBytes(module_bytes) + | ExecutableItem::SessionBytes { kind: TransactionSessionKind::Standard, module_bytes, } => Ok(ExecutionKind::Standard(module_bytes)), - ExecutableItem::SessionModuleBytes { + ExecutableItem::SessionBytes { kind: TransactionSessionKind::Installer, module_bytes, } => Ok(ExecutionKind::Installer(module_bytes)), - ExecutableItem::SessionModuleBytes { + ExecutableItem::SessionBytes { kind: TransactionSessionKind::Upgrader, module_bytes, } => Ok(ExecutionKind::Upgrader(module_bytes)), - ExecutableItem::SessionModuleBytes { + ExecutableItem::SessionBytes { kind: TransactionSessionKind::Isolated, module_bytes, } => Ok(ExecutionKind::Isolated(module_bytes)), - ExecutableItem::DeploySessionModuleBytes(module_bytes) => { - Ok(ExecutionKind::Deploy(module_bytes)) - } - ExecutableItem::StandardPayment => Err(Error::Deprecated( - "standard payment is no longer handled by the execution engine".to_string(), - )), + ExecutableItem::LegacyDeploy(module_bytes) => Ok(ExecutionKind::Deploy(module_bytes)), } } diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index fb7a0bec2a..4dd5d69608 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -69,6 +69,7 @@ impl ExecutionEngineV1 { entry_point, args, authorization_keys, + phase, }: WasmV1Request, ) -> WasmV1Result { // NOTE to core engineers: it is intended for the EE to ONLY execute wasm targeting the @@ -112,7 +113,6 @@ impl ExecutionEngineV1 { return WasmV1Result::precondition_failure(gas_limit, Error::TrackingCopy(tce)) } }; - let phase = executable_item.phase(); let execution_kind = match ExecutionKind::new( &mut *tc.borrow_mut(), &named_keys, diff --git a/execution_engine/src/engine_state/wasm_v1.rs b/execution_engine/src/engine_state/wasm_v1.rs index c0e7d43805..a98f24dbcc 100644 --- a/execution_engine/src/engine_state/wasm_v1.rs +++ b/execution_engine/src/engine_state/wasm_v1.rs @@ -37,39 +37,26 @@ pub enum InvalidRequest { } /// The item to be executed. -#[derive(Debug)] -pub enum ExecutableItem<'a> { - /// A stored entity or package. - Stored(TransactionInvocationTarget), - /// Compiled Wasm from a transaction >= V1 as byte code. - SessionModuleBytes { +#[derive(Debug, Clone)] +pub enum ExecutableItem { + /// Legacy deploy byte code. + LegacyDeploy(Bytes), + /// Payment byte code. + PaymentBytes(Bytes), + /// Session byte code. + SessionBytes { /// The kind of session. kind: TransactionSessionKind, /// The compiled Wasm. - module_bytes: &'a Bytes, + module_bytes: Bytes, }, - /// Compiled Wasm from a deploy as byte code. - DeploySessionModuleBytes(&'a Bytes), - /// Module bytes to be used as custom payment. - CustomPayment(&'a Bytes), - /// Standard payment. - StandardPayment, -} - -impl<'a> ExecutableItem<'a> { - pub(super) fn phase(&self) -> Phase { - match self { - ExecutableItem::Stored(_) - | ExecutableItem::SessionModuleBytes { .. } - | ExecutableItem::DeploySessionModuleBytes(_) => Phase::Session, - ExecutableItem::CustomPayment(_) | ExecutableItem::StandardPayment => Phase::Payment, - } - } + /// An attempt to invoke a stored entity or package. + Invocation(TransactionInvocationTarget), } /// A request to execute the given Wasm on the V1 runtime. #[derive(Debug)] -pub struct WasmV1Request<'a> { +pub struct WasmV1Request { /// State root hash of the global state in which the transaction will be executed. pub state_hash: Digest, /// Block time represented as a unix timestamp. @@ -81,45 +68,68 @@ pub struct WasmV1Request<'a> { /// The transaction's initiator. pub initiator_addr: InitiatorAddr, /// The executable item. - pub executable_item: ExecutableItem<'a>, + pub executable_item: ExecutableItem, /// The entry point to call when executing. pub entry_point: String, /// The runtime args. pub args: RuntimeArgs, /// The account hashes of the signers of the transaction. pub authorization_keys: BTreeSet, + /// Execution phase. + pub phase: Phase, } -impl<'a> WasmV1Request<'a> { +impl WasmV1Request { + pub(crate) fn new_from_executable_info( + state_hash: Digest, + block_time: BlockTime, + gas_limit: Gas, + transaction_hash: TransactionHash, + initiator_addr: InitiatorAddr, + authorization_keys: BTreeSet, + executable_info: impl Executable, + ) -> Self { + let executable_item = executable_info.item(); + Self { + state_hash, + block_time, + transaction_hash, + gas_limit, + initiator_addr, + authorization_keys, + executable_item, + entry_point: executable_info.entry_point().clone(), + args: executable_info.args().clone(), + phase: executable_info.phase(), + } + } + /// Creates a new request from a transaction for use as the session code. pub fn new_session( state_hash: Digest, block_time: BlockTime, gas_limit: Gas, - txn: &'a Transaction, + transaction: &Transaction, ) -> Result { - let transaction_hash = txn.hash(); - let initiator_addr = txn.initiator_addr(); - let authorization_keys = txn.signers(); - - let session_info = match txn { + let info = match transaction { Transaction::Deploy(deploy) => { SessionInfo::try_from((deploy.session(), deploy.hash()))? } Transaction::V1(v1_txn) => SessionInfo::try_from(v1_txn)?, }; - Ok(Self { + let transaction_hash = transaction.hash(); + let initiator_addr = transaction.initiator_addr(); + let authorization_keys = transaction.signers(); + Ok(WasmV1Request::new_from_executable_info( state_hash, block_time, - transaction_hash, gas_limit, + transaction_hash, initiator_addr, - executable_item: session_info.session, - entry_point: session_info.entry_point, - args: session_info.args, authorization_keys, - }) + info, + )) } /// Creates a new request from a transaction for use as custom payment. @@ -127,35 +137,30 @@ impl<'a> WasmV1Request<'a> { state_hash: Digest, block_time: BlockTime, gas_limit: Gas, - txn: &'a Transaction, + transaction: &Transaction, ) -> Result { - let transaction_hash = txn.hash(); - let initiator_addr = txn.initiator_addr(); - let authorization_keys = txn.signers(); - - let payment_info = match txn { + let info = match transaction { Transaction::Deploy(deploy) => { PaymentInfo::try_from((deploy.payment(), deploy.hash()))? } Transaction::V1(v1_txn) => PaymentInfo::try_from(v1_txn)?, }; - Ok(Self { + let transaction_hash = transaction.hash(); + let initiator_addr = transaction.initiator_addr(); + let authorization_keys = transaction.signers(); + Ok(WasmV1Request::new_from_executable_info( state_hash, block_time, - transaction_hash, gas_limit, + transaction_hash, initiator_addr, - executable_item: payment_info.payment, - entry_point: DEFAULT_ENTRY_POINT.to_string(), - args: payment_info.args, authorization_keys, - }) + info, + )) } /// Creates a new request from a deploy item for use as the session code. - // - // TODO - deprecate? pub fn new_session_from_deploy_item( state_hash: Digest, block_time: BlockTime, @@ -166,25 +171,24 @@ impl<'a> WasmV1Request<'a> { ref authorization_keys, ref deploy_hash, .. - }: &'a DeployItem, + }: &DeployItem, ) -> Result { - let session_info = SessionInfo::try_from((session, deploy_hash))?; - Ok(Self { + let info = SessionInfo::try_from((session, deploy_hash))?; + let transaction_hash = TransactionHash::Deploy(*deploy_hash); + let initiator_addr = InitiatorAddr::AccountHash(*address); + let authorization_keys = authorization_keys.clone(); + Ok(WasmV1Request::new_from_executable_info( state_hash, block_time, - transaction_hash: TransactionHash::Deploy(*deploy_hash), gas_limit, - initiator_addr: InitiatorAddr::AccountHash(*address), - executable_item: session_info.session, - entry_point: session_info.entry_point, - args: session_info.args, - authorization_keys: authorization_keys.clone(), - }) + transaction_hash, + initiator_addr, + authorization_keys, + info, + )) } /// Creates a new request from a deploy item for use as custom payment. - // - // TODO - deprecate? pub fn new_custom_payment_from_deploy_item( state_hash: Digest, block_time: BlockTime, @@ -195,20 +199,21 @@ impl<'a> WasmV1Request<'a> { ref authorization_keys, ref deploy_hash, .. - }: &'a DeployItem, + }: &DeployItem, ) -> Result { - let payment_info = PaymentInfo::try_from((payment, deploy_hash))?; - Ok(Self { + let info = PaymentInfo::try_from((payment, deploy_hash))?; + let transaction_hash = TransactionHash::Deploy(*deploy_hash); + let initiator_addr = InitiatorAddr::AccountHash(*address); + let authorization_keys = authorization_keys.clone(); + Ok(WasmV1Request::new_from_executable_info( state_hash, block_time, - transaction_hash: TransactionHash::Deploy(*deploy_hash), gas_limit, - initiator_addr: InitiatorAddr::AccountHash(*address), - executable_item: payment_info.payment, - entry_point: DEFAULT_ENTRY_POINT.to_string(), - args: payment_info.args, - authorization_keys: authorization_keys.clone(), - }) + transaction_hash, + initiator_addr, + authorization_keys, + info, + )) } } @@ -352,28 +357,54 @@ impl WasmV1Result { } } -/// Helper struct to carry the appropriate info for converting an `ExecutableDeployItem` or a -/// `TransactionV1` into the corresponding fields of a `WasmV1Request` for execution as session -/// code. -struct SessionInfo<'a> { - session: ExecutableItem<'a>, +/// Helper struct to carry item, entry_point, and arg info for a `WasmV1Request`. +struct ExecutableInfo { + item: ExecutableItem, entry_point: String, args: RuntimeArgs, } -impl<'a> TryFrom<(&'a ExecutableDeployItem, &'a DeployHash)> for SessionInfo<'a> { +pub(crate) trait Executable { + fn item(&self) -> ExecutableItem; + fn entry_point(&self) -> &String; + fn args(&self) -> &RuntimeArgs; + fn phase(&self) -> Phase; +} + +/// New type for hanging session specific impl's off of. +struct SessionInfo(ExecutableInfo); + +impl Executable for SessionInfo { + fn item(&self) -> ExecutableItem { + self.0.item.clone() + } + + fn entry_point(&self) -> &String { + &self.0.entry_point + } + + fn args(&self) -> &RuntimeArgs { + &self.0.args + } + + fn phase(&self) -> Phase { + Phase::Session + } +} + +impl TryFrom<(&ExecutableDeployItem, &DeployHash)> for SessionInfo { type Error = InvalidRequest; fn try_from( - (session_item, deploy_hash): (&'a ExecutableDeployItem, &'a DeployHash), + (session_item, deploy_hash): (&ExecutableDeployItem, &DeployHash), ) -> Result { let transaction_hash = TransactionHash::Deploy(*deploy_hash); - let session: ExecutableItem<'a>; + let session: ExecutableItem; let session_entry_point: String; let session_args: RuntimeArgs; match session_item { ExecutableDeployItem::ModuleBytes { module_bytes, args } => { - session = ExecutableItem::DeploySessionModuleBytes(module_bytes); + session = ExecutableItem::LegacyDeploy(module_bytes.clone()); session_entry_point = DEFAULT_ENTRY_POINT.to_string(); session_args = args.clone(); } @@ -382,7 +413,7 @@ impl<'a> TryFrom<(&'a ExecutableDeployItem, &'a DeployHash)> for SessionInfo<'a> entry_point, args, } => { - session = ExecutableItem::Stored( + session = ExecutableItem::Invocation( TransactionInvocationTarget::new_invocable_entity(*hash), ); session_entry_point = entry_point.clone(); @@ -393,7 +424,7 @@ impl<'a> TryFrom<(&'a ExecutableDeployItem, &'a DeployHash)> for SessionInfo<'a> entry_point, args, } => { - session = ExecutableItem::Stored( + session = ExecutableItem::Invocation( TransactionInvocationTarget::new_invocable_entity_alias(name.clone()), ); session_entry_point = entry_point.clone(); @@ -405,7 +436,7 @@ impl<'a> TryFrom<(&'a ExecutableDeployItem, &'a DeployHash)> for SessionInfo<'a> entry_point, args, } => { - session = ExecutableItem::Stored(TransactionInvocationTarget::new_package( + session = ExecutableItem::Invocation(TransactionInvocationTarget::new_package( *hash, *version, )); session_entry_point = entry_point.clone(); @@ -417,10 +448,9 @@ impl<'a> TryFrom<(&'a ExecutableDeployItem, &'a DeployHash)> for SessionInfo<'a> entry_point, args, } => { - session = ExecutableItem::Stored(TransactionInvocationTarget::new_package_alias( - name.clone(), - *version, - )); + session = ExecutableItem::Invocation( + TransactionInvocationTarget::new_package_alias(name.clone(), *version), + ); session_entry_point = entry_point.clone(); session_args = args.clone(); } @@ -432,18 +462,18 @@ impl<'a> TryFrom<(&'a ExecutableDeployItem, &'a DeployHash)> for SessionInfo<'a> } } - Ok(SessionInfo { - session, + Ok(SessionInfo(ExecutableInfo { + item: session, entry_point: session_entry_point, args: session_args, - }) + })) } } -impl<'a> TryFrom<&'a TransactionV1> for SessionInfo<'a> { +impl TryFrom<&TransactionV1> for SessionInfo { type Error = InvalidRequest; - fn try_from(v1_txn: &'a TransactionV1) -> Result { + fn try_from(v1_txn: &TransactionV1) -> Result { let transaction_hash = TransactionHash::V1(*v1_txn.hash()); let args = v1_txn.args().clone(); let session = match v1_txn.target() { @@ -453,12 +483,12 @@ impl<'a> TryFrom<&'a TransactionV1> for SessionInfo<'a> { v1_txn.target().to_string(), )); } - TransactionTarget::Stored { id, .. } => ExecutableItem::Stored(id.clone()), + TransactionTarget::Stored { id, .. } => ExecutableItem::Invocation(id.clone()), TransactionTarget::Session { kind, module_bytes, .. - } => ExecutableItem::SessionModuleBytes { + } => ExecutableItem::SessionBytes { kind: *kind, - module_bytes, + module_bytes: module_bytes.clone(), }, }; @@ -466,75 +496,102 @@ impl<'a> TryFrom<&'a TransactionV1> for SessionInfo<'a> { return Err(InvalidRequest::InvalidEntryPoint(transaction_hash, v1_txn.entry_point().to_string())); }; - Ok(SessionInfo { - session, + Ok(SessionInfo(ExecutableInfo { + item: session, entry_point: entry_point.clone(), args, - }) + })) } } -/// Helper struct to carry the appropriate info for converting an `ExecutableDeployItem` or a -/// `TransactionV1` into the corresponding fields of a `WasmV1Request` for execution as custom -/// payment. -struct PaymentInfo<'a> { - payment: ExecutableItem<'a>, - args: RuntimeArgs, +/// New type for hanging payment specific impl's off of. +struct PaymentInfo(ExecutableInfo); + +impl Executable for PaymentInfo { + fn item(&self) -> ExecutableItem { + self.0.item.clone() + } + + fn entry_point(&self) -> &String { + &self.0.entry_point + } + + fn args(&self) -> &RuntimeArgs { + &self.0.args + } + + fn phase(&self) -> Phase { + Phase::Payment + } } -impl<'a> TryFrom<(&'a ExecutableDeployItem, &'a DeployHash)> for PaymentInfo<'a> { +impl TryFrom<(&ExecutableDeployItem, &DeployHash)> for PaymentInfo { type Error = InvalidRequest; fn try_from( - (payment_item, deploy_hash): (&'a ExecutableDeployItem, &'a DeployHash), + (payment_item, deploy_hash): (&ExecutableDeployItem, &DeployHash), ) -> Result { let transaction_hash = TransactionHash::Deploy(*deploy_hash); match payment_item { ExecutableDeployItem::ModuleBytes { module_bytes, args } => { - if module_bytes.is_empty() { - Ok(PaymentInfo { - payment: ExecutableItem::StandardPayment, - args: args.clone(), - }) + let payment = if module_bytes.is_empty() { + return Err(InvalidRequest::UnsupportedMode( + transaction_hash, + "standard payment is no longer handled by the execution engine".to_string(), + )); } else { - Ok(PaymentInfo { - payment: ExecutableItem::CustomPayment(module_bytes), - args: args.clone(), - }) - } + ExecutableItem::PaymentBytes(module_bytes.clone()) + }; + Ok(PaymentInfo(ExecutableInfo { + item: payment, + entry_point: DEFAULT_ENTRY_POINT.to_string(), + args: args.clone(), + })) } - ExecutableDeployItem::StoredContractByHash { hash, args, .. } => Ok(PaymentInfo { - payment: ExecutableItem::Stored(TransactionInvocationTarget::ByHash(hash.value())), + ExecutableDeployItem::StoredContractByHash { + hash, + args, + entry_point, + } => Ok(PaymentInfo(ExecutableInfo { + item: ExecutableItem::Invocation(TransactionInvocationTarget::ByHash(hash.value())), + entry_point: entry_point.clone(), args: args.clone(), - }), - ExecutableDeployItem::StoredContractByName { name, args, .. } => Ok(PaymentInfo { - payment: ExecutableItem::Stored(TransactionInvocationTarget::ByName(name.clone())), + })), + ExecutableDeployItem::StoredContractByName { + name, + args, + entry_point, + } => Ok(PaymentInfo(ExecutableInfo { + item: ExecutableItem::Invocation(TransactionInvocationTarget::ByName(name.clone())), + entry_point: entry_point.clone(), args: args.clone(), - }), + })), ExecutableDeployItem::StoredVersionedContractByHash { args, hash, version, - .. - } => Ok(PaymentInfo { - payment: ExecutableItem::Stored(TransactionInvocationTarget::ByPackageHash { + entry_point, + } => Ok(PaymentInfo(ExecutableInfo { + item: ExecutableItem::Invocation(TransactionInvocationTarget::ByPackageHash { addr: hash.value(), version: *version, }), + entry_point: entry_point.clone(), args: args.clone(), - }), + })), ExecutableDeployItem::StoredVersionedContractByName { name, version, args, - .. - } => Ok(PaymentInfo { - payment: ExecutableItem::Stored(TransactionInvocationTarget::ByPackageName { + entry_point, + } => Ok(PaymentInfo(ExecutableInfo { + item: ExecutableItem::Invocation(TransactionInvocationTarget::ByPackageName { name: name.clone(), version: *version, }), + entry_point: entry_point.clone(), args: args.clone(), - }), + })), ExecutableDeployItem::Transfer { .. } => Err(InvalidRequest::UnexpectedVariant( transaction_hash, "payment item".to_string(), @@ -543,10 +600,10 @@ impl<'a> TryFrom<(&'a ExecutableDeployItem, &'a DeployHash)> for PaymentInfo<'a> } } -impl<'a> TryFrom<&'a TransactionV1> for PaymentInfo<'a> { +impl TryFrom<&TransactionV1> for PaymentInfo { type Error = InvalidRequest; - fn try_from(v1_txn: &'a TransactionV1) -> Result { + fn try_from(v1_txn: &TransactionV1) -> Result { let transaction_hash = TransactionHash::V1(*v1_txn.hash()); let pricing_mode = v1_txn.pricing_mode(); let payment_amount = match v1_txn.pricing_mode() { @@ -573,7 +630,7 @@ impl<'a> TryFrom<&'a TransactionV1> for PaymentInfo<'a> { let payment = match v1_txn.target() { TransactionTarget::Session { module_bytes, .. } => { - ExecutableItem::CustomPayment(module_bytes) + ExecutableItem::PaymentBytes(module_bytes.clone()) } TransactionTarget::Native | TransactionTarget::Stored { .. } => { return Err(InvalidRequest::InvalidTarget( @@ -583,6 +640,13 @@ impl<'a> TryFrom<&'a TransactionV1> for PaymentInfo<'a> { } }; let args = runtime_args! { ARG_AMOUNT => U512::from(payment_amount)}; - Ok(PaymentInfo { payment, args }) + let TransactionEntryPoint::Custom(entry_point) = v1_txn.entry_point().clone() else { + return Err(InvalidRequest::InvalidEntryPoint(transaction_hash, v1_txn.entry_point().to_string())); + }; + Ok(PaymentInfo(ExecutableInfo { + item: payment, + entry_point, + args, + })) } } diff --git a/execution_engine/src/execution/executor.rs b/execution_engine/src/execution/executor.rs index 846732760b..53515d4713 100644 --- a/execution_engine/src/execution/executor.rs +++ b/execution_engine/src/execution/executor.rs @@ -5,16 +5,14 @@ use casper_storage::{ tracking_copy::TrackingCopy, AddressGenerator, }; -use casper_types::execution::Effects; use casper_types::{ - account::AccountHash, addressable_entity::NamedKeys, AddressableEntity, AddressableEntityHash, - BlockTime, ContextAccessRights, EntryPointType, Gas, Key, Phase, ProtocolVersion, RuntimeArgs, - StoredValue, Tagged, TransactionHash, U512, + account::AccountHash, addressable_entity::NamedKeys, execution::Effects, AddressableEntity, + AddressableEntityHash, BlockTime, ContextAccessRights, EntryPointType, Gas, Key, Phase, + ProtocolVersion, RuntimeArgs, StoredValue, Tagged, TransactionHash, U512, }; -use crate::engine_state::WasmV1Result; use crate::{ - engine_state::{execution_kind::ExecutionKind, EngineConfig}, + engine_state::{execution_kind::ExecutionKind, EngineConfig, WasmV1Result}, execution::ExecError, runtime::{Runtime, RuntimeStack}, runtime_context::{CallingAddContractVersion, RuntimeContext}, diff --git a/execution_engine_testing/test_support/src/chainspec_config.rs b/execution_engine_testing/test_support/src/chainspec_config.rs index eaa943d45a..5a17e99b78 100644 --- a/execution_engine_testing/test_support/src/chainspec_config.rs +++ b/execution_engine_testing/test_support/src/chainspec_config.rs @@ -106,14 +106,22 @@ impl ChainspecConfig { genesis_accounts: Vec, protocol_version: ProtocolVersion, ) -> Result { - let chainspec_config = ChainspecConfig::from_path(filename)?; + ChainspecConfig::from_path(filename)? + .create_genesis_request(genesis_accounts, protocol_version) + } + /// Create genesis request from self. + pub fn create_genesis_request( + &self, + genesis_accounts: Vec, + protocol_version: ProtocolVersion, + ) -> Result { // if you get a compilation error here, make sure to update the builder below accordingly let ChainspecConfig { core_config, wasm_config, system_costs_config, - } = chainspec_config; + } = self; let CoreConfig { validator_slots, auction_delay, @@ -125,13 +133,13 @@ impl ChainspecConfig { let genesis_config = GenesisConfigBuilder::new() .with_accounts(genesis_accounts) - .with_wasm_config(wasm_config) - .with_system_config(system_costs_config) - .with_validator_slots(validator_slots) - .with_auction_delay(auction_delay) + .with_wasm_config(*wasm_config) + .with_system_config(*system_costs_config) + .with_validator_slots(*validator_slots) + .with_auction_delay(*auction_delay) .with_locked_funds_period_millis(locked_funds_period.millis()) - .with_round_seigniorage_rate(round_seigniorage_rate) - .with_unbonding_delay(unbonding_delay) + .with_round_seigniorage_rate(*round_seigniorage_rate) + .with_unbonding_delay(*unbonding_delay) .with_genesis_timestamp_millis(DEFAULT_GENESIS_TIMESTAMP_MILLIS) .build(); diff --git a/execution_engine_testing/test_support/src/execute_request_builder.rs b/execution_engine_testing/test_support/src/execute_request_builder.rs index 828b0f0724..3000a00852 100644 --- a/execution_engine_testing/test_support/src/execute_request_builder.rs +++ b/execution_engine_testing/test_support/src/execute_request_builder.rs @@ -4,40 +4,42 @@ use casper_execution_engine::engine_state::{ deploy_item::DeployItem, ExecutableItem, WasmV1Request, }; use casper_types::{ - account::AccountHash, runtime_args, AddressableEntityHash, BlockTime, Digest, EntityVersion, - Gas, InitiatorAddr, PackageHash, Phase, RuntimeArgs, Transaction, TransactionHash, - TransactionV1Hash, + account::AccountHash, addressable_entity::DEFAULT_ENTRY_POINT_NAME, runtime_args, + AddressableEntityHash, BlockTime, Digest, EntityVersion, Gas, InitiatorAddr, PackageHash, + Phase, RuntimeArgs, Transaction, TransactionHash, TransactionV1Hash, }; use crate::{DeployItemBuilder, ARG_AMOUNT, DEFAULT_BLOCK_TIME, DEFAULT_PAYMENT}; /// A request comprising a [`WasmV1Request`] for use as session code, and an optional custom /// payment `WasmV1Request`. -pub struct ExecuteRequest<'a> { +#[derive(Debug)] +pub struct ExecuteRequest { /// The session request. - pub session: WasmV1Request<'a>, + pub session: WasmV1Request, /// The optional custom payment request. - pub custom_payment: Option>, + pub custom_payment: Option, } /// Builds an [`ExecuteRequest`]. #[derive(Debug)] -pub struct ExecuteRequestBuilder<'a> { +pub struct ExecuteRequestBuilder { state_hash: Digest, block_time: BlockTime, transaction_hash: TransactionHash, initiator_addr: InitiatorAddr, - payment: Option>, + payment: Option, payment_gas_limit: Gas, + payment_entry_point: String, payment_args: RuntimeArgs, - session: ExecutableItem<'a>, + session: ExecutableItem, session_gas_limit: Gas, session_entry_point: String, session_args: RuntimeArgs, authorization_keys: BTreeSet, } -impl<'a> ExecuteRequestBuilder<'a> { +impl ExecuteRequestBuilder { /// The default value used for `WasmV1Request::state_hash`. pub const DEFAULT_STATE_HASH: Digest = Digest::from_raw([1; 32]); /// The default value used for `WasmV1Request::transaction_hash`. @@ -47,7 +49,7 @@ impl<'a> ExecuteRequestBuilder<'a> { pub const DEFAULT_ENTRY_POINT: &'static str = "call"; /// Converts a `Transaction` into an `ExecuteRequestBuilder`. - pub fn from_transaction(txn: &'a Transaction) -> Self { + pub fn from_transaction(txn: &Transaction) -> Self { let authorization_keys = txn.authorization_keys(); let session = WasmV1Request::new_session( Self::DEFAULT_STATE_HASH, @@ -59,10 +61,12 @@ impl<'a> ExecuteRequestBuilder<'a> { let payment: Option; let payment_gas_limit: Gas; + let payment_entry_point: String; let payment_args: RuntimeArgs; if txn.is_standard_payment() { payment = None; payment_gas_limit = Gas::zero(); + payment_entry_point = DEFAULT_ENTRY_POINT_NAME.to_string(); payment_args = RuntimeArgs::new(); } else { let request = WasmV1Request::new_custom_payment( @@ -74,6 +78,7 @@ impl<'a> ExecuteRequestBuilder<'a> { .unwrap(); payment = Some(request.executable_item); payment_gas_limit = request.gas_limit; + payment_entry_point = request.entry_point; payment_args = request.args; } @@ -84,6 +89,7 @@ impl<'a> ExecuteRequestBuilder<'a> { initiator_addr: session.initiator_addr, payment, payment_gas_limit, + payment_entry_point, payment_args, session: session.executable_item, session_gas_limit: session.gas_limit, @@ -94,7 +100,7 @@ impl<'a> ExecuteRequestBuilder<'a> { } /// Converts a `DeployItem` into an `ExecuteRequestBuilder`. - pub fn from_deploy_item(deploy_item: &'a DeployItem) -> Self { + pub fn from_deploy_item(deploy_item: &DeployItem) -> Self { let authorization_keys = deploy_item.authorization_keys.clone(); let session = WasmV1Request::new_session_from_deploy_item( Self::DEFAULT_STATE_HASH, @@ -106,10 +112,12 @@ impl<'a> ExecuteRequestBuilder<'a> { let payment: Option; let payment_gas_limit: Gas; + let payment_entry_point: String; let payment_args: RuntimeArgs; if deploy_item.payment.is_standard_payment(Phase::Payment) { payment = None; payment_gas_limit = Gas::zero(); + payment_entry_point = DEFAULT_ENTRY_POINT_NAME.to_string(); payment_args = RuntimeArgs::new(); } else { let request = WasmV1Request::new_custom_payment_from_deploy_item( @@ -121,6 +129,7 @@ impl<'a> ExecuteRequestBuilder<'a> { .unwrap(); payment = Some(request.executable_item); payment_gas_limit = request.gas_limit; + payment_entry_point = request.entry_point; payment_args = request.args; } @@ -131,6 +140,7 @@ impl<'a> ExecuteRequestBuilder<'a> { initiator_addr: session.initiator_addr, payment, payment_gas_limit, + payment_entry_point, payment_args, session: session.executable_item, session_gas_limit: session.gas_limit, @@ -154,7 +164,7 @@ impl<'a> ExecuteRequestBuilder<'a> { }) .with_authorization_keys(&[account_hash]) .build(); - Self::from_deploy_item(Box::leak(Box::new(deploy_item))) + Self::from_deploy_item(&deploy_item) } /// Returns an [`ExecuteRequest`] derived from a deploy with session module bytes. @@ -171,7 +181,7 @@ impl<'a> ExecuteRequestBuilder<'a> { }) .with_authorization_keys(&[account_hash]) .build(); - Self::from_deploy_item(Box::leak(Box::new(deploy_item))) + Self::from_deploy_item(&deploy_item) } /// Returns an [`ExecuteRequest`] derived from a deploy with a session item that will call a @@ -188,7 +198,7 @@ impl<'a> ExecuteRequestBuilder<'a> { .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[sender]) .build(); - Self::from_deploy_item(Box::leak(Box::new(deploy_item))) + Self::from_deploy_item(&deploy_item) } /// Returns an [`ExecuteRequest`] derived from a deploy with a session item that will call a @@ -205,7 +215,7 @@ impl<'a> ExecuteRequestBuilder<'a> { .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[sender]) .build(); - Self::from_deploy_item(Box::leak(Box::new(deploy_item))) + Self::from_deploy_item(&deploy_item) } /// Returns an [`ExecuteRequest`] derived from a deploy with a session item that will call a @@ -228,7 +238,7 @@ impl<'a> ExecuteRequestBuilder<'a> { .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[sender]) .build(); - Self::from_deploy_item(Box::leak(Box::new(deploy_item))) + Self::from_deploy_item(&deploy_item) } /// Returns an [`ExecuteRequest`] derived from a deploy with a session item that will call a @@ -246,7 +256,7 @@ impl<'a> ExecuteRequestBuilder<'a> { .with_standard_payment(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) .with_authorization_keys(&[sender]) .build(); - Self::from_deploy_item(Box::leak(Box::new(deploy_item))) + Self::from_deploy_item(&deploy_item) } /// Sets the block time of the [`WasmV1Request`]s. @@ -262,7 +272,7 @@ impl<'a> ExecuteRequestBuilder<'a> { } /// Consumes self and returns an `ExecuteRequest`. - pub fn build(self) -> ExecuteRequest<'a> { + pub fn build(self) -> ExecuteRequest { let ExecuteRequestBuilder { state_hash, block_time, @@ -270,6 +280,7 @@ impl<'a> ExecuteRequestBuilder<'a> { initiator_addr, payment, payment_gas_limit, + payment_entry_point, payment_args, session, session_gas_limit, @@ -285,9 +296,10 @@ impl<'a> ExecuteRequestBuilder<'a> { gas_limit: payment_gas_limit, initiator_addr: initiator_addr.clone(), executable_item, - entry_point: Self::DEFAULT_ENTRY_POINT.to_string(), + entry_point: payment_entry_point, args: payment_args, authorization_keys: authorization_keys.clone(), + phase: Phase::Payment, }); let session = WasmV1Request { @@ -300,6 +312,7 @@ impl<'a> ExecuteRequestBuilder<'a> { entry_point: session_entry_point, args: session_args, authorization_keys, + phase: Phase::Session, }; ExecuteRequest { diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index 2aea4d2fae..48f39ebe6f 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -21,15 +21,15 @@ use casper_execution_engine::engine_state::{ }; use casper_storage::{ data_access_layer::{ - balance::BalanceHandling, AuctionMethod, BalanceRequest, BalanceResult, BiddingRequest, - BiddingResult, BidsRequest, BlockRewardsRequest, BlockRewardsResult, BlockStore, - DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, FeeRequest, FeeResult, - FlushRequest, FlushResult, GenesisRequest, GenesisResult, ProtocolUpgradeRequest, - ProtocolUpgradeResult, PruneRequest, PruneResult, QueryRequest, QueryResult, - RoundSeigniorageRateRequest, RoundSeigniorageRateResult, StepRequest, StepResult, - SystemEntityRegistryPayload, SystemEntityRegistryRequest, SystemEntityRegistryResult, - SystemEntityRegistrySelector, TotalSupplyRequest, TotalSupplyResult, TransferRequest, - TrieRequest, + balance::BalanceHandling, AuctionMethod, BalanceIdentifier, BalanceRequest, BalanceResult, + BiddingRequest, BiddingResult, BidsRequest, BlockRewardsRequest, BlockRewardsResult, + BlockStore, DataAccessLayer, EraValidatorsRequest, EraValidatorsResult, FeeRequest, + FeeResult, FlushRequest, FlushResult, GenesisRequest, GenesisResult, + ProtocolUpgradeRequest, ProtocolUpgradeResult, PruneRequest, PruneResult, QueryRequest, + QueryResult, RoundSeigniorageRateRequest, RoundSeigniorageRateResult, StepRequest, + StepResult, SystemEntityRegistryPayload, SystemEntityRegistryRequest, + SystemEntityRegistryResult, SystemEntityRegistrySelector, TotalSupplyRequest, + TotalSupplyResult, TransferRequest, TrieRequest, }, global_state::{ state::{ @@ -833,6 +833,7 @@ where } execute_request.session.state_hash = self.post_state_hash.expect("expected post_state_hash"); + let session_result = self .execution_engine .execute(self.data_access_layer.as_ref(), execute_request.session); @@ -843,6 +844,18 @@ where self } + /// Execute a `WasmV1Request`. + pub fn exec_wasm_v1(&mut self, mut request: WasmV1Request) -> &mut Self { + request.state_hash = self.post_state_hash.expect("expected post_state_hash"); + let result = self + .execution_engine + .execute(self.data_access_layer.as_ref(), request); + let effects = result.effects().clone(); + self.exec_results.push(result); + self.effects.push(effects); + self + } + /// Commit effects of previous exec call on the latest post-state hash. pub fn commit(&mut self) -> &mut Self { let prestate_hash = self.post_state_hash.expect("Should have genesis hash"); @@ -1209,7 +1222,7 @@ where pub fn get_purse_balance_result( &self, protocol_version: ProtocolVersion, - purse: URef, + balance_identifier: BalanceIdentifier, block_time: u64, ) -> BalanceResult { let hold_interval = self.chainspec.core_config.balance_hold_interval.millis(); @@ -1217,8 +1230,12 @@ where let balance_handling = BalanceHandling::Available { holds_epoch }; let state_root_hash: Digest = self.post_state_hash.expect("should have post_state_hash"); - let request = - BalanceRequest::from_purse(state_root_hash, protocol_version, purse, balance_handling); + let request = BalanceRequest::new( + state_root_hash, + protocol_version, + balance_identifier, + balance_handling, + ); self.data_access_layer.balance(request) } diff --git a/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs b/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs index 9601c8f4bf..70220c6e54 100644 --- a/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs +++ b/execution_engine_testing/tests/src/test/contract_api/get_call_stack.rs @@ -3573,7 +3573,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_versioned_payment_by_name_to_stored_versioned_session() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3599,7 +3598,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_versioned_payment_by_hash_to_stored_versioned_session() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3629,7 +3627,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_versioned_payment_by_name_to_stored_session() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3650,7 +3647,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_versioned_payment_by_hash_to_stored_session() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3679,7 +3675,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_payment_by_name_to_stored_versioned_session() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3705,7 +3700,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_payment_by_hash_to_stored_versioned_session() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3738,7 +3732,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_payment_by_name_to_stored_session() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3759,7 +3752,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_payment_by_hash_to_stored_session() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3785,7 +3777,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_versioned_payment_by_name_to_stored_versioned_contract() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3811,7 +3802,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_versioned_payment_by_hash_to_stored_versioned_contract() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3842,7 +3832,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_versioned_payment_by_name_to_stored_contract() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3863,7 +3852,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_versioned_payment_by_hash_to_stored_contract() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3892,7 +3880,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_payment_by_name_to_stored_versioned_contract() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3917,7 +3904,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_payment_by_hash_to_stored_versioned_contract() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3950,7 +3936,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_payment_by_name_to_stored_contract() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3971,7 +3956,7 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] + #[test] fn stored_payment_by_hash_to_stored_contract() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -3999,7 +3984,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_versioned_payment_by_name_to_stored_versioned_contract_to_stored_versioned_session_should_fail( ) { for call_depth in DEPTHS { @@ -4031,7 +4015,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_versioned_payment_by_hash_to_stored_versioned_contract_to_stored_session_should_fail() { for call_depth in DEPTHS { @@ -4068,7 +4051,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_versioned_payment_by_name_to_stored_contract_to_stored_versioned_session_should_fail() { for call_depth in DEPTHS { @@ -4101,7 +4083,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_versioned_payment_by_hash_to_stored_contract_to_stored_session_should_fail() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -4136,7 +4117,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_payment_by_name_to_stored_versioned_contract_to_stored_versioned_session_should_fail() { for call_depth in DEPTHS { @@ -4168,7 +4148,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_session_by_hash_to_stored_versioned_contract_to_stored_session_should_fail() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -4204,7 +4183,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_payment_by_name_to_stored_contract_to_stored_versioned_session_should_fail() { for call_depth in DEPTHS { let mut builder = super::setup(); @@ -4236,7 +4214,6 @@ mod payment { #[ignore] #[allow(unused)] - // #[test] fn stored_payment_by_name_to_stored_contract_to_stored_session_should_fail() { for call_depth in DEPTHS { let mut builder = super::setup(); diff --git a/execution_engine_testing/tests/src/test/contract_api/transfer.rs b/execution_engine_testing/tests/src/test/contract_api/transfer.rs index 443af358bd..60a378ce43 100644 --- a/execution_engine_testing/tests/src/test/contract_api/transfer.rs +++ b/execution_engine_testing/tests/src/test/contract_api/transfer.rs @@ -470,41 +470,105 @@ fn should_fail_when_insufficient_funds() { #[ignore] #[allow(unused)] -// #[test] +#[test] fn should_transfer_total_amount() { - let mut builder = LmdbWasmTestBuilder::default(); - - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_TRANSFER_PURSE_TO_ACCOUNT, - runtime_args! { "target" => *ACCOUNT_1_ADDR, "amount" => *ACCOUNT_1_INITIAL_BALANCE }, - ) - .build(); - - let transfer_amount_1 = *ACCOUNT_1_INITIAL_BALANCE - *DEFAULT_PAYMENT; - - let exec_request_2 = ExecuteRequestBuilder::standard( - *ACCOUNT_1_ADDR, - CONTRACT_TRANSFER_PURSE_TO_ACCOUNT, - runtime_args! { "target" => *ACCOUNT_2_ADDR, "amount" => transfer_amount_1 }, - ) - .build(); - - builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); - - builder.exec(exec_request_1).expect_success().commit(); - - builder.exec(exec_request_2).commit().expect_success(); + // NOTE: as of protocol version 2.0.0 the execution engine is no longer reponsible + // for payment, refund, or fee handling...thus + // full transactions executed via the node are subject to payment, fee, refund, + // etc based upon chainspec settings, but when using the EE directly as is done + // in this test, there is no charge and all transfers are at face value. + fn balance_checker(bldr: &mut LmdbWasmTestBuilder, account_hash: AccountHash) -> U512 { + let entity = bldr + .get_entity_by_account_hash(account_hash) + .expect("should have account entity"); + let entity_main_purse = entity.main_purse(); + bldr.get_purse_balance(entity_main_purse) + } + fn commit(bldr: &mut LmdbWasmTestBuilder, req_bldr: ExecuteRequestBuilder) { + let req = req_bldr.build(); + bldr.exec(req).expect_success().commit(); + } + fn genesis() -> LmdbWasmTestBuilder { + let mut builder = LmdbWasmTestBuilder::default(); + builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); + builder + } + + let mut builder = genesis(); + + let balance_x_initial = balance_checker(&mut builder, *DEFAULT_ACCOUNT_ADDR); + let amount_to_fund = *ACCOUNT_1_INITIAL_BALANCE; + + // fund account 1 from default account + commit( + &mut builder, + ExecuteRequestBuilder::standard( + *DEFAULT_ACCOUNT_ADDR, + CONTRACT_TRANSFER_PURSE_TO_ACCOUNT, + runtime_args! { "target" => *ACCOUNT_1_ADDR, "amount" => amount_to_fund }, + ), + ); + let balance_x_out = balance_checker(&mut builder, *DEFAULT_ACCOUNT_ADDR); + assert_eq!( + balance_x_initial - amount_to_fund, + balance_x_out, + "funded amount should be deducted from funder's balance" + ); + let balance_y_initial = balance_checker(&mut builder, *ACCOUNT_1_ADDR); + assert_eq!( + amount_to_fund, balance_y_initial, + "receiving account's balance should match funding amount" + ); + let diff = balance_x_initial - balance_y_initial; + assert_eq!( + diff, balance_x_out, + "funder's balance difference should equal funded amount" + ); - let account_1 = builder - .get_entity_by_account_hash(*ACCOUNT_1_ADDR) - .expect("should have account"); - let account_1_main_purse = account_1.main_purse(); - let account_1_balance = builder.get_purse_balance(account_1_main_purse); + // transfer it to a different account + commit( + &mut builder, + ExecuteRequestBuilder::standard( + *ACCOUNT_1_ADDR, + CONTRACT_TRANSFER_PURSE_TO_ACCOUNT, + runtime_args! { "target" => *ACCOUNT_2_ADDR, "amount" => balance_y_initial }, + ), + ); + let balance_y_out = balance_checker(&mut builder, *ACCOUNT_1_ADDR); + assert_eq!( + balance_y_initial - amount_to_fund, + balance_y_out, + "funded amount should be deducted from funder's balance" + ); + let balance_z_initial = balance_checker(&mut builder, *ACCOUNT_2_ADDR); + assert_eq!( + amount_to_fund, balance_z_initial, + "receiving account's balance should match funding amount" + ); + let diff = balance_y_initial - balance_z_initial; + assert_eq!( + diff, balance_y_out, + "funder's balance difference should equal funded amount" + ); + // transfer it back to originator + commit( + &mut builder, + ExecuteRequestBuilder::standard( + *ACCOUNT_2_ADDR, + CONTRACT_TRANSFER_PURSE_TO_ACCOUNT, + runtime_args! { "target" => *DEFAULT_ACCOUNT_ADDR, "amount" => balance_z_initial }, + ), + ); + let balance_x_in = balance_checker(&mut builder, *DEFAULT_ACCOUNT_ADDR); + let balance_z_out = balance_checker(&mut builder, *ACCOUNT_2_ADDR); assert_eq!( - account_1_balance, - builder.calculate_refund_amount(*DEFAULT_PAYMENT), - "account 1 should only have refunded amount after transferring full amount" + U512::zero(), + balance_z_out, + "trampoline account should be zero'd" + ); + assert_eq!( + balance_x_initial, balance_x_in, + "original balance should be restored" ); } diff --git a/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs b/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs index 3c20a7dad9..cac1baa96c 100644 --- a/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs +++ b/execution_engine_testing/tests/src/test/deploy/non_standard_payment.rs @@ -1,8 +1,11 @@ use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, LOCAL_GENESIS_REQUEST, MINIMUM_ACCOUNT_CREATION_BALANCE, + DEFAULT_PAYMENT, DEFAULT_PROTOCOL_VERSION, LOCAL_GENESIS_REQUEST, + MINIMUM_ACCOUNT_CREATION_BALANCE, }; -use casper_types::{account::AccountHash, runtime_args, RuntimeArgs, U512}; +use casper_execution_engine::engine_state::WasmV1Request; +use casper_storage::data_access_layer::BalanceIdentifier; +use casper_types::{account::AccountHash, runtime_args, Digest, Gas, RuntimeArgs, Timestamp, U512}; const ACCOUNT_1_ADDR: AccountHash = AccountHash::new([42u8; 32]); const DO_NOTHING_WASM: &str = "do_nothing.wasm"; @@ -16,14 +19,13 @@ const ARG_DESTINATION: &str = "destination"; #[ignore] #[allow(unused)] -// #[test] +#[test] fn should_charge_non_main_purse() { // as account_1, create & fund a new purse and use that to pay for something // instead of account_1 main purse const TEST_PURSE_NAME: &str = "test-purse"; let account_1_account_hash = ACCOUNT_1_ADDR; - let payment_purse_amount = *DEFAULT_PAYMENT; let account_1_funding_amount = U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE); let account_1_purse_funding_amount = *DEFAULT_PAYMENT; @@ -41,7 +43,7 @@ fn should_charge_non_main_purse() { TRANSFER_MAIN_PURSE_TO_NEW_PURSE_WASM, runtime_args! { ARG_DESTINATION => TEST_PURSE_NAME, ARG_AMOUNT => account_1_purse_funding_amount }, ) - .build(); + .build(); builder.run_genesis(LOCAL_GENESIS_REQUEST.clone()); @@ -60,14 +62,16 @@ fn should_charge_non_main_purse() { // get purse let purse_key = account_1.named_keys().get(TEST_PURSE_NAME).unwrap(); let purse = purse_key.into_uref().expect("should have uref"); - let purse_starting_balance = builder.get_purse_balance(purse); assert_eq!( purse_starting_balance, account_1_purse_funding_amount, - "purse should be funded with expected amount" + "purse should be funded with expected amount, which in this case is also == to the amount to be paid" ); + // in this test, we're just going to pay everything in the purse to + // keep the math easy. + let amount_to_be_paid = account_1_purse_funding_amount; // should be able to pay for exec using new purse let deploy_item = DeployItemBuilder::new() .with_address(ACCOUNT_1_ADDR) @@ -76,31 +80,53 @@ fn should_charge_non_main_purse() { NAMED_PURSE_PAYMENT_WASM, runtime_args! { ARG_PURSE_NAME => TEST_PURSE_NAME, - ARG_AMOUNT => payment_purse_amount + ARG_AMOUNT => amount_to_be_paid }, ) .with_authorization_keys(&[account_1_account_hash]) .with_deploy_hash([3; 32]) .build(); - let account_payment_exec_request = - ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(); - - let proposer_reward_starting_balance = builder.get_proposer_purse_balance(); + let block_time = Timestamp::now().millis(); builder - .exec(account_payment_exec_request) + .exec_wasm_v1( + WasmV1Request::new_custom_payment_from_deploy_item( + Digest::default(), + block_time.into(), + Gas::from(12_500_000_000_u64), + &deploy_item, + ) + .expect("should be valid req"), + ) .expect_success() .commit(); - let transaction_fee = builder.get_proposer_purse_balance() - proposer_reward_starting_balance; + let payment_purse_balance = builder.get_purse_balance_result( + DEFAULT_PROTOCOL_VERSION, + BalanceIdentifier::Payment, + block_time, + ); - let expected_resting_balance = account_1_purse_funding_amount - transaction_fee; + assert!( + payment_purse_balance.is_success(), + "payment purse balance check should succeed" + ); - let purse_final_balance = builder.get_purse_balance(purse); + let paid_amount = *payment_purse_balance + .motes() + .expect("should have payment amount"); assert_eq!( - purse_final_balance, expected_resting_balance, + paid_amount, amount_to_be_paid, "purse resting balance should equal funding amount minus exec costs" ); + + let purse_final_balance = builder.get_purse_balance(purse); + + assert_eq!( + purse_final_balance, + U512::zero(), + "since we zero'd out the paying purse, the final balance should be zero" + ); } diff --git a/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs b/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs index c771b9f31e..9d1e449407 100644 --- a/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs +++ b/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs @@ -285,7 +285,7 @@ fn should_not_transfer_above_balance_using_stored_payment_code_by_hash() { #[ignore] #[allow(unused)] -// #[test] +#[test] fn should_empty_account_using_stored_payment_code_by_hash() { let payment_purse_amount = *DEFAULT_PAYMENT; diff --git a/execution_engine_testing/tests/src/test/explorer/faucet.rs b/execution_engine_testing/tests/src/test/explorer/faucet.rs index fab2d9125e..9bfbc94020 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet.rs @@ -926,10 +926,10 @@ fn faucet_costs() { // This test will fail if execution costs vary. The expected costs should not be updated // without understanding why the cost has changed. If the costs do change, it should be // reflected in the "Costs by Entry Point" section of the faucet crate's README.md. - const EXPECTED_FAUCET_INSTALL_COST: u64 = 91_842_307_540; - const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 110_733_980; - const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_317_720; - const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_618_815_540; + const EXPECTED_FAUCET_INSTALL_COST: u64 = 91_914_271_090; + const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 111_340_630; + const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_774_911_250; + const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_619_882_230; let installer_account = AccountHash::new([1u8; 32]); let user_account: AccountHash = AccountHash::new([2u8; 32]); diff --git a/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs b/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs index ee3de0cd71..c78209c35a 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet_test_helpers.rs @@ -97,7 +97,7 @@ impl FaucetInstallSessionRequestBuilder { self } - pub fn build(&self) -> ExecuteRequest<'static> { + pub fn build(&self) -> ExecuteRequest { ExecuteRequestBuilder::standard( self.installer_account, &self.faucet_installer_session, @@ -159,7 +159,7 @@ impl FaucetConfigRequestBuilder { self } - pub fn build(&self) -> ExecuteRequest<'static> { + pub fn build(&self) -> ExecuteRequest { ExecuteRequestBuilder::contract_call_by_hash( self.installer_account, self.faucet_contract_hash @@ -219,7 +219,7 @@ impl FaucetAuthorizeAccountRequestBuilder { self } - pub fn build<'a>(self) -> ExecuteRequest<'a> { + pub fn build(self) -> ExecuteRequest { ExecuteRequestBuilder::contract_call_by_hash( self.installer_account, self.faucet_contract_hash @@ -315,7 +315,7 @@ impl FaucetFundRequestBuilder { self } - pub fn build(self) -> ExecuteRequest<'static> { + pub fn build(self) -> ExecuteRequest { let mut rng = rand::thread_rng(); let deploy_item = DeployItemBuilder::new() @@ -342,14 +342,10 @@ impl FaucetFundRequestBuilder { .build(); match self.block_time { - Some(block_time) => { - ExecuteRequestBuilder::from_deploy_item(Box::leak(Box::new(deploy_item))) - .with_block_time(block_time) - .build() - } - None => { - ExecuteRequestBuilder::from_deploy_item(Box::leak(Box::new(deploy_item))).build() - } + Some(block_time) => ExecuteRequestBuilder::from_deploy_item(&deploy_item) + .with_block_time(block_time) + .build(), + None => ExecuteRequestBuilder::from_deploy_item(&deploy_item).build(), } } } @@ -559,7 +555,7 @@ impl FaucetDeployHelper { .build() } - pub fn faucet_install_request(&self) -> ExecuteRequest<'static> { + pub fn faucet_install_request(&self) -> ExecuteRequest { self.faucet_install_session_request_builder .clone() .with_installer_account(self.installer_account) @@ -569,7 +565,7 @@ impl FaucetDeployHelper { .build() } - pub fn faucet_config_request(&self) -> ExecuteRequest<'static> { + pub fn faucet_config_request(&self) -> ExecuteRequest { self.faucet_config_request_builder .with_installer_account(self.installer_account()) .with_faucet_contract_hash( diff --git a/execution_engine_testing/tests/src/test/get_balance.rs b/execution_engine_testing/tests/src/test/get_balance.rs index 9ef06d0959..c324cbc085 100644 --- a/execution_engine_testing/tests/src/test/get_balance.rs +++ b/execution_engine_testing/tests/src/test/get_balance.rs @@ -3,7 +3,10 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ LmdbWasmTestBuilder, TransferRequestBuilder, LOCAL_GENESIS_REQUEST, }; -use casper_storage::tracking_copy::{self, ValidationError}; +use casper_storage::{ + data_access_layer::BalanceIdentifier, + tracking_copy::{self, ValidationError}, +}; use casper_types::{ account::AccountHash, AccessRights, Digest, Key, ProtocolVersion, PublicKey, SecretKey, URef, U512, @@ -39,8 +42,11 @@ fn get_balance_should_work() { let alice_main_purse = alice_account.main_purse(); - let alice_balance_result = - builder.get_purse_balance_result(protocol_version, alice_main_purse, block_time); + let alice_balance_result = builder.get_purse_balance_result( + protocol_version, + BalanceIdentifier::Purse(alice_main_purse), + block_time, + ); let alice_balance = alice_balance_result .motes() diff --git a/execution_engine_testing/tests/src/test/regression/ee_966.rs b/execution_engine_testing/tests/src/test/regression/ee_966.rs index 26785ac415..ee472bf628 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_966.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_966.rs @@ -57,7 +57,7 @@ fn make_session_code_with_memory_pages(initial_pages: u32, max_pages: Option(session_code: Vec) -> ExecuteRequest<'a> { +fn make_request_with_session_bytes(session_code: Vec) -> ExecuteRequest { let deploy_item = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_session_bytes(session_code, RuntimeArgs::new()) @@ -68,7 +68,7 @@ fn make_request_with_session_bytes<'a>(session_code: Vec) -> ExecuteRequest< .with_deploy_hash([42; 32]) .build(); - ExecuteRequestBuilder::from_deploy_item(Box::leak(Box::new(deploy_item))).build() + ExecuteRequestBuilder::from_deploy_item(&deploy_item).build() } #[ignore] diff --git a/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs b/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs index 3c6debc79f..b594619e28 100644 --- a/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs +++ b/execution_engine_testing/tests/src/test/regression/host_function_metrics_size_and_gas_cost.rs @@ -59,7 +59,7 @@ fn host_function_metrics_has_acceptable_size() { ) } -fn create_account_exec_request<'a>(address: AccountHash) -> ExecuteRequest<'a> { +fn create_account_exec_request(address: AccountHash) -> ExecuteRequest { ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, CONTRACT_TRANSFER_TO_ACCOUNT_U512, diff --git a/execution_engine_testing/tests/src/test/regression/regression_20210707.rs b/execution_engine_testing/tests/src/test/regression/regression_20210707.rs index 61b06555cb..d3cdb68ed2 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20210707.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20210707.rs @@ -42,7 +42,7 @@ static BOB_KEY: Lazy = Lazy::new(|| { }); static BOB_ADDR: Lazy = Lazy::new(|| AccountHash::from(&*BOB_KEY)); -fn setup_regression_contract<'a>() -> ExecuteRequest<'a> { +fn setup_regression_contract() -> ExecuteRequest { ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, REGRESSION_20210707, diff --git a/node/src/components/transaction_acceptor/tests.rs b/node/src/components/transaction_acceptor/tests.rs index 51b9c1a0e4..2e6107a20e 100644 --- a/node/src/components/transaction_acceptor/tests.rs +++ b/node/src/components/transaction_acceptor/tests.rs @@ -559,7 +559,7 @@ impl TestScenario { let classic_mode_transaction = TransactionV1Builder::new_random(rng) .with_pricing_mode(PricingMode::Classic { payment_amount: 10000u64, - gas_price: 1u8, + gas_price_tolerance: 1u8, standard_payment: true, }) .with_chain_name("casper-example") diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index f9f9c1f557..9c1147ab4c 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -1637,7 +1637,7 @@ "Classic": { "type": "object", "required": [ - "gas_price", + "gas_price_tolerance", "payment_amount", "standard_payment" ], @@ -1648,8 +1648,8 @@ "format": "uint64", "minimum": 0.0 }, - "gas_price": { - "description": "User-specified gas_price (minimum 1).", + "gas_price_tolerance": { + "description": "User-specified gas_price tolerance (minimum 1). This is interpreted to mean \"do not include this transaction in a block if the current gas price is greater than this number\"", "type": "integer", "format": "uint8", "minimum": 0.0 diff --git a/storage/src/data_access_layer/balance.rs b/storage/src/data_access_layer/balance.rs index 50acb56e33..14510c7c32 100644 --- a/storage/src/data_access_layer/balance.rs +++ b/storage/src/data_access_layer/balance.rs @@ -345,4 +345,12 @@ impl BalanceResult { } => available_balance >= &cost, } } + + /// Was the balance request successful? + pub fn is_success(&self) -> bool { + match self { + BalanceResult::RootNotFound | BalanceResult::Failure(_) => false, + BalanceResult::Success { .. } => true, + } + } } diff --git a/types/src/transaction/deploy/deploy_header.rs b/types/src/transaction/deploy/deploy_header.rs index 737e3ff95e..09a27057cc 100644 --- a/types/src/transaction/deploy/deploy_header.rs +++ b/types/src/transaction/deploy/deploy_header.rs @@ -87,7 +87,7 @@ impl DeployHeader { pub fn gas_price(&self) -> u64 { // in the original implementation, we did not have dynamic gas pricing // but the sender of the deploy could specify a higher gas price, - // and the the payment amount would be multiplied by that number + // and the payment amount would be multiplied by that number // for settlement purposes. This did not increase their computation limit, // only how much they were charged. The intent was, the total cost // would be a consideration for block proposal but in the end we shipped diff --git a/types/src/transaction/pricing_mode.rs b/types/src/transaction/pricing_mode.rs index 74cc4fbd77..b50f13a52c 100644 --- a/types/src/transaction/pricing_mode.rs +++ b/types/src/transaction/pricing_mode.rs @@ -37,8 +37,10 @@ pub enum PricingMode { Classic { /// User-specified payment amount. payment_amount: u64, - /// User-specified gas_price (minimum 1). - gas_price: u8, + /// User-specified gas_price tolerance (minimum 1). + /// This is interpreted to mean "do not include this transaction in a block + /// if the current gas price is greater than this number" + gas_price_tolerance: u8, /// Standard payment. standard_payment: bool, }, @@ -69,7 +71,7 @@ impl PricingMode { match rng.gen_range(0..3) { 0 => PricingMode::Classic { payment_amount: rng.gen(), - gas_price: 1, + gas_price_tolerance: 1, standard_payment: true, }, 1 => PricingMode::Fixed { @@ -90,7 +92,7 @@ impl Display for PricingMode { match self { PricingMode::Classic { payment_amount, - gas_price, + gas_price_tolerance: gas_price, standard_payment, } => { write!( @@ -120,7 +122,7 @@ impl ToBytes for PricingMode { match self { PricingMode::Classic { payment_amount, - gas_price, + gas_price_tolerance: gas_price, standard_payment, } => { CLASSIC_TAG.write_bytes(writer)?; @@ -158,7 +160,7 @@ impl ToBytes for PricingMode { + match self { PricingMode::Classic { payment_amount, - gas_price, + gas_price_tolerance: gas_price, standard_payment, } => { payment_amount.serialized_length() @@ -193,7 +195,7 @@ impl FromBytes for PricingMode { Ok(( PricingMode::Classic { payment_amount, - gas_price, + gas_price_tolerance: gas_price, standard_payment, }, remainder, diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index b638b37c78..a72ddc88b8 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -1193,7 +1193,7 @@ mod tests { .with_chain_name(chain_name) .with_pricing_mode(PricingMode::Classic { payment_amount: 100000, - gas_price: 1, + gas_price_tolerance: 1, standard_payment: true, }) .build() @@ -1240,7 +1240,7 @@ mod tests { .with_chain_name(chain_name) .with_pricing_mode(PricingMode::Classic { payment_amount, - gas_price: 1, + gas_price_tolerance: 1, standard_payment: true, }); let transaction = builder.build().expect("should build"); diff --git a/types/src/transaction/transaction_v1/transaction_v1_header.rs b/types/src/transaction/transaction_v1/transaction_v1_header.rs index 8b1e4ecd01..6dbcb43123 100644 --- a/types/src/transaction/transaction_v1/transaction_v1_header.rs +++ b/types/src/transaction/transaction_v1/transaction_v1_header.rs @@ -154,7 +154,10 @@ impl TransactionV1Header { /// Returns the gas price tolerance for the given transaction. pub fn gas_price_tolerance(&self) -> u8 { match self.pricing_mode { - PricingMode::Classic { gas_price, .. } => gas_price, + PricingMode::Classic { + gas_price_tolerance, + .. + } => gas_price_tolerance, PricingMode::Fixed { gas_price_tolerance, .. From 8952b6bcfe6cb00adcef5026ebdca09737b4c87a Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Mon, 1 Apr 2024 03:37:09 -0700 Subject: [PATCH 63/70] tweaking fee distribution per convo w michal --- .../test_support/src/wasm_test_builder.rs | 1 + .../components/contract_runtime/operations.rs | 12 +- storage/src/data_access_layer/fee.rs | 12 +- .../src/data_access_layer/handle_payment.rs | 12 - storage/src/global_state/state/mod.rs | 254 ++++-------------- 5 files changed, 77 insertions(+), 214 deletions(-) diff --git a/execution_engine_testing/test_support/src/wasm_test_builder.rs b/execution_engine_testing/test_support/src/wasm_test_builder.rs index 48f39ebe6f..ea3ad1311d 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -973,6 +973,7 @@ where native_runtime_config, pre_state_hash, protocol_version, + block_time.into(), holds_epoch, ); let fee_result = self.data_access_layer.distribute_fees(fee_req); diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 62ff7514ea..52e4cef78c 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -372,15 +372,20 @@ pub fn execute_finalized_block( FeeHandling::Accumulate => { // in this mode, consumed gas is accumulated into a single purse for later // distribution - let consumed = Some(artifact_builder.consumed()); + let consumed = Gas::new(artifact_builder.consumed()); let handle_payment_request = HandlePaymentRequest::new( native_runtime_config.clone(), state_root_hash, protocol_version, transaction_hash, - HandlePaymentMode::distribute_accumulated( + HandlePaymentMode::finalize( + gas_limit.value(), + current_gas_price, + cost, + consumed.value(), + balance_identifier, BalanceIdentifier::Accumulate, - consumed, + holds_epoch, ), ); let handle_payment_result = scratch_state.handle_payment(handle_payment_request); @@ -449,6 +454,7 @@ pub fn execute_finalized_block( native_runtime_config.clone(), state_root_hash, protocol_version, + block_time, holds_epoch, ); match scratch_state.distribute_fees(fee_req) { diff --git a/storage/src/data_access_layer/fee.rs b/storage/src/data_access_layer/fee.rs index 5abe07c0ab..38fd942a27 100644 --- a/storage/src/data_access_layer/fee.rs +++ b/storage/src/data_access_layer/fee.rs @@ -6,8 +6,8 @@ use crate::system::{ transfer::TransferError, }; use casper_types::{ - account::AccountHash, execution::Effects, Digest, FeeHandling, HoldsEpoch, ProtocolVersion, - Transfer, + account::AccountHash, execution::Effects, BlockTime, Digest, FeeHandling, HoldsEpoch, + ProtocolVersion, Transfer, }; use crate::tracking_copy::TrackingCopyError; @@ -17,6 +17,7 @@ pub struct FeeRequest { config: NativeRuntimeConfig, state_hash: Digest, protocol_version: ProtocolVersion, + block_time: BlockTime, holds_epoch: HoldsEpoch, } @@ -25,12 +26,14 @@ impl FeeRequest { config: NativeRuntimeConfig, state_hash: Digest, protocol_version: ProtocolVersion, + block_time: BlockTime, holds_epoch: HoldsEpoch, ) -> Self { FeeRequest { config, state_hash, protocol_version, + block_time, holds_epoch, } } @@ -55,6 +58,11 @@ impl FeeRequest { self.config.fee_handling() } + /// Returns block time. + pub fn block_time(&self) -> BlockTime { + self.block_time + } + /// Returns holds epoch. pub fn holds_epoch(&self) -> HoldsEpoch { self.holds_epoch diff --git a/storage/src/data_access_layer/handle_payment.rs b/storage/src/data_access_layer/handle_payment.rs index 2f73d9d948..4dc9248d60 100644 --- a/storage/src/data_access_layer/handle_payment.rs +++ b/storage/src/data_access_layer/handle_payment.rs @@ -17,10 +17,6 @@ pub enum HandlePaymentMode { target: Box, holds_epoch: HoldsEpoch, }, - Distribute { - source: BalanceIdentifier, - amount: Option, - }, Burn { source: BalanceIdentifier, amount: Option, @@ -52,14 +48,6 @@ impl HandlePaymentMode { } } - /// What source should be used to distribute from (typically the Accumulate purse), and how - /// much? If amount is None or greater than the available balance, the full available - /// balance will be distributed. If amount is less than available balance, only that much - /// will be distributed leaving a remaining balance. - pub fn distribute_accumulated(source: BalanceIdentifier, amount: Option) -> Self { - HandlePaymentMode::Distribute { source, amount } - } - /// What source should be used to burn from, and how much? /// If amount is None or greater than the available balance, the full available balance /// will be burned. If amount is less than available balance, only that much will be diff --git a/storage/src/global_state/state/mod.rs b/storage/src/global_state/state/mod.rs index 25e94c4181..5e8cdbb480 100644 --- a/storage/src/global_state/state/mod.rs +++ b/storage/src/global_state/state/mod.rs @@ -18,21 +18,20 @@ use tracing::{debug, error, warn}; use casper_types::{ addressable_entity::{EntityKindTag, NamedKeys}, - bytesrepr::{self, FromBytes, ToBytes}, + bytesrepr::{self, ToBytes}, execution::{Effects, TransformError, TransformInstruction, TransformKindV2, TransformV2}, global_state::TrieMerkleProof, system::{ self, auction::SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY, - handle_payment::ACCUMULATION_PURSE_KEY, mint::{ BalanceHoldAddr, BalanceHoldAddrTag, ARG_AMOUNT, ROUND_SEIGNIORAGE_RATE_KEY, TOTAL_SUPPLY_KEY, }, - AUCTION, HANDLE_PAYMENT, MINT, + AUCTION, MINT, }, - Account, AddressableEntity, CLValue, Digest, EntityAddr, InitiatorAddr, Key, KeyTag, Phase, - PublicKey, RuntimeArgs, StoredValue, TransactionHash, TransactionV1Hash, U512, + Account, AddressableEntity, CLValue, Digest, EntityAddr, Key, KeyTag, Phase, PublicKey, + RuntimeArgs, StoredValue, U512, }; #[cfg(test)] @@ -46,8 +45,8 @@ use crate::{ mint::{TransferRequest, TransferRequestArgs, TransferResult}, tagged_values::{TaggedValuesRequest, TaggedValuesResult}, AddressableEntityRequest, AddressableEntityResult, AuctionMethod, BalanceHoldError, - BalanceHoldRequest, BalanceHoldResult, BalanceRequest, BalanceResult, BidsRequest, - BidsResult, BlockRewardsError, BlockRewardsRequest, BlockRewardsResult, + BalanceHoldRequest, BalanceHoldResult, BalanceIdentifier, BalanceRequest, BalanceResult, + BidsRequest, BidsResult, BlockRewardsError, BlockRewardsRequest, BlockRewardsResult, EraValidatorsRequest, ExecutionResultsChecksumRequest, ExecutionResultsChecksumResult, FeeError, FeeRequest, FeeResult, FlushRequest, FlushResult, GenesisRequest, GenesisResult, InsufficientBalanceHandling, ProtocolUpgradeRequest, ProtocolUpgradeResult, PruneRequest, @@ -75,9 +74,7 @@ use crate::{ mint::Mint, protocol_upgrade::{ProtocolUpgradeError, ProtocolUpgrader}, runtime_native::{Id, RuntimeNative}, - transfer::{ - NewTransferTargetMode, TransferArgs, TransferError, TransferRuntimeArgsBuilder, - }, + transfer::{NewTransferTargetMode, TransferError, TransferRuntimeArgsBuilder}, }, tracking_copy::{TrackingCopy, TrackingCopyEntityExt, TrackingCopyError, TrackingCopyExt}, }; @@ -427,13 +424,6 @@ pub trait CommitProvider: StateProvider { }; } - let administrative_accounts = match request.administrative_accounts() { - Some(administrative_accounts) => administrative_accounts, - None => { - return FeeResult::Failure(FeeError::AdministrativeAccountsNotFound); - } - }; - let tc = match self.tracking_copy(state_hash) { Ok(Some(tracking_copy)) => Rc::new(RefCell::new(tracking_copy)), Ok(None) => return FeeResult::RootNotFound, @@ -442,182 +432,73 @@ pub trait CommitProvider: StateProvider { } }; - // need the accumulation purse - let entity_hash = match tc.borrow_mut().get_system_entity_registry() { - Ok(scr) => match scr.get(HANDLE_PAYMENT).copied() { - Some(entity_hash) => entity_hash, - None => { - return FeeResult::Failure(FeeError::RegistryEntryNotFound( - HANDLE_PAYMENT.to_string(), + let config = request.config(); + let protocol_version = request.protocol_version(); + let seed = { + let mut bytes = match request.block_time().into_bytes() { + Ok(bytes) => bytes, + Err(bre) => { + return FeeResult::Failure(FeeError::TrackingCopy( + TrackingCopyError::BytesRepr(bre), )) } - }, - Err(tce) => return FeeResult::Failure(FeeError::TrackingCopy(tce)), - }; - let named_keys = match tc - .borrow_mut() - .get_named_keys(EntityAddr::System(entity_hash.value())) - { - Ok(named_keys) => named_keys, - Err(tce) => return FeeResult::Failure(FeeError::TrackingCopy(tce)), - }; - - let accumulation_purse = match named_keys.get(ACCUMULATION_PURSE_KEY) { - Some(key) => { - if let Key::URef(uref) = key { - *uref - } else { + }; + match &mut protocol_version.into_bytes() { + Ok(next) => bytes.append(next), + Err(bre) => { return FeeResult::Failure(FeeError::TrackingCopy( - TrackingCopyError::UnexpectedKeyVariant(*key), - )); + TrackingCopyError::BytesRepr(*bre), + )) } - } - None => { - return FeeResult::Failure(FeeError::TrackingCopy( - TrackingCopyError::NamedKeyNotFound(ACCUMULATION_PURSE_KEY.to_string()), - )) - } - }; + }; - let protocol_version = request.protocol_version(); + Id::Seed(bytes) + }; - let accumulated_balance = { - let balance_req = BalanceRequest::from_purse( - state_hash, - protocol_version, - accumulation_purse, - BalanceHandling::Total, - ); - let balance_result = self.balance(balance_req); - match balance_result { - BalanceResult::RootNotFound => { - return FeeResult::RootNotFound; - } - BalanceResult::Failure(tce) => { - return FeeResult::Failure(FeeError::TrackingCopy(tce)); - } - BalanceResult::Success { - available_balance: motes, - .. - } => motes, + // this runtime uses the system's context + let mut runtime = match RuntimeNative::new_system_runtime( + config.clone(), + protocol_version, + seed, + Rc::clone(&tc), + Phase::System, + ) { + Ok(rt) => rt, + Err(tce) => { + return FeeResult::Failure(FeeError::TrackingCopy(tce)); } }; - let mut current_state_hash = state_hash; - let mut effects = Effects::new(); - let mut transfers = vec![]; - let recipient_count = U512::from(administrative_accounts.len()); - - // distribute fees to administrators - // this is basically just a series of transfers from the accumulated purse to - // configured accounts. this is a behavior used by some (but not all) private chains. - if let Some(fee_portion) = accumulated_balance.checked_div(recipient_count) { - if fee_portion.is_zero() { - // If there are no fees to be paid out, it is effectively noop - return FeeResult::Success { - effects: Effects::default(), - post_state_hash: state_hash, - transfers: vec![], - }; - } + let source = BalanceIdentifier::Accumulate; + let source_purse = match source.purse_uref(&mut tc.borrow_mut(), protocol_version) { + Ok(value) => value, + Err(tce) => return FeeResult::Failure(FeeError::TrackingCopy(tce)), + }; + // amount = None will distribute the full current balance of the accumulation purse + let result = runtime.distribute_accumulated_fees(source_purse, None); - let holds_epoch = request.holds_epoch(); - let system_account_key = PublicKey::System; - let id = { - let mut bytes = match holds_epoch.value().into_bytes() { - Ok(bytes) => bytes, - Err(bre) => { - return FeeResult::Failure(FeeError::TrackingCopy( - TrackingCopyError::BytesRepr(bre), - )) - } - }; - match &mut state_hash.into_bytes() { - Ok(more_bytes) => bytes.append(more_bytes), - Err(bre) => { + match result { + Ok(_) => { + let effects = tc.borrow_mut().effects(); + let transfers = runtime.into_transfers(); + let post_state_hash = match self.commit(state_hash, effects.clone()) { + Ok(post_state_hash) => post_state_hash, + Err(gse) => { return FeeResult::Failure(FeeError::TrackingCopy( - TrackingCopyError::BytesRepr(*bre), + TrackingCopyError::Storage(gse), )) } }; - - Id::Seed(bytes) - }; - - let config = request.config(); - let authorization_keys = { - let mut auth_keys = BTreeSet::new(); - auth_keys.insert(system_account_key.to_account_hash()); - auth_keys - }; - - // TODO: the transfer logic needs to be tweaked once Fraser's logic w/ version handling - // merges - let tmp_hash = match TransactionV1Hash::from_bytes(&id.seed()) { - Ok((hash, _rem)) => TransactionHash::V1(hash), - Err(bre) => { - return FeeResult::Failure(FeeError::TrackingCopy( - TrackingCopyError::BytesRepr(bre), - )) - } - }; - - for target in administrative_accounts { - let target_purse = match tc - .borrow_mut() - .get_addressable_entity_by_account_hash(protocol_version, *target) - { - Ok(entity) => entity.main_purse(), - Err(tce) => return FeeResult::Failure(FeeError::TrackingCopy(tce)), - }; - let args = TransferArgs::new( - Some(*target), - accumulation_purse, - target_purse, - fee_portion, - None, - ); - - let transfer_req = TransferRequest::new( - config.clone(), - current_state_hash, - holds_epoch, - protocol_version, - tmp_hash, - InitiatorAddr::from(system_account_key.clone()), - authorization_keys.clone(), - args, - ); - match self.transfer(transfer_req) { - TransferResult::RootNotFound => return FeeResult::RootNotFound, - TransferResult::Failure(transfer_error) => { - return FeeResult::Failure(FeeError::Transfer(transfer_error)) - } - TransferResult::Success { - effects: transfer_effects, - transfers: more_transfers, - } => match self.commit(current_state_hash, transfer_effects.clone()) { - Ok(post_state_hash) => { - current_state_hash = post_state_hash; - effects.append(transfer_effects); - transfers.extend(more_transfers); - } - Err(gse) => { - return FeeResult::Failure(FeeError::TrackingCopy( - TrackingCopyError::Storage(gse), - )) - } - }, + FeeResult::Success { + effects, + transfers, + post_state_hash, } } - - return FeeResult::Success { - post_state_hash: current_state_hash, - effects, - transfers, - }; + Err(hpe) => FeeResult::Failure(FeeError::TrackingCopy( + TrackingCopyError::SystemContract(system::Error::HandlePayment(hpe)), + )), } - FeeResult::Failure(FeeError::NoFeesDistributed) } } @@ -1077,13 +958,6 @@ pub trait StateProvider { holds_epoch, ) } - HandlePaymentMode::Distribute { source, amount } => { - let source_purse = match source.purse_uref(&mut tc.borrow_mut(), protocol_version) { - Ok(value) => value, - Err(tce) => return HandlePaymentResult::Failure(tce), - }; - runtime.distribute_accumulated_fees(source_purse, amount) - } HandlePaymentMode::Burn { source, amount } => { let source_purse = match source.purse_uref(&mut tc.borrow_mut(), protocol_version) { Ok(value) => value, @@ -1557,20 +1431,6 @@ pub trait StateProvider { let transfers = runtime.into_transfers(); - // TODO: i really don't want us to write this data into global state. - // perhaps we can put it into normal storage instead? - // let txn_info = TransactionInfo::new( - // request.transaction_hash(), - // transfers.clone(), - // request.initiator().clone(), - // entity.main_purse(), - // request.gas(), - // ); - // tc.borrow_mut().write( - // Key::TransactionInfo(txn_info.transaction_hash), - // StoredValue::TransactionInfo(txn_info), - // ); - let effects = tc.borrow_mut().effects(); TransferResult::Success { transfers, effects } From b2507b8afc9279e11d36af247f8f08d00ef3cb94 Mon Sep 17 00:00:00 2001 From: Karan Dhareshwar Date: Mon, 1 Apr 2024 12:37:51 -0500 Subject: [PATCH 64/70] Fix incorrect size estimation of v1 transaction --- types/src/transaction.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/src/transaction.rs b/types/src/transaction.rs index 37734b5c52..00b0aa0eb6 100644 --- a/types/src/transaction.rs +++ b/types/src/transaction.rs @@ -151,7 +151,7 @@ impl Transaction { pub fn size_estimate(&self) -> usize { match self { Transaction::Deploy(deploy) => deploy.serialized_length(), - Transaction::V1(v1) => v1.header().serialized_length(), + Transaction::V1(v1) => v1.serialized_length(), } } From 06223f75c4866f26508f1fb08de95ed7a5a64b38 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Mon, 1 Apr 2024 16:31:25 -0700 Subject: [PATCH 65/70] changed to progressive commit --- .../components/contract_runtime/operations.rs | 19 ++++++++++++++++++- node/src/components/contract_runtime/types.rs | 4 ---- storage/src/data_access_layer/mint.rs | 10 ++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 52e4cef78c..817d7dd1e9 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -194,6 +194,8 @@ pub fn execute_finalized_block( BalanceIdentifier::Payment } }; + state_root_hash = + scratch_state.commit(state_root_hash, pay_result.effects().clone())?; artifact_builder .with_wasm_v1_result(pay_result) .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; @@ -250,6 +252,8 @@ pub fn execute_finalized_block( runtime_args, )); let consumed = gas_limit; + state_root_hash = + scratch_state.commit(state_root_hash, transfer_result.effects().clone())?; artifact_builder .with_added_consumed(consumed) .with_transfer_result(transfer_result) @@ -273,6 +277,8 @@ pub fn execute_finalized_block( auction_method, )); let consumed = gas_limit; + state_root_hash = scratch_state + .commit(state_root_hash, bidding_result.effects().clone())?; artifact_builder .with_added_consumed(consumed) .with_bidding_result(bidding_result) @@ -300,6 +306,8 @@ pub fn execute_finalized_block( let wasm_v1_result = execution_engine_v1.execute(&scratch_state, wasm_v1_request); trace!(%transaction_hash, ?category, ?wasm_v1_result, "able to get wasm v1 result"); + state_root_hash = scratch_state + .commit(state_root_hash, wasm_v1_result.effects().clone())?; // note: consumed is scraped from wasm_v1_result along w/ other fields artifact_builder .with_wasm_v1_result(wasm_v1_result) @@ -329,6 +337,8 @@ pub fn execute_finalized_block( HandlePaymentMode::clear_holds(balance_identifier.clone(), holds_epoch), ); let handle_payment_result = scratch_state.handle_payment(handle_payment_request); + state_root_hash = scratch_state + .commit(state_root_hash, handle_payment_result.effects().clone())?; artifact_builder .with_handle_payment_result(&handle_payment_result) .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; @@ -342,6 +352,8 @@ pub fn execute_finalized_block( holds_epoch, insufficient_balance_handling, )); + state_root_hash = + scratch_state.commit(state_root_hash, hold_result.effects().clone())?; artifact_builder .with_balance_hold_result(&hold_result) .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; @@ -365,6 +377,8 @@ pub fn execute_finalized_block( ), ); let handle_payment_result = scratch_state.handle_payment(handle_payment_request); + state_root_hash = scratch_state + .commit(state_root_hash, handle_payment_result.effects().clone())?; artifact_builder .with_handle_payment_result(&handle_payment_result) .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; @@ -389,6 +403,8 @@ pub fn execute_finalized_block( ), ); let handle_payment_result = scratch_state.handle_payment(handle_payment_request); + state_root_hash = scratch_state + .commit(state_root_hash, handle_payment_result.effects().clone())?; artifact_builder .with_handle_payment_result(&handle_payment_result) .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; @@ -403,13 +419,14 @@ pub fn execute_finalized_block( HandlePaymentMode::burn(balance_identifier, Some(consumed)), ); let handle_payment_result = scratch_state.handle_payment(handle_payment_request); + state_root_hash = scratch_state + .commit(state_root_hash, handle_payment_result.effects().clone())?; artifact_builder .with_handle_payment_result(&handle_payment_result) .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; } } - scratch_state.commit(state_root_hash, artifact_builder.effects())?; if let Some(metrics) = metrics.as_ref() { metrics .commit_effects diff --git a/node/src/components/contract_runtime/types.rs b/node/src/components/contract_runtime/types.rs index 3af31e5d14..67ac8ee293 100644 --- a/node/src/components/contract_runtime/types.rs +++ b/node/src/components/contract_runtime/types.rs @@ -94,10 +94,6 @@ impl ExecutionArtifactBuilder { } } - pub fn effects(&self) -> Effects { - self.effects.clone() - } - pub fn consumed(&self) -> U512 { self.consumed.value() } diff --git a/storage/src/data_access_layer/mint.rs b/storage/src/data_access_layer/mint.rs index d6a9f15f8f..fe0f32186b 100644 --- a/storage/src/data_access_layer/mint.rs +++ b/storage/src/data_access_layer/mint.rs @@ -158,3 +158,13 @@ pub enum TransferResult { /// Transfer failed Failure(TransferError), } + +impl TransferResult { + /// Returns the effects, if any. + pub fn effects(&self) -> Effects { + match self { + TransferResult::RootNotFound | TransferResult::Failure(_) => Effects::new(), + TransferResult::Success { effects, .. } => effects.clone(), + } + } +} From 36dc7bf9f2198b7c27724a5634f28b0dff1dfe0a Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Tue, 2 Apr 2024 08:40:14 -0700 Subject: [PATCH 66/70] merge fixes --- binary_port/src/payload_type.rs | 2 +- node/src/components/binary_port.rs | 6 +++--- node/src/reactor/main_reactor/tests/binary_port.rs | 14 ++++---------- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/binary_port/src/payload_type.rs b/binary_port/src/payload_type.rs index ce89e1a6d0..a68de02611 100644 --- a/binary_port/src/payload_type.rs +++ b/binary_port/src/payload_type.rs @@ -23,7 +23,7 @@ use crate::{ speculative_execution_result::SpeculativeExecutionResult, type_wrappers::{ ConsensusStatus, ConsensusValidatorChanges, GetTrieFullResult, LastProgress, NetworkName, - ReactorStateName, TransactionWithExecutionInfo, Uptime, + ReactorStateName, }, DictionaryQueryResult, RecordId, TransactionWithExecutionInfo, Uptime, }; diff --git a/node/src/components/binary_port.rs b/node/src/components/binary_port.rs index 651e7a0099..8ae69e6c3f 100644 --- a/node/src/components/binary_port.rs +++ b/node/src/components/binary_port.rs @@ -11,9 +11,9 @@ use std::{convert::TryFrom, net::SocketAddr, sync::Arc}; use bytes::Bytes; use casper_binary_port::{ BinaryRequest, BinaryRequestHeader, BinaryRequestTag, BinaryResponse, BinaryResponseAndRequest, - DictionaryItemIdentifier, ErrorCode, GetRequest, GetTrieFullResult, GlobalStateQueryResult, - GlobalStateRequest, InformationRequest, InformationRequestTag, NodeStatus, PayloadType, - ReactorStateName, RecordId, TransactionWithExecutionInfo, + DictionaryItemIdentifier, DictionaryQueryResult, ErrorCode, GetRequest, GetTrieFullResult, + GlobalStateQueryResult, GlobalStateRequest, InformationRequest, InformationRequestTag, + NodeStatus, PayloadType, ReactorStateName, RecordId, TransactionWithExecutionInfo, }; use casper_storage::{ data_access_layer::{ diff --git a/node/src/reactor/main_reactor/tests/binary_port.rs b/node/src/reactor/main_reactor/tests/binary_port.rs index 4dc9b869c8..127cd16f91 100644 --- a/node/src/reactor/main_reactor/tests/binary_port.rs +++ b/node/src/reactor/main_reactor/tests/binary_port.rs @@ -8,21 +8,15 @@ use std::{ use casper_binary_port::{ BinaryRequest, BinaryRequestHeader, BinaryResponse, BinaryResponseAndRequest, ConsensusStatus, - ConsensusValidatorChanges, DictionaryItemIdentifier, ErrorCode, GetRequest, GetTrieFullResult, - GlobalStateQueryResult, GlobalStateRequest, InformationRequest, InformationRequestTag, - LastProgress, NetworkName, NodeStatus, PayloadType, ReactorStateName, RecordId, Uptime, + ConsensusValidatorChanges, DictionaryItemIdentifier, DictionaryQueryResult, ErrorCode, + GetRequest, GetTrieFullResult, GlobalStateQueryResult, GlobalStateRequest, InformationRequest, + InformationRequestTag, LastProgress, NetworkName, NodeStatus, PayloadType, ReactorStateName, + RecordId, Uptime, }; use casper_storage::global_state::state::CommitProvider; use casper_types::{ account::{AccountHash, ActionThresholds, AssociatedKeys}, addressable_entity::{NamedKeyAddr, NamedKeyValue}, - binary_port::{ - BinaryRequest, BinaryRequestHeader, BinaryResponse, BinaryResponseAndRequest, - ConsensusStatus, ConsensusValidatorChanges, DictionaryItemIdentifier, - DictionaryQueryResult, ErrorCode, GetRequest, GetTrieFullResult, GlobalStateQueryResult, - GlobalStateRequest, InformationRequest, InformationRequestTag, LastProgress, NetworkName, - NodeStatus, PayloadType, ReactorStateName, RecordId, Uptime, - }, bytesrepr::{FromBytes, ToBytes}, execution::{Effects, TransformKindV2, TransformV2}, testing::TestRng, From 7edc83f171f795e26f50826f3a40a348c6bd0595 Mon Sep 17 00:00:00 2001 From: Alexandru Sardan Date: Mon, 1 Apr 2024 15:43:36 +0000 Subject: [PATCH 67/70] reactor/tests: add tests for burning and paying fees to proposer Signed-off-by: Alexandru Sardan --- node/src/reactor/main_reactor/tests.rs | 15 + .../main_reactor/tests/transactions.rs | 509 +++++++++++++++++- 2 files changed, 521 insertions(+), 3 deletions(-) diff --git a/node/src/reactor/main_reactor/tests.rs b/node/src/reactor/main_reactor/tests.rs index a5e7b7bd30..b0ea8993ed 100644 --- a/node/src/reactor/main_reactor/tests.rs +++ b/node/src/reactor/main_reactor/tests.rs @@ -146,6 +146,21 @@ impl ConfigsOverride { self.balance_hold_interval_override = Some(balance_hold_interval); self } + + fn with_min_gas_price(mut self, min_gas_price: u8) -> Self { + self.min_gas_price = min_gas_price; + self + } + + fn with_max_gas_price(mut self, max_gas_price: u8) -> Self { + self.max_gas_price = max_gas_price; + self + } + + fn with_minimum_era_height(mut self, minimum_era_height: u64) -> Self { + self.minimum_era_height = minimum_era_height; + self + } } impl Default for ConfigsOverride { diff --git a/node/src/reactor/main_reactor/tests/transactions.rs b/node/src/reactor/main_reactor/tests/transactions.rs index c4a8c3993c..2b03ea7a60 100644 --- a/node/src/reactor/main_reactor/tests/transactions.rs +++ b/node/src/reactor/main_reactor/tests/transactions.rs @@ -116,7 +116,39 @@ fn get_entity(fixture: &mut TestFixture, account_key: PublicKey) -> AddressableE )) } -fn assert_exec_result_fixed_cost( +fn get_total_supply(fixture: &mut TestFixture, block_height: Option) -> U512 { + let (_node_id, runner) = fixture.network.nodes().iter().next().unwrap(); + let protocol_version = fixture.chainspec.protocol_version(); + let height = block_height.unwrap_or( + runner + .main_reactor() + .storage() + .highest_complete_block_height() + .expect("missing highest completed block"), + ); + let state_hash = *runner + .main_reactor() + .storage() + .read_block_header_by_height(height, true) + .expect("failure to read block header") + .unwrap() + .state_root_hash(); + + let total_supply_req = TotalSupplyRequest::new(state_hash, protocol_version); + let result = runner + .main_reactor() + .contract_runtime() + .data_access_layer() + .total_supply(total_supply_req); + + if let TotalSupplyResult::Success { total_supply } = result { + return total_supply; + } else { + panic!("Can't get total supply") + } +} + +fn assert_exec_result_cost( exec_result: ExecutionResult, expected_cost: U512, expected_consumed_gas: Gas, @@ -187,7 +219,7 @@ async fn transfer_cost_fixed_price_no_fee_no_refund() { .into(); let expected_transfer_cost = expected_transfer_gas; // since we set gas_price_tolerance to 1. - assert_exec_result_fixed_cost( + assert_exec_result_cost( exec_result, expected_transfer_cost, Gas::new(expected_transfer_gas), @@ -225,7 +257,7 @@ async fn transfer_cost_fixed_price_no_fee_no_refund() { assert_eq!( charlie_balance .motes() - .expect("Expected Alice to have a balance") + .expect("Expected Charlie to have a balance") .clone(), TRANSFER_AMOUNT.into() ); @@ -284,3 +316,474 @@ async fn should_accept_transfer_without_id() { assert!(exec_result_is_success(&result)) } + +#[tokio::test] +async fn failed_transfer_cost_fixed_price_no_fee_no_refund() { + let initial_stakes = InitialStakes::FromVec(vec![u128::MAX, 1]); + + let config = ConfigsOverride::default() + .with_pricing_handling(PricingHandling::Fixed) + .with_refund_handling(RefundHandling::NoRefund) + .with_fee_handling(FeeHandling::NoFee) + .with_balance_hold_interval(TimeDiff::from_seconds(5)); + + let mut fixture = TestFixture::new(initial_stakes, Some(config)).await; + + let alice_secret_key = Arc::clone(&fixture.node_contexts[0].secret_key); + let charlie_secret_key = Arc::new(SecretKey::random(&mut fixture.rng)); + let charlie_public_key = PublicKey::from(&*charlie_secret_key); + + // Wait for all nodes to complete era 0. + fixture.run_until_consensus_in_era(ERA_ONE, ONE_MIN).await; + + let transfer_amount = fixture + .chainspec + .transaction_config + .native_transfer_minimum_motes + + 100; + + // Transfer some token to Charlie. + let (_txn_hash, _block, exec_result) = transfer_to_account( + &mut fixture, + transfer_amount, + PublicKey::from(&*charlie_secret_key), + &alice_secret_key, + PricingMode::Fixed { + gas_price_tolerance: 1, + }, + None, + ) + .await; + assert!(exec_result_is_success(&exec_result)); + + // Attempt to transfer more than Charlie has to Bob. + let bob_secret_key = Arc::new(SecretKey::random(&mut fixture.rng)); + let (_txn_hash, block_height, exec_result) = transfer_to_account( + &mut fixture, + transfer_amount + 100, + PublicKey::from(&*bob_secret_key), + &charlie_secret_key, + PricingMode::Fixed { + gas_price_tolerance: 1, + }, + None, + ) + .await; + assert!(!exec_result_is_success(&exec_result)); // transaction should have failed. + + let expected_transfer_gas = fixture + .chainspec + .system_costs_config + .mint_costs() + .transfer + .into(); + let expected_transfer_cost = expected_transfer_gas; // since we set gas_price_tolerance to 1. + + assert_exec_result_cost( + exec_result, + expected_transfer_cost, + Gas::new(expected_transfer_gas), + ); + + // Even though the transaction failed, a hold must still be in place for the transfer cost. + let charlie_available_balance = + get_balance(&mut fixture, &charlie_public_key, Some(block_height), false); + assert_eq!( + charlie_available_balance + .motes() + .expect("Expected Charlie to have a balance") + .clone(), + U512::from(transfer_amount) - expected_transfer_cost + ); +} + +#[tokio::test] +async fn transfer_cost_classic_price_no_fee_no_refund() { + const TRANSFER_AMOUNT: u64 = 30_000_000_000; + const MIN_GAS_PRICE: u8 = 5; + const MAX_GAS_PRICE: u8 = MIN_GAS_PRICE * 2; + + let initial_stakes = InitialStakes::FromVec(vec![u128::MAX, 1]); + + let config = ConfigsOverride::default() + .with_pricing_handling(PricingHandling::Classic) + .with_refund_handling(RefundHandling::NoRefund) + .with_fee_handling(FeeHandling::NoFee) + .with_balance_hold_interval(TimeDiff::from_seconds(5)) + .with_min_gas_price(MIN_GAS_PRICE) + .with_max_gas_price(MAX_GAS_PRICE); + + let mut fixture = TestFixture::new(initial_stakes, Some(config)).await; + + let alice_secret_key = Arc::clone(&fixture.node_contexts[0].secret_key); + let alice_public_key = PublicKey::from(&*alice_secret_key); + let charlie_secret_key = Arc::new(SecretKey::random(&mut fixture.rng)); + let charlie_public_key = PublicKey::from(&*charlie_secret_key); + + // Wait for all nodes to complete era 0. + fixture.run_until_consensus_in_era(ERA_ONE, ONE_MIN).await; + + let alice_initial_balance = *get_balance(&mut fixture, &alice_public_key, None, true) + .motes() + .expect("Expected Alice to have a balance."); + + const TRANSFER_GAS: u64 = 100; + + // This transaction should be included since the tolerance is above the min gas price. + let (_txn_hash, block_height, exec_result) = transfer_to_account( + &mut fixture, + TRANSFER_AMOUNT, + PublicKey::from(&*charlie_secret_key), + &alice_secret_key, + PricingMode::Classic { + payment_amount: TRANSFER_GAS, + gas_price_tolerance: MIN_GAS_PRICE + 1, + standard_payment: true, + }, + None, + ) + .await; + + let expected_transfer_cost = TRANSFER_GAS * MIN_GAS_PRICE as u64; + + assert!(exec_result_is_success(&exec_result)); // transaction should have succeeded. + assert_exec_result_cost( + exec_result, + expected_transfer_cost.into(), + Gas::new(TRANSFER_GAS), + ); + + let alice_available_balance = + get_balance(&mut fixture, &alice_public_key, Some(block_height), false); + let alice_total_balance = + get_balance(&mut fixture, &alice_public_key, Some(block_height), true); + + // since FeeHandling is set to NoFee, we expect that there's a hold on Alice's balance for the + // cost of the transfer. The total balance of Alice now should be the initial balance - the + // amount transfered to Charlie. + let alice_expected_total_balance = alice_initial_balance - TRANSFER_AMOUNT; + // The available balance is the initial balance - the amount transferred to Charlie - the hold + // for the transfer cost. + let alice_expected_available_balance = alice_expected_total_balance - expected_transfer_cost; + + assert_eq!( + alice_total_balance + .motes() + .expect("Expected Alice to have a balance") + .clone(), + alice_expected_total_balance + ); + assert_eq!( + alice_available_balance + .motes() + .expect("Expected Alice to have a balance") + .clone(), + alice_expected_available_balance + ); + + let charlie_balance = get_balance(&mut fixture, &charlie_public_key, Some(block_height), false); + assert_eq!( + charlie_balance + .motes() + .expect("Expected Charlie to have a balance") + .clone(), + TRANSFER_AMOUNT.into() + ); + + // Check if the hold is released. + let hold_release_block_height = block_height + 8; // Block time is 1s. + fixture + .run_until_block_height(hold_release_block_height, ONE_MIN) + .await; + + let alice_available_balance = get_balance( + &mut fixture, + &alice_public_key, + Some(hold_release_block_height), + false, + ); + let alice_total_balance = get_balance( + &mut fixture, + &alice_public_key, + Some(hold_release_block_height), + true, + ); + + assert_eq!(alice_available_balance.motes(), alice_total_balance.motes()); +} + +#[tokio::test] +#[should_panic = "within 10 seconds"] +async fn transaction_with_low_threshold_should_not_get_included() { + const TRANSFER_AMOUNT: u64 = 30_000_000_000; + const MIN_GAS_PRICE: u8 = 5; + const MAX_GAS_PRICE: u8 = MIN_GAS_PRICE * 2; + + let initial_stakes = InitialStakes::FromVec(vec![u128::MAX, 1]); + + let config = ConfigsOverride::default() + .with_pricing_handling(PricingHandling::Classic) + .with_refund_handling(RefundHandling::NoRefund) + .with_fee_handling(FeeHandling::NoFee) + .with_balance_hold_interval(TimeDiff::from_seconds(5)) + .with_min_gas_price(MIN_GAS_PRICE) + .with_max_gas_price(MAX_GAS_PRICE); + + let mut fixture = TestFixture::new(initial_stakes, Some(config)).await; + + let alice_secret_key = Arc::clone(&fixture.node_contexts[0].secret_key); + let charlie_secret_key = Arc::new(SecretKey::random(&mut fixture.rng)); + + // Wait for all nodes to complete era 0. + fixture.run_until_consensus_in_era(ERA_ONE, ONE_MIN).await; + + // This transaction should NOT be included since the tolerance is below the min gas price. + let (_, _, _) = transfer_to_account( + &mut fixture, + TRANSFER_AMOUNT, + PublicKey::from(&*charlie_secret_key), + &alice_secret_key, + PricingMode::Classic { + payment_amount: 1000, + gas_price_tolerance: MIN_GAS_PRICE - 1, + standard_payment: true, + }, + None, + ) + .await; +} + +#[tokio::test] +async fn transfer_fee_is_burnt_no_refund() { + const MIN_GAS_PRICE: u8 = 5; + const MAX_GAS_PRICE: u8 = MIN_GAS_PRICE; + + let initial_stakes = InitialStakes::FromVec(vec![u128::MAX, 1]); + + let config = ConfigsOverride::default() + .with_minimum_era_height(5) // make the era longer so that the transaction doesn't land in the switch block. + .with_pricing_handling(PricingHandling::Fixed) + .with_refund_handling(RefundHandling::NoRefund) + .with_fee_handling(FeeHandling::Burn) + .with_balance_hold_interval(TimeDiff::from_seconds(5)) + .with_min_gas_price(MIN_GAS_PRICE) + .with_max_gas_price(MAX_GAS_PRICE); + + let mut fixture = TestFixture::new(initial_stakes, Some(config)).await; + + let alice_secret_key = Arc::clone(&fixture.node_contexts[0].secret_key); + let alice_public_key = PublicKey::from(&*alice_secret_key); + let charlie_secret_key = Arc::new(SecretKey::random(&mut fixture.rng)); + let charlie_public_key = PublicKey::from(&*charlie_secret_key); + + // Wait for all nodes to complete era 0. + fixture.run_until_consensus_in_era(ERA_ONE, ONE_MIN).await; + + let initial_total_supply = get_total_supply(&mut fixture, None); + + let alice_initial_balance = *get_balance(&mut fixture, &alice_public_key, None, true) + .motes() + .expect("Expected Alice to have a balance."); + + let transfer_amount = fixture + .chainspec + .transaction_config + .native_transfer_minimum_motes + + 100; + + let (_txn_hash, block_height, exec_result) = transfer_to_account( + &mut fixture, + transfer_amount, + PublicKey::from(&*charlie_secret_key), + &alice_secret_key, + PricingMode::Fixed { + gas_price_tolerance: MIN_GAS_PRICE, + }, + None, + ) + .await; + + assert!(exec_result_is_success(&exec_result)); // transaction should have succeeded. + + let expected_transfer_gas: u64 = fixture + .chainspec + .system_costs_config + .mint_costs() + .transfer + .into(); + let expected_transfer_cost = expected_transfer_gas * MIN_GAS_PRICE as u64; + assert_exec_result_cost( + exec_result, + expected_transfer_cost.into(), + expected_transfer_gas.into(), + ); + + // The fees should have been burnt. So expect the total supply should have been reduced by the + // fee that was burnt. + let total_supply_after_transaction = get_total_supply(&mut fixture, Some(block_height)); + assert_eq!( + total_supply_after_transaction, + initial_total_supply - expected_transfer_cost + ); + + let alice_available_balance = + get_balance(&mut fixture, &alice_public_key, Some(block_height), false); + let alice_total_balance = + get_balance(&mut fixture, &alice_public_key, Some(block_height), true); + + let alice_expected_total_balance = + alice_initial_balance - transfer_amount - expected_transfer_cost; + let alice_expected_available_balance = alice_expected_total_balance; + + let charlie_balance = get_balance(&mut fixture, &charlie_public_key, Some(block_height), false); + assert_eq!( + charlie_balance + .motes() + .expect("Expected Charlie to have a balance") + .clone(), + transfer_amount.into() + ); + + assert_eq!( + alice_available_balance + .motes() + .expect("Expected Alice to have a balance") + .clone(), + alice_expected_available_balance + ); + + assert_eq!( + alice_total_balance + .motes() + .expect("Expected Alice to have a balance") + .clone(), + alice_expected_total_balance + ); +} + +#[tokio::test] +async fn fee_is_payed_to_proposer_no_refund() { + const MIN_GAS_PRICE: u8 = 5; + const MAX_GAS_PRICE: u8 = MIN_GAS_PRICE; + + let initial_stakes = InitialStakes::FromVec(vec![u128::MAX, 1]); // Node 0 is effectively guaranteed to be the proposer. + + let config = ConfigsOverride::default() + .with_minimum_era_height(5) // make the era longer so that the transaction doesn't land in the switch block. + .with_pricing_handling(PricingHandling::Fixed) + .with_refund_handling(RefundHandling::NoRefund) + .with_fee_handling(FeeHandling::PayToProposer) + .with_balance_hold_interval(TimeDiff::from_seconds(5)) + .with_min_gas_price(MIN_GAS_PRICE) + .with_max_gas_price(MAX_GAS_PRICE); + + let mut fixture = TestFixture::new(initial_stakes, Some(config)).await; + + let alice_secret_key = Arc::clone(&fixture.node_contexts[0].secret_key); + let alice_public_key = PublicKey::from(&*alice_secret_key); + let bob_secret_key = Arc::clone(&fixture.node_contexts[1].secret_key); + let bob_public_key = PublicKey::from(&*bob_secret_key); + let charlie_secret_key = Arc::new(SecretKey::random(&mut fixture.rng)); + let charlie_public_key = PublicKey::from(&*charlie_secret_key); + + // Wait for all nodes to complete era 0. + fixture.run_until_consensus_in_era(ERA_ONE, ONE_MIN).await; + + let bob_initial_balance = *get_balance(&mut fixture, &bob_public_key, None, true) + .motes() + .expect("Expected Bob to have a balance."); + let alice_initial_balance = *get_balance(&mut fixture, &alice_public_key, None, true) + .motes() + .expect("Expected Alice to have a balance."); + + let transfer_amount = fixture + .chainspec + .transaction_config + .native_transfer_minimum_motes + + 100; + + let (_txn_hash, block_height, exec_result) = transfer_to_account( + &mut fixture, + transfer_amount, + PublicKey::from(&*charlie_secret_key), + &bob_secret_key, + PricingMode::Fixed { + gas_price_tolerance: MIN_GAS_PRICE, + }, + None, + ) + .await; + + assert!(exec_result_is_success(&exec_result)); // transaction should have succeeded. + + let expected_transfer_gas: u64 = fixture + .chainspec + .system_costs_config + .mint_costs() + .transfer + .into(); + let expected_transfer_cost = expected_transfer_gas * MIN_GAS_PRICE as u64; + assert_exec_result_cost( + exec_result, + expected_transfer_cost.into(), + expected_transfer_gas.into(), + ); + + let bob_available_balance = + get_balance(&mut fixture, &bob_public_key, Some(block_height), false); + let bob_total_balance = get_balance(&mut fixture, &bob_public_key, Some(block_height), true); + + let alice_available_balance = + get_balance(&mut fixture, &alice_public_key, Some(block_height), false); + let alice_total_balance = + get_balance(&mut fixture, &alice_public_key, Some(block_height), true); + + // since Alice was the proposer of the block, it should get back the transfer fee since + // FeeHandling is set to PayToProposer. + let bob_expected_total_balance = bob_initial_balance - transfer_amount - expected_transfer_cost; + let bob_expected_available_balance = bob_expected_total_balance; + + let alice_expected_total_balance = alice_initial_balance + expected_transfer_cost; + let alice_expected_available_balance = alice_expected_total_balance; + + let charlie_balance = get_balance(&mut fixture, &charlie_public_key, Some(block_height), false); + assert_eq!( + charlie_balance + .motes() + .expect("Expected Charlie to have a balance") + .clone(), + transfer_amount.into() + ); + + assert_eq!( + bob_available_balance + .motes() + .expect("Expected Bob to have a balance") + .clone(), + bob_expected_available_balance + ); + + assert_eq!( + bob_total_balance + .motes() + .expect("Expected Bob to have a balance") + .clone(), + bob_expected_total_balance + ); + + assert_eq!( + alice_available_balance + .motes() + .expect("Expected Bob to have a balance") + .clone(), + alice_expected_available_balance + ); + + assert_eq!( + alice_total_balance + .motes() + .expect("Expected Bob to have a balance") + .clone(), + alice_expected_total_balance + ); +} From 041fd5943d1f3ed5d9cbbd80b574ad57213161b9 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Tue, 2 Apr 2024 11:49:32 -0700 Subject: [PATCH 68/70] merge lint --- node/src/reactor/main_reactor/tests/transactions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/src/reactor/main_reactor/tests/transactions.rs b/node/src/reactor/main_reactor/tests/transactions.rs index 2b03ea7a60..cce04b19ff 100644 --- a/node/src/reactor/main_reactor/tests/transactions.rs +++ b/node/src/reactor/main_reactor/tests/transactions.rs @@ -142,7 +142,7 @@ fn get_total_supply(fixture: &mut TestFixture, block_height: Option) -> U51 .total_supply(total_supply_req); if let TotalSupplyResult::Success { total_supply } = result { - return total_supply; + total_supply } else { panic!("Can't get total supply") } From 15312163ebfda75f48992139791bf1e31071429f Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Wed, 3 Apr 2024 10:46:01 -0700 Subject: [PATCH 69/70] disabling refund test --- .../main_reactor/tests/transactions.rs | 214 +++++++++--------- 1 file changed, 107 insertions(+), 107 deletions(-) diff --git a/node/src/reactor/main_reactor/tests/transactions.rs b/node/src/reactor/main_reactor/tests/transactions.rs index cce04b19ff..3e31ea4820 100644 --- a/node/src/reactor/main_reactor/tests/transactions.rs +++ b/node/src/reactor/main_reactor/tests/transactions.rs @@ -553,113 +553,113 @@ async fn transaction_with_low_threshold_should_not_get_included() { .await; } -#[tokio::test] -async fn transfer_fee_is_burnt_no_refund() { - const MIN_GAS_PRICE: u8 = 5; - const MAX_GAS_PRICE: u8 = MIN_GAS_PRICE; - - let initial_stakes = InitialStakes::FromVec(vec![u128::MAX, 1]); - - let config = ConfigsOverride::default() - .with_minimum_era_height(5) // make the era longer so that the transaction doesn't land in the switch block. - .with_pricing_handling(PricingHandling::Fixed) - .with_refund_handling(RefundHandling::NoRefund) - .with_fee_handling(FeeHandling::Burn) - .with_balance_hold_interval(TimeDiff::from_seconds(5)) - .with_min_gas_price(MIN_GAS_PRICE) - .with_max_gas_price(MAX_GAS_PRICE); - - let mut fixture = TestFixture::new(initial_stakes, Some(config)).await; - - let alice_secret_key = Arc::clone(&fixture.node_contexts[0].secret_key); - let alice_public_key = PublicKey::from(&*alice_secret_key); - let charlie_secret_key = Arc::new(SecretKey::random(&mut fixture.rng)); - let charlie_public_key = PublicKey::from(&*charlie_secret_key); - - // Wait for all nodes to complete era 0. - fixture.run_until_consensus_in_era(ERA_ONE, ONE_MIN).await; - - let initial_total_supply = get_total_supply(&mut fixture, None); - - let alice_initial_balance = *get_balance(&mut fixture, &alice_public_key, None, true) - .motes() - .expect("Expected Alice to have a balance."); - - let transfer_amount = fixture - .chainspec - .transaction_config - .native_transfer_minimum_motes - + 100; - - let (_txn_hash, block_height, exec_result) = transfer_to_account( - &mut fixture, - transfer_amount, - PublicKey::from(&*charlie_secret_key), - &alice_secret_key, - PricingMode::Fixed { - gas_price_tolerance: MIN_GAS_PRICE, - }, - None, - ) - .await; - - assert!(exec_result_is_success(&exec_result)); // transaction should have succeeded. - - let expected_transfer_gas: u64 = fixture - .chainspec - .system_costs_config - .mint_costs() - .transfer - .into(); - let expected_transfer_cost = expected_transfer_gas * MIN_GAS_PRICE as u64; - assert_exec_result_cost( - exec_result, - expected_transfer_cost.into(), - expected_transfer_gas.into(), - ); - - // The fees should have been burnt. So expect the total supply should have been reduced by the - // fee that was burnt. - let total_supply_after_transaction = get_total_supply(&mut fixture, Some(block_height)); - assert_eq!( - total_supply_after_transaction, - initial_total_supply - expected_transfer_cost - ); - - let alice_available_balance = - get_balance(&mut fixture, &alice_public_key, Some(block_height), false); - let alice_total_balance = - get_balance(&mut fixture, &alice_public_key, Some(block_height), true); - - let alice_expected_total_balance = - alice_initial_balance - transfer_amount - expected_transfer_cost; - let alice_expected_available_balance = alice_expected_total_balance; - - let charlie_balance = get_balance(&mut fixture, &charlie_public_key, Some(block_height), false); - assert_eq!( - charlie_balance - .motes() - .expect("Expected Charlie to have a balance") - .clone(), - transfer_amount.into() - ); - - assert_eq!( - alice_available_balance - .motes() - .expect("Expected Alice to have a balance") - .clone(), - alice_expected_available_balance - ); - - assert_eq!( - alice_total_balance - .motes() - .expect("Expected Alice to have a balance") - .clone(), - alice_expected_total_balance - ); -} +// #[tokio::test] +// async fn transfer_fee_is_burnt_no_refund() { +// const MIN_GAS_PRICE: u8 = 5; +// const MAX_GAS_PRICE: u8 = MIN_GAS_PRICE; +// +// let initial_stakes = InitialStakes::FromVec(vec![u128::MAX, 1]); +// +// let config = ConfigsOverride::default() +// .with_minimum_era_height(5) // make the era longer so that the transaction doesn't land in the switch block. +// .with_pricing_handling(PricingHandling::Fixed) +// .with_refund_handling(RefundHandling::NoRefund) +// .with_fee_handling(FeeHandling::Burn) +// .with_balance_hold_interval(TimeDiff::from_seconds(5)) +// .with_min_gas_price(MIN_GAS_PRICE) +// .with_max_gas_price(MAX_GAS_PRICE); +// +// let mut fixture = TestFixture::new(initial_stakes, Some(config)).await; +// +// let alice_secret_key = Arc::clone(&fixture.node_contexts[0].secret_key); +// let alice_public_key = PublicKey::from(&*alice_secret_key); +// let charlie_secret_key = Arc::new(SecretKey::random(&mut fixture.rng)); +// let charlie_public_key = PublicKey::from(&*charlie_secret_key); +// +// // Wait for all nodes to complete era 0. +// fixture.run_until_consensus_in_era(ERA_ONE, ONE_MIN).await; +// +// let initial_total_supply = get_total_supply(&mut fixture, None); +// +// let alice_initial_balance = *get_balance(&mut fixture, &alice_public_key, None, true) +// .motes() +// .expect("Expected Alice to have a balance."); +// +// let transfer_amount = fixture +// .chainspec +// .transaction_config +// .native_transfer_minimum_motes +// + 100; +// +// let (_txn_hash, block_height, exec_result) = transfer_to_account( +// &mut fixture, +// transfer_amount, +// PublicKey::from(&*charlie_secret_key), +// &alice_secret_key, +// PricingMode::Fixed { +// gas_price_tolerance: MIN_GAS_PRICE, +// }, +// None, +// ) +// .await; +// +// assert!(exec_result_is_success(&exec_result)); // transaction should have succeeded. +// +// let expected_transfer_gas: u64 = fixture +// .chainspec +// .system_costs_config +// .mint_costs() +// .transfer +// .into(); +// let expected_transfer_cost = expected_transfer_gas * MIN_GAS_PRICE as u64; +// assert_exec_result_cost( +// exec_result, +// expected_transfer_cost.into(), +// expected_transfer_gas.into(), +// ); +// +// // The fees should have been burnt. So expect the total supply should have been reduced by the +// // fee that was burnt. +// let total_supply_after_transaction = get_total_supply(&mut fixture, Some(block_height)); +// assert_eq!( +// total_supply_after_transaction, +// initial_total_supply - expected_transfer_cost +// ); +// +// let alice_available_balance = +// get_balance(&mut fixture, &alice_public_key, Some(block_height), false); +// let alice_total_balance = +// get_balance(&mut fixture, &alice_public_key, Some(block_height), true); +// +// let alice_expected_total_balance = +// alice_initial_balance - transfer_amount - expected_transfer_cost; +// let alice_expected_available_balance = alice_expected_total_balance; +// +// let charlie_balance = get_balance(&mut fixture, &charlie_public_key, Some(block_height), false); +// assert_eq!( +// charlie_balance +// .motes() +// .expect("Expected Charlie to have a balance") +// .clone(), +// transfer_amount.into() +// ); +// +// assert_eq!( +// alice_available_balance +// .motes() +// .expect("Expected Alice to have a balance") +// .clone(), +// alice_expected_available_balance +// ); +// +// assert_eq!( +// alice_total_balance +// .motes() +// .expect("Expected Alice to have a balance") +// .clone(), +// alice_expected_total_balance +// ); +// } #[tokio::test] async fn fee_is_payed_to_proposer_no_refund() { From c502a1c1979547f4c0b2310c65b5950f97a823d9 Mon Sep 17 00:00:00 2001 From: Ed Hastings Date: Wed, 3 Apr 2024 12:18:32 -0700 Subject: [PATCH 70/70] fixing refund test --- Makefile | 2 +- .../components/contract_runtime/operations.rs | 12 +- .../main_reactor/tests/transactions.rs | 246 ++++++++++-------- 3 files changed, 140 insertions(+), 120 deletions(-) diff --git a/Makefile b/Makefile index e15f0f483a..e0e8810b70 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,7 @@ lint-smart-contracts: .PHONY: audit-rs audit-rs: - $(CARGO) audit --ignore RUSTSEC-2024-0006 --ignore RUSTSEC-2024-0003 --ignore RUSTSEC-2024-0019 + $(CARGO) audit --ignore RUSTSEC-2024-0006 --ignore RUSTSEC-2024-0003 --ignore RUSTSEC-2024-0019 --ignore RUSTSEC-2024-0332 .PHONY: audit-as audit-as: diff --git a/node/src/components/contract_runtime/operations.rs b/node/src/components/contract_runtime/operations.rs index 817d7dd1e9..52e45f6609 100644 --- a/node/src/components/contract_runtime/operations.rs +++ b/node/src/components/contract_runtime/operations.rs @@ -25,7 +25,7 @@ use casper_types::{ execution::{Effects, ExecutionResult, TransformKindV2, TransformV2}, system::mint::BalanceHoldAddrTag, BlockHeader, BlockTime, BlockV2, CLValue, CategorizedTransaction, Chainspec, ChecksumRegistry, - Digest, EraEndV2, EraId, FeeHandling, Gas, GasLimited, HoldsEpoch, Key, ProtocolVersion, + Digest, EraEndV2, EraId, FeeHandling, Gas, GasLimited, HoldsEpoch, Key, Motes, ProtocolVersion, PublicKey, Transaction, TransactionCategory, U512, }; @@ -387,6 +387,9 @@ pub fn execute_finalized_block( // in this mode, consumed gas is accumulated into a single purse for later // distribution let consumed = Gas::new(artifact_builder.consumed()); + let amount = Motes::from_gas(consumed, current_gas_price) + .map(|x| x.value()) + .unwrap_or_else(U512::zero); let handle_payment_request = HandlePaymentRequest::new( native_runtime_config.clone(), state_root_hash, @@ -396,7 +399,7 @@ pub fn execute_finalized_block( gas_limit.value(), current_gas_price, cost, - consumed.value(), + amount, balance_identifier, BalanceIdentifier::Accumulate, holds_epoch, @@ -410,13 +413,14 @@ pub fn execute_finalized_block( .map_err(|_| BlockExecutionError::RootNotFound(state_root_hash))?; } FeeHandling::Burn => { - let consumed = artifact_builder.consumed(); + let consumed = Gas::new(artifact_builder.consumed()); + let amount = Motes::from_gas(consumed, current_gas_price).map(|x| x.value()); let handle_payment_request = HandlePaymentRequest::new( native_runtime_config.clone(), state_root_hash, protocol_version, transaction_hash, - HandlePaymentMode::burn(balance_identifier, Some(consumed)), + HandlePaymentMode::burn(balance_identifier, amount), ); let handle_payment_result = scratch_state.handle_payment(handle_payment_request); state_root_hash = scratch_state diff --git a/node/src/reactor/main_reactor/tests/transactions.rs b/node/src/reactor/main_reactor/tests/transactions.rs index 3e31ea4820..89b9c53cd5 100644 --- a/node/src/reactor/main_reactor/tests/transactions.rs +++ b/node/src/reactor/main_reactor/tests/transactions.rs @@ -5,8 +5,8 @@ use casper_types::execution::ExecutionResultV1; async fn transfer_to_account>( fixture: &mut TestFixture, amount: A, - to: PublicKey, from: &SecretKey, + to: PublicKey, pricing: PricingMode, transfer_id: Option, ) -> (TransactionHash, u64, ExecutionResult) { @@ -202,8 +202,8 @@ async fn transfer_cost_fixed_price_no_fee_no_refund() { let (_txn_hash, block_height, exec_result) = transfer_to_account( &mut fixture, TRANSFER_AMOUNT, - PublicKey::from(&*charlie_secret_key), &alice_secret_key, + PublicKey::from(&*charlie_secret_key), PricingMode::Fixed { gas_price_tolerance: 1, }, @@ -305,8 +305,8 @@ async fn should_accept_transfer_without_id() { let (_, _, result) = transfer_to_account( &mut fixture, transfer_amount, - PublicKey::from(&*charlie_secret_key), &alice_secret_key, + PublicKey::from(&*charlie_secret_key), PricingMode::Fixed { gas_price_tolerance: 1, }, @@ -346,8 +346,8 @@ async fn failed_transfer_cost_fixed_price_no_fee_no_refund() { let (_txn_hash, _block, exec_result) = transfer_to_account( &mut fixture, transfer_amount, - PublicKey::from(&*charlie_secret_key), &alice_secret_key, + PublicKey::from(&*charlie_secret_key), PricingMode::Fixed { gas_price_tolerance: 1, }, @@ -361,8 +361,8 @@ async fn failed_transfer_cost_fixed_price_no_fee_no_refund() { let (_txn_hash, block_height, exec_result) = transfer_to_account( &mut fixture, transfer_amount + 100, - PublicKey::from(&*bob_secret_key), &charlie_secret_key, + PublicKey::from(&*bob_secret_key), PricingMode::Fixed { gas_price_tolerance: 1, }, @@ -433,8 +433,8 @@ async fn transfer_cost_classic_price_no_fee_no_refund() { let (_txn_hash, block_height, exec_result) = transfer_to_account( &mut fixture, TRANSFER_AMOUNT, - PublicKey::from(&*charlie_secret_key), &alice_secret_key, + PublicKey::from(&*charlie_secret_key), PricingMode::Classic { payment_amount: TRANSFER_GAS, gas_price_tolerance: MIN_GAS_PRICE + 1, @@ -541,8 +541,8 @@ async fn transaction_with_low_threshold_should_not_get_included() { let (_, _, _) = transfer_to_account( &mut fixture, TRANSFER_AMOUNT, - PublicKey::from(&*charlie_secret_key), &alice_secret_key, + PublicKey::from(&*charlie_secret_key), PricingMode::Classic { payment_amount: 1000, gas_price_tolerance: MIN_GAS_PRICE - 1, @@ -553,113 +553,129 @@ async fn transaction_with_low_threshold_should_not_get_included() { .await; } -// #[tokio::test] -// async fn transfer_fee_is_burnt_no_refund() { -// const MIN_GAS_PRICE: u8 = 5; -// const MAX_GAS_PRICE: u8 = MIN_GAS_PRICE; -// -// let initial_stakes = InitialStakes::FromVec(vec![u128::MAX, 1]); -// -// let config = ConfigsOverride::default() -// .with_minimum_era_height(5) // make the era longer so that the transaction doesn't land in the switch block. -// .with_pricing_handling(PricingHandling::Fixed) -// .with_refund_handling(RefundHandling::NoRefund) -// .with_fee_handling(FeeHandling::Burn) -// .with_balance_hold_interval(TimeDiff::from_seconds(5)) -// .with_min_gas_price(MIN_GAS_PRICE) -// .with_max_gas_price(MAX_GAS_PRICE); -// -// let mut fixture = TestFixture::new(initial_stakes, Some(config)).await; -// -// let alice_secret_key = Arc::clone(&fixture.node_contexts[0].secret_key); -// let alice_public_key = PublicKey::from(&*alice_secret_key); -// let charlie_secret_key = Arc::new(SecretKey::random(&mut fixture.rng)); -// let charlie_public_key = PublicKey::from(&*charlie_secret_key); -// -// // Wait for all nodes to complete era 0. -// fixture.run_until_consensus_in_era(ERA_ONE, ONE_MIN).await; -// -// let initial_total_supply = get_total_supply(&mut fixture, None); -// -// let alice_initial_balance = *get_balance(&mut fixture, &alice_public_key, None, true) -// .motes() -// .expect("Expected Alice to have a balance."); -// -// let transfer_amount = fixture -// .chainspec -// .transaction_config -// .native_transfer_minimum_motes -// + 100; -// -// let (_txn_hash, block_height, exec_result) = transfer_to_account( -// &mut fixture, -// transfer_amount, -// PublicKey::from(&*charlie_secret_key), -// &alice_secret_key, -// PricingMode::Fixed { -// gas_price_tolerance: MIN_GAS_PRICE, -// }, -// None, -// ) -// .await; -// -// assert!(exec_result_is_success(&exec_result)); // transaction should have succeeded. -// -// let expected_transfer_gas: u64 = fixture -// .chainspec -// .system_costs_config -// .mint_costs() -// .transfer -// .into(); -// let expected_transfer_cost = expected_transfer_gas * MIN_GAS_PRICE as u64; -// assert_exec_result_cost( -// exec_result, -// expected_transfer_cost.into(), -// expected_transfer_gas.into(), -// ); -// -// // The fees should have been burnt. So expect the total supply should have been reduced by the -// // fee that was burnt. -// let total_supply_after_transaction = get_total_supply(&mut fixture, Some(block_height)); -// assert_eq!( -// total_supply_after_transaction, -// initial_total_supply - expected_transfer_cost -// ); -// -// let alice_available_balance = -// get_balance(&mut fixture, &alice_public_key, Some(block_height), false); -// let alice_total_balance = -// get_balance(&mut fixture, &alice_public_key, Some(block_height), true); -// -// let alice_expected_total_balance = -// alice_initial_balance - transfer_amount - expected_transfer_cost; -// let alice_expected_available_balance = alice_expected_total_balance; -// -// let charlie_balance = get_balance(&mut fixture, &charlie_public_key, Some(block_height), false); -// assert_eq!( -// charlie_balance -// .motes() -// .expect("Expected Charlie to have a balance") -// .clone(), -// transfer_amount.into() -// ); -// -// assert_eq!( -// alice_available_balance -// .motes() -// .expect("Expected Alice to have a balance") -// .clone(), -// alice_expected_available_balance -// ); -// -// assert_eq!( -// alice_total_balance -// .motes() -// .expect("Expected Alice to have a balance") -// .clone(), -// alice_expected_total_balance -// ); -// } +#[tokio::test] +async fn transfer_fee_is_burnt_no_refund() { + const MIN_GAS_PRICE: u8 = 5; + const MAX_GAS_PRICE: u8 = MIN_GAS_PRICE; + + let initial_stakes = InitialStakes::FromVec(vec![u128::MAX, 1]); + + // make the era longer so that the transaction doesn't land in the switch block. + let minimum_era_height = 5; + // make the hold interval very short so we can see the behavior. + let balance_hold_interval = TimeDiff::from_seconds(5); + + let config = ConfigsOverride::default() + .with_minimum_era_height(minimum_era_height) + .with_pricing_handling(PricingHandling::Fixed) + .with_refund_handling(RefundHandling::NoRefund) + .with_fee_handling(FeeHandling::Burn) + .with_balance_hold_interval(balance_hold_interval) + .with_min_gas_price(MIN_GAS_PRICE) + .with_max_gas_price(MAX_GAS_PRICE); + + let mut fixture = TestFixture::new(initial_stakes, Some(config)).await; + + let alice_secret_key = Arc::clone(&fixture.node_contexts[0].secret_key); + let alice_public_key = PublicKey::from(&*alice_secret_key); + let charlie_secret_key = Arc::new(SecretKey::random(&mut fixture.rng)); + let charlie_public_key = PublicKey::from(&*charlie_secret_key); + + info!("waiting for all nodes to complete era 0"); + fixture.run_until_consensus_in_era(ERA_ONE, ONE_MIN).await; + + let initial_total_supply = get_total_supply(&mut fixture, None); + + let alice_initial_balance = *get_balance(&mut fixture, &alice_public_key, None, true) + .motes() + .expect("expected alice to have a balance"); + + let transfer_amount = fixture + .chainspec + .transaction_config + .native_transfer_minimum_motes + + 100; + + info!("transferring from alice to charlie"); + let (_txn_hash, block_height, exec_result) = transfer_to_account( + &mut fixture, + transfer_amount, + &alice_secret_key, + PublicKey::from(&*charlie_secret_key), + PricingMode::Fixed { + gas_price_tolerance: MIN_GAS_PRICE, + }, + None, + ) + .await; + assert!(exec_result_is_success(&exec_result), "{:?}", exec_result); + info!("transfer was successful"); + + let expected_transfer_gas: u64 = fixture + .chainspec + .system_costs_config + .mint_costs() + .transfer + .into(); + let expected_transfer_cost = expected_transfer_gas * MIN_GAS_PRICE as u64; + info!("checking expected cost"); + assert_exec_result_cost( + exec_result, + expected_transfer_cost.into(), + expected_transfer_gas.into(), + ); + + // The fees should have been burnt so expect the total supply to have been + // reduced by the fee that was burnt. + info!("checking total supply"); + let total_supply_after_transaction = get_total_supply(&mut fixture, Some(block_height)); + assert_ne!( + total_supply_after_transaction, initial_total_supply, + "total supply should be lowered" + ); + let diff = initial_total_supply - total_supply_after_transaction; + assert_eq!( + diff, + U512::from(expected_transfer_cost), + "total supply should be lowered by expected transfer cost" + ); + + let alice_available_balance = + get_balance(&mut fixture, &alice_public_key, Some(block_height), false); + let alice_total_balance = + get_balance(&mut fixture, &alice_public_key, Some(block_height), true); + let alice_expected_total_balance = + alice_initial_balance - transfer_amount - expected_transfer_cost; + let alice_expected_available_balance = alice_expected_total_balance; + + info!("checking charlie balance"); + let charlie_balance = get_balance(&mut fixture, &charlie_public_key, Some(block_height), false); + assert_eq!( + charlie_balance + .motes() + .expect("Expected Charlie to have a balance") + .clone(), + transfer_amount.into() + ); + + info!("checking alice available balance"); + assert_eq!( + alice_available_balance + .motes() + .expect("Expected Alice to have a balance") + .clone(), + alice_expected_available_balance + ); + + info!("checking alice total balance"); + assert_eq!( + alice_total_balance + .motes() + .expect("Expected Alice to have a balance") + .clone(), + alice_expected_total_balance + ); +} #[tokio::test] async fn fee_is_payed_to_proposer_no_refund() { @@ -705,8 +721,8 @@ async fn fee_is_payed_to_proposer_no_refund() { let (_txn_hash, block_height, exec_result) = transfer_to_account( &mut fixture, transfer_amount, - PublicKey::from(&*charlie_secret_key), &bob_secret_key, + PublicKey::from(&*charlie_secret_key), PricingMode::Fixed { gas_price_tolerance: MIN_GAS_PRICE, },