diff --git a/Makefile b/Makefile index 14efdc5770..290e9c924a 100644 --- a/Makefile +++ b/Makefile @@ -152,7 +152,7 @@ lint-smart-contracts: .PHONY: audit-rs audit-rs: - $(CARGO) audit --ignore RUSTSEC-2024-0344 --ignore RUSTSEC-2024-0367 --ignore RUSTSEC-2024-0371 + $(CARGO) audit --ignore RUSTSEC-2024-0344 --ignore RUSTSEC-2024-0367 --ignore RUSTSEC-2024-0371 --ignore RUSTSEC-2024-0421 .PHONY: audit-as audit-as: diff --git a/execution_engine/src/execution/error.rs b/execution_engine/src/execution/error.rs index 796a35648c..4d21bb31a2 100644 --- a/execution_engine/src/execution/error.rs +++ b/execution_engine/src/execution/error.rs @@ -9,7 +9,7 @@ use casper_types::{ bytesrepr, execution::TransformError, system, AccessRights, AddressableEntityHash, ApiError, ByteCodeHash, CLType, CLValueError, - EntityVersionKey, Key, PackageHash, StoredValueTypeMismatch, TransactionRuntime, URef, + ContractRuntimeTag, EntityVersionKey, Key, PackageHash, StoredValueTypeMismatch, URef, }; use casper_wasm::elements; @@ -191,7 +191,7 @@ pub enum Error { InvalidUtf8Encoding(Utf8Error), /// Incompatible transaction runtime. #[error("Incompatible runtime: {0}")] - IncompatibleRuntime(TransactionRuntime), + IncompatibleRuntime(ContractRuntimeTag), } impl From for Error { diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index 010baf0c8a..885e1c344e 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -38,9 +38,9 @@ use casper_types::{ }, addressable_entity::{ self, ActionThresholds, ActionType, AddressableEntity, AddressableEntityHash, - AssociatedKeys, EntityKindTag, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, - MessageTopicError, MessageTopics, NamedKeyAddr, NamedKeyValue, Parameter, Weight, - DEFAULT_ENTRY_POINT_NAME, + AssociatedKeys, ContractRuntimeTag, EntityKindTag, EntryPoint, EntryPointAccess, + EntryPointType, EntryPoints, MessageTopicError, MessageTopics, NamedKeyAddr, NamedKeyValue, + Parameter, Weight, DEFAULT_ENTRY_POINT_NAME, }, bytesrepr::{self, Bytes, FromBytes, ToBytes}, contract_messages::{ @@ -60,9 +60,8 @@ use casper_types::{ ByteCodeKind, CLTyped, CLValue, ContextAccessRights, Contract, ContractWasm, EntityAddr, EntityKind, EntityVersion, EntityVersionKey, EntityVersions, Gas, GrantedAccess, Group, Groups, HashAddr, HostFunction, HostFunctionCost, InitiatorAddr, Key, NamedArg, Package, PackageHash, - PackageStatus, Phase, PublicKey, RuntimeArgs, RuntimeFootprint, StoredValue, - TransactionRuntime, Transfer, TransferResult, TransferV2, TransferredTo, URef, - DICTIONARY_ITEM_KEY_MAX_LENGTH, U512, + PackageStatus, Phase, PublicKey, RuntimeArgs, RuntimeFootprint, StoredValue, Transfer, + TransferResult, TransferV2, TransferredTo, URef, DICTIONARY_ITEM_KEY_MAX_LENGTH, U512, }; use crate::{ @@ -1893,14 +1892,14 @@ where EntityKind::System(_) | EntityKind::Account(_) => { Key::ByteCode(ByteCodeAddr::Empty) } - EntityKind::SmartContract(TransactionRuntime::VmCasperV1) => { + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1) => { if self.context.engine_config().enable_entity { Key::ByteCode(ByteCodeAddr::new_wasm_addr(byte_code_addr)) } else { Key::Hash(byte_code_addr) } } - EntityKind::SmartContract(runtime @ TransactionRuntime::VmCasperV2) => { + EntityKind::SmartContract(runtime @ ContractRuntimeTag::VmCasperV2) => { return Err(ExecError::IncompatibleRuntime(runtime)); } }; @@ -2576,7 +2575,7 @@ where main_purse, associated_keys, action_thresholds, - EntityKind::SmartContract(TransactionRuntime::VmCasperV1), + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1), ); let entity_key = Key::AddressableEntity(entity_addr); self.context.metered_write_gs_unsafe(entity_key, entity)?; 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 c2d6d9f64a..3764d38a7c 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 @@ -13,7 +13,7 @@ use casper_types::{ bytesrepr::{Bytes, ToBytes}, ApiError, BlockTime, Digest, EraId, InitiatorAddr, Key, PricingMode, ProtocolVersion, PublicKey, RuntimeArgs, SecretKey, TimeDiff, Timestamp, Transaction, TransactionArgs, - TransactionEntryPoint, TransactionRuntime, TransactionScheduling, TransactionTarget, + TransactionEntryPoint, TransactionRuntimeParams, TransactionScheduling, TransactionTarget, TransactionV1, TransactionV1Payload, }; @@ -49,8 +49,7 @@ fn try_add_contract_version( let txn = new_transaction_v1_session( is_install_upgrade, module_bytes, - casper_types::TransactionRuntime::VmCasperV1, - 0, + TransactionRuntimeParams::VmCasperV1, &DEFAULT_ACCOUNT_SECRET_KEY, ); @@ -111,8 +110,7 @@ fn try_add_contract_version( pub fn new_transaction_v1_session( is_install_upgrade: bool, module_bytes: Bytes, - runtime: TransactionRuntime, - transferred_value: u64, + runtime: TransactionRuntimeParams, secret_key: &SecretKey, ) -> TransactionV1 { let timestamp = Timestamp::now(); @@ -121,8 +119,6 @@ pub fn new_transaction_v1_session( is_install_upgrade, module_bytes, runtime, - transferred_value, - seed: None, }; let args = TransactionArgs::Named(RuntimeArgs::new()); let entry_point = TransactionEntryPoint::Call; diff --git a/executor/wasm-host/src/host.rs b/executor/wasm-host/src/host.rs index c4abfbeb0e..3db36e078f 100644 --- a/executor/wasm-host/src/host.rs +++ b/executor/wasm-host/src/host.rs @@ -23,10 +23,9 @@ use casper_types::{ account::AccountHash, addressable_entity::{ActionThresholds, AssociatedKeys, NamedKeyAddr}, AddressableEntity, AddressableEntityHash, BlockHash, ByteCode, ByteCodeAddr, ByteCodeHash, - ByteCodeKind, CLType, Digest, EntityAddr, EntityKind, EntryPoint, EntryPointAccess, - EntryPointAddr, EntryPointPayment, EntryPointType, EntryPointValue, Groups, HashAddr, Key, - Package, PackageHash, PackageStatus, ProtocolVersion, StoredValue, TransactionRuntime, URef, - U512, + ByteCodeKind, CLType, ContractRuntimeTag, Digest, EntityAddr, EntityKind, EntryPoint, + EntryPointAccess, EntryPointAddr, EntryPointPayment, EntryPointType, EntryPointValue, Groups, + HashAddr, Key, Package, PackageHash, PackageStatus, ProtocolVersion, StoredValue, URef, U512, }; use either::Either; use num_derive::FromPrimitive; @@ -506,7 +505,7 @@ pub fn casper_create( main_purse, AssociatedKeys::default(), ActionThresholds::default(), - EntityKind::SmartContract(TransactionRuntime::VmCasperV2), + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV2), ); caller.context_mut().tracking_copy.write( diff --git a/executor/wasm/src/lib.rs b/executor/wasm/src/lib.rs index 58a927f065..f30d29279c 100644 --- a/executor/wasm/src/lib.rs +++ b/executor/wasm/src/lib.rs @@ -35,9 +35,9 @@ use casper_types::{ account::AccountHash, addressable_entity::{ActionThresholds, AssociatedKeys}, bytesrepr, AddressableEntity, AddressableEntityHash, ByteCode, ByteCodeAddr, ByteCodeHash, - ByteCodeKind, Digest, EntityAddr, EntityKind, Gas, Groups, InitiatorAddr, Key, Package, - PackageHash, PackageStatus, Phase, ProtocolVersion, StoredValue, TransactionInvocationTarget, - TransactionRuntime, URef, U512, + ByteCodeKind, ContractRuntimeTag, Digest, EntityAddr, EntityKind, Gas, Groups, InitiatorAddr, + Key, Package, PackageHash, PackageStatus, Phase, ProtocolVersion, StoredValue, + TransactionInvocationTarget, URef, U512, }; use either::Either; use install::{InstallContractError, InstallContractRequest, InstallContractResult}; @@ -230,7 +230,7 @@ impl ExecutorV2 { main_purse, AssociatedKeys::default(), ActionThresholds::default(), - EntityKind::SmartContract(TransactionRuntime::VmCasperV2), + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV2), ); tracking_copy.write( @@ -374,7 +374,7 @@ impl ExecutorV2 { let wasm_key = match addressable_entity.kind() { EntityKind::System(_) => todo!(), EntityKind::Account(_) => todo!(), - EntityKind::SmartContract(TransactionRuntime::VmCasperV1) => { + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1) => { // We need to short circuit here to execute v1 contracts with legacy // execut @@ -398,7 +398,7 @@ impl ExecutorV2 { gas_limit, ); } - EntityKind::SmartContract(TransactionRuntime::VmCasperV2) => { + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV2) => { Key::ByteCode(ByteCodeAddr::V2CasperWasm( addressable_entity.byte_code_addr(), )) diff --git a/node/src/components/contract_runtime/operations/wasm_v2_request.rs b/node/src/components/contract_runtime/operations/wasm_v2_request.rs index 0b4c4cb086..d2b70b1e7e 100644 --- a/node/src/components/contract_runtime/operations/wasm_v2_request.rs +++ b/node/src/components/contract_runtime/operations/wasm_v2_request.rs @@ -21,7 +21,7 @@ use casper_storage::{ }; use casper_types::{ execution::Effects, BlockHash, Digest, Gas, Key, TransactionEntryPoint, - TransactionInvocationTarget, TransactionTarget, U512, + TransactionInvocationTarget, TransactionRuntimeParams, TransactionTarget, U512, }; use thiserror::Error; use tracing::info; @@ -102,6 +102,8 @@ pub(crate) enum InvalidRequest { InvalidGasLimit(U512), #[error("Expected transferred value")] ExpectedTransferredValue, + #[error("Expected V2 runtime")] + ExpectedV2Runtime, } impl WasmV2Request { @@ -139,6 +141,7 @@ impl WasmV2Request { Install { module_bytes: Bytes, entry_point: String, + transferred_value: u64, seed: Option<[u8; 32]>, }, Session { @@ -153,22 +156,28 @@ impl WasmV2Request { let target = transaction.target().ok_or(InvalidRequest::ExpectedTarget)?; let target = match target { TransactionTarget::Native => todo!(), // - TransactionTarget::Stored { - id, - runtime: _, - transferred_value: _, - } => match transaction.entry_point() { + TransactionTarget::Stored { id, runtime: _ } => match transaction.entry_point() { TransactionEntryPoint::Custom(entry_point) => Target::Stored { id: id.clone(), entry_point: entry_point.clone(), }, _ => todo!(), }, + + TransactionTarget::Session { + module_bytes: _, + runtime: TransactionRuntimeParams::VmCasperV1, + is_install_upgrade: _, // TODO: Handle this + } => { + return Err(InvalidRequest::ExpectedV2Runtime); + } TransactionTarget::Session { module_bytes, - runtime: _, - transferred_value: _, - seed, + runtime: + TransactionRuntimeParams::VmCasperV2 { + transferred_value, + seed, + }, is_install_upgrade: _, // TODO: Handle this } => match transaction.entry_point() { TransactionEntryPoint::Call => Target::Session { @@ -177,6 +186,7 @@ impl WasmV2Request { TransactionEntryPoint::Custom(entry_point) => Target::Install { module_bytes: module_bytes.clone().take_inner().into(), entry_point: entry_point.to_string(), + transferred_value, seed, }, _ => todo!(), @@ -189,6 +199,7 @@ impl WasmV2Request { Target::Install { module_bytes, entry_point, + transferred_value, seed, } => { let mut builder = InstallContractRequestBuilder::default(); @@ -213,6 +224,10 @@ impl WasmV2Request { builder = builder.with_seed(seed); } + // Value is expected to be the same as transferred value, it's just taken through + // different API. + debug_assert_eq!(transferred_value, value); + let install_request = builder .with_initiator(initiator_addr.account_hash()) .with_gas_limit(gas_limit) diff --git a/node/src/components/transaction_acceptor.rs b/node/src/components/transaction_acceptor.rs index ae8fa44282..6975e2f29e 100644 --- a/node/src/components/transaction_acceptor.rs +++ b/node/src/components/transaction_acceptor.rs @@ -6,7 +6,7 @@ mod tests; use std::{collections::BTreeSet, fmt::Debug, sync::Arc}; -use casper_types::{InvalidTransaction, InvalidTransactionV1}; +use casper_types::{ContractRuntimeTag, InvalidTransaction, InvalidTransactionV1}; use datasize::DataSize; use prometheus::Registry; use tracing::{debug, error, trace}; @@ -19,7 +19,7 @@ use casper_types::{ EntityKind, EntityVersion, EntityVersionKey, ExecutableDeployItem, ExecutableDeployItemIdentifier, InitiatorAddr, Key, Package, PackageAddr, PackageHash, PackageIdentifier, Timestamp, Transaction, TransactionEntryPoint, TransactionInvocationTarget, - TransactionRuntime, TransactionTarget, DEFAULT_ENTRY_POINT_NAME, U512, + TransactionTarget, DEFAULT_ENTRY_POINT_NAME, U512, }; use crate::{ @@ -657,7 +657,7 @@ impl TransactionAcceptor { entry_point_exist: bool, ) -> Effects { match addressable_entity.kind() { - EntityKind::SmartContract(TransactionRuntime::VmCasperV1) + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1) | EntityKind::Account(_) | EntityKind::System(_) => { if !entry_point_exist { @@ -672,7 +672,7 @@ impl TransactionAcceptor { } self.validate_transaction_cryptography(effect_builder, event_metadata) } - EntityKind::SmartContract(TransactionRuntime::VmCasperV2) => { + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV2) => { // Engine V2 does not store entrypoint information on chain and relies entirely on // the Wasm itself. self.validate_transaction_cryptography(effect_builder, event_metadata) diff --git a/node/src/components/transaction_acceptor/tests.rs b/node/src/components/transaction_acceptor/tests.rs index dc795bedd0..68fc057a4b 100644 --- a/node/src/components/transaction_acceptor/tests.rs +++ b/node/src/components/transaction_acceptor/tests.rs @@ -38,7 +38,7 @@ use casper_types::{ Block, BlockV2, CLValue, Chainspec, ChainspecRawBytes, Contract, Deploy, EraId, HashAddr, InvalidDeploy, InvalidTransaction, InvalidTransactionV1, Package, PricingHandling, PricingMode, ProtocolVersion, PublicKey, SecretKey, StoredValue, TestBlockBuilder, TimeDiff, Timestamp, - Transaction, TransactionConfig, TransactionRuntime, TransactionV1, URef, U512, + Transaction, TransactionConfig, TransactionRuntimeParams, TransactionV1, URef, U512, }; use super::*; @@ -288,9 +288,7 @@ impl TestScenario { let txn = TransactionV1Builder::new_session( false, Bytes::from(vec![1]), - TransactionRuntime::VmCasperV1, - 0, - None, + TransactionRuntimeParams::VmCasperV1, ) .with_chain_name("casper-example") .with_timestamp(Timestamp::zero()) @@ -315,9 +313,7 @@ impl TestScenario { let txn = TransactionV1Builder::new_session( false, Bytes::from(vec![1]), - TransactionRuntime::VmCasperV1, - 0, - None, + TransactionRuntimeParams::VmCasperV1, ) .with_chain_name("casper-example") .with_timestamp(Timestamp::now()) @@ -336,9 +332,7 @@ impl TestScenario { let txn = TransactionV1Builder::new_session( false, Bytes::from(vec![1]), - TransactionRuntime::VmCasperV1, - 0, - None, + TransactionRuntimeParams::VmCasperV1, ) .with_chain_name("casper-example") .with_timestamp(Timestamp::now()) @@ -419,8 +413,7 @@ impl TestScenario { let txn = TransactionV1Builder::new_targeting_invocable_entity_via_alias( "Test", "call", - TransactionRuntime::VmCasperV1, - 0, + TransactionRuntimeParams::VmCasperV1, ) .with_chain_name("casper-example") .with_timestamp(Timestamp::now()) @@ -433,8 +426,7 @@ impl TestScenario { let txn = TransactionV1Builder::new_targeting_invocable_entity( AddressableEntityHash::new(HashAddr::default()), "call", - TransactionRuntime::VmCasperV1, - 0, + TransactionRuntimeParams::VmCasperV1, ) .with_chain_name("casper-example") .with_timestamp(Timestamp::now()) @@ -447,8 +439,7 @@ impl TestScenario { let txn = TransactionV1Builder::new_targeting_invocable_entity( AddressableEntityHash::new(HashAddr::default()), "non-existent-entry-point", - TransactionRuntime::VmCasperV1, - 0, + TransactionRuntimeParams::VmCasperV1, ) .with_chain_name("casper-example") .with_timestamp(Timestamp::now()) @@ -490,8 +481,7 @@ impl TestScenario { "Test", None, "call", - TransactionRuntime::VmCasperV1, - 0, + TransactionRuntimeParams::VmCasperV1, ) .with_chain_name("casper-example") .with_timestamp(Timestamp::now()) @@ -505,8 +495,7 @@ impl TestScenario { PackageHash::new(PackageAddr::default()), None, "call", - TransactionRuntime::VmCasperV1, - 0, + TransactionRuntimeParams::VmCasperV1, ) .with_chain_name("casper-example") .with_timestamp(Timestamp::now()) @@ -520,8 +509,7 @@ impl TestScenario { PackageHash::new(PackageAddr::default()), Some(6), "call", - TransactionRuntime::VmCasperV1, - 0, + TransactionRuntimeParams::VmCasperV1, ) .with_chain_name("casper-example") .with_timestamp(Timestamp::now()) @@ -550,9 +538,7 @@ impl TestScenario { let txn = TransactionV1Builder::new_session( false, Bytes::from(vec![1]), - TransactionRuntime::VmCasperV1, - 0, - None, + TransactionRuntimeParams::VmCasperV1, ) .with_chain_name("casper-example") .with_timestamp(timestamp) @@ -579,9 +565,7 @@ impl TestScenario { let txn = TransactionV1Builder::new_session( false, Bytes::from(vec![1]), - TransactionRuntime::VmCasperV1, - 0, - None, + TransactionRuntimeParams::VmCasperV1, ) .with_chain_name("casper-example") .with_timestamp(timestamp) @@ -629,9 +613,7 @@ impl TestScenario { let txn = TransactionV1Builder::new_session( false, Bytes::from(vec![1]), - TransactionRuntime::VmCasperV1, - 0, - None, + TransactionRuntimeParams::VmCasperV1, ) .with_chain_name("casper-example") .with_ttl(TimeDiff::from_seconds(300)) diff --git a/node/src/reactor/main_reactor/tests/binary_port.rs b/node/src/reactor/main_reactor/tests/binary_port.rs index 2c4884b824..972d9f414f 100644 --- a/node/src/reactor/main_reactor/tests/binary_port.rs +++ b/node/src/reactor/main_reactor/tests/binary_port.rs @@ -27,11 +27,11 @@ use casper_types::{ testing::TestRng, Account, AddressableEntity, AvailableBlockRange, Block, BlockHash, BlockHeader, BlockIdentifier, BlockSynchronizerStatus, ByteCode, ByteCodeAddr, ByteCodeHash, ByteCodeKind, - CLValue, CLValueDictionary, ChainspecRawBytes, Contract, ContractWasm, ContractWasmHash, - DictionaryAddr, Digest, EntityAddr, EntityKind, EntityVersions, GlobalStateIdentifier, Key, - KeyTag, NextUpgrade, Package, PackageAddr, PackageHash, Peers, ProtocolVersion, PublicKey, - Rewards, SecretKey, SignedBlock, StoredValue, Transaction, TransactionRuntime, Transfer, URef, - U512, + CLValue, CLValueDictionary, ChainspecRawBytes, Contract, ContractRuntimeTag, ContractWasm, + ContractWasmHash, DictionaryAddr, Digest, EntityAddr, EntityKind, EntityVersions, + GlobalStateIdentifier, Key, KeyTag, NextUpgrade, Package, PackageAddr, PackageHash, Peers, + ProtocolVersion, PublicKey, Rewards, SecretKey, SignedBlock, StoredValue, Transaction, + Transfer, URef, U512, }; use futures::{SinkExt, StreamExt}; use rand::Rng; @@ -315,7 +315,7 @@ fn test_effects(rng: &mut TestRng) -> TestEffects { main_purse, AssociatedKeys::default(), ActionThresholds::default(), - EntityKind::SmartContract(TransactionRuntime::VmCasperV1), + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1), ))), )); effects.push(TransformV2::new( @@ -1336,8 +1336,7 @@ fn try_accept_transaction(key: &SecretKey) -> TestCase { TransactionV1Builder::new_targeting_invocable_entity_via_alias( "Test", "call", - TransactionRuntime::VmCasperV1, - 0, + casper_types::TransactionRuntimeParams::VmCasperV1, ) .with_secret_key(key) .with_chain_name("casper-example") diff --git a/node/src/reactor/main_reactor/tests/transactions.rs b/node/src/reactor/main_reactor/tests/transactions.rs index b60d7ac3db..9726ac0162 100644 --- a/node/src/reactor/main_reactor/tests/transactions.rs +++ b/node/src/reactor/main_reactor/tests/transactions.rs @@ -9,7 +9,8 @@ use casper_types::{ addressable_entity::NamedKeyAddr, runtime_args, system::mint::{ARG_AMOUNT, ARG_TARGET}, - AddressableEntity, Digest, EntityAddr, ExecutionInfo, TransactionRuntime, LARGE_WASM_LANE_ID, + AddressableEntity, Digest, EntityAddr, ExecutionInfo, TransactionRuntimeParams, + LARGE_WASM_LANE_ID, }; use once_cell::sync::Lazy; @@ -98,9 +99,7 @@ async fn send_wasm_transaction( TransactionV1Builder::new_session( false, module_bytes, - TransactionRuntime::VmCasperV1, - 0, - None, + casper_types::TransactionRuntimeParams::VmCasperV1, ) .with_chain_name(chain_name) .with_pricing_mode(pricing) @@ -1771,9 +1770,7 @@ async fn only_refunds_are_burnt_no_fee_custom_payment() { TransactionV1Builder::new_session( false, module_bytes, - TransactionRuntime::VmCasperV1, - 0, - None, + casper_types::TransactionRuntimeParams::VmCasperV1, ) .with_chain_name(CHAIN_NAME) .with_pricing_mode(PricingMode::PaymentLimited { @@ -1874,9 +1871,7 @@ async fn no_refund_no_fee_custom_payment() { TransactionV1Builder::new_session( false, module_bytes, - TransactionRuntime::VmCasperV1, - 0, - None, + TransactionRuntimeParams::VmCasperV1, ) .with_chain_name(CHAIN_NAME) .with_pricing_mode(PricingMode::PaymentLimited { @@ -2440,9 +2435,7 @@ fn invalid_wasm_txn(initiator: Arc, pricing_mode: PricingMode) -> Tra TransactionV1Builder::new_session( false, module_bytes, - TransactionRuntime::VmCasperV1, - 0, - None, + casper_types::TransactionRuntimeParams::VmCasperV1, ) .with_chain_name(CHAIN_NAME) .with_pricing_mode(pricing_mode) @@ -3149,9 +3142,7 @@ async fn insufficient_funds_transfer_from_purse() { TransactionV1Builder::new_session( false, module_bytes, - TransactionRuntime::VmCasperV1, - 0, - None, + casper_types::TransactionRuntimeParams::VmCasperV1, ) .with_runtime_args(runtime_args! { "destination" => purse_name, "amount" => U512::zero() }) .with_chain_name(CHAIN_NAME) @@ -3277,9 +3268,7 @@ async fn charge_when_session_code_succeeds() { TransactionV1Builder::new_session( false, module_bytes, - TransactionRuntime::VmCasperV1, - 0, - None, + casper_types::TransactionRuntimeParams::VmCasperV1, ) .with_runtime_args(runtime_args! { ARG_TARGET => CHARLIE_PUBLIC_KEY.to_account_hash(), @@ -3350,9 +3339,7 @@ async fn charge_when_session_code_fails_with_user_error() { TransactionV1Builder::new_session( false, module_bytes, - TransactionRuntime::VmCasperV1, - 0, - None, + casper_types::TransactionRuntimeParams::VmCasperV1, ) .with_chain_name(CHAIN_NAME) .with_initiator_addr(BOB_PUBLIC_KEY.clone()) @@ -3420,9 +3407,7 @@ async fn charge_when_session_code_runs_out_of_gas() { TransactionV1Builder::new_session( false, module_bytes, - TransactionRuntime::VmCasperV1, - 0, - None, + casper_types::TransactionRuntimeParams::VmCasperV1, ) .with_chain_name(CHAIN_NAME) .with_initiator_addr(BOB_PUBLIC_KEY.clone()) @@ -3491,7 +3476,7 @@ async fn successful_purse_to_purse_transfer() { Bytes::from(std::fs::read(purse_create_contract).expect("cannot read module bytes")); let mut txn = Transaction::from( - TransactionV1Builder::new_session(false, module_bytes,TransactionRuntime::VmCasperV1, 0, None) + TransactionV1Builder::new_session(false, module_bytes, TransactionRuntimeParams::VmCasperV1) .with_runtime_args( runtime_args! { "destination" => purse_name, "amount" => U512::from(MAX_PAYMENT_AMOUNT) + U512::one() }, ) @@ -3584,7 +3569,7 @@ async fn successful_purse_to_account_transfer() { Bytes::from(std::fs::read(purse_create_contract).expect("cannot read module bytes")); let mut txn = Transaction::from( - TransactionV1Builder::new_session(false, module_bytes, TransactionRuntime::VmCasperV1, 0, None) + TransactionV1Builder::new_session(false, module_bytes, TransactionRuntimeParams::VmCasperV1) .with_runtime_args( runtime_args! { "destination" => purse_name, "amount" => U512::from(MAX_PAYMENT_AMOUNT) + U512::one() }, ) @@ -3748,9 +3733,7 @@ async fn out_of_gas_txn_does_not_produce_effects() { TransactionV1Builder::new_session( false, module_bytes, - TransactionRuntime::VmCasperV1, - 0, - None, + casper_types::TransactionRuntimeParams::VmCasperV1, ) .with_chain_name(CHAIN_NAME) .with_initiator_addr(BOB_PUBLIC_KEY.clone()) diff --git a/node/src/types/transaction/fields_container.rs b/node/src/types/transaction/fields_container.rs index b22cb02ad9..5ae3b62a39 100644 --- a/node/src/types/transaction/fields_container.rs +++ b/node/src/types/transaction/fields_container.rs @@ -6,8 +6,9 @@ use casper_types::{ }; #[cfg(test)] use casper_types::{ - testing::TestRng, PublicKey, RuntimeArgs, TransactionInvocationTarget, TransactionRuntime, - TransferTarget, AUCTION_LANE_ID, INSTALL_UPGRADE_LANE_ID, MINT_LANE_ID, + testing::TestRng, PublicKey, RuntimeArgs, TransactionInvocationTarget, + TransactionRuntimeParams, TransferTarget, AUCTION_LANE_ID, INSTALL_UPGRADE_LANE_ID, + MINT_LANE_ID, }; #[cfg(test)] use rand::{Rng, RngCore}; @@ -184,9 +185,7 @@ impl FieldsContainer { let target = TransactionTarget::Session { is_install_upgrade, module_bytes: Bytes::from(buffer), - runtime: TransactionRuntime::VmCasperV1, - transferred_value: rng.gen(), - seed: rng.gen(), + runtime: TransactionRuntimeParams::VmCasperV1, }; FieldsContainer::new( TransactionArgs::Named(RuntimeArgs::random(rng)), @@ -214,10 +213,8 @@ impl FieldsContainer { fn random_install_upgrade(rng: &mut TestRng) -> Self { let target = TransactionTarget::Session { module_bytes: Bytes::from(rng.random_vec(0..100)), - runtime: TransactionRuntime::VmCasperV1, + runtime: TransactionRuntimeParams::VmCasperV1, is_install_upgrade: true, - transferred_value: 0, - seed: None, }; FieldsContainer::new( TransactionArgs::Named(RuntimeArgs::random(rng)), @@ -272,8 +269,7 @@ impl FieldsContainer { fn random_standard(rng: &mut TestRng) -> Self { let target = TransactionTarget::Stored { id: TransactionInvocationTarget::random(rng), - runtime: TransactionRuntime::VmCasperV1, - transferred_value: rng.gen(), + runtime: TransactionRuntimeParams::VmCasperV1, }; FieldsContainer::new( TransactionArgs::Named(RuntimeArgs::random(rng)), diff --git a/node/src/types/transaction/meta_transaction/meta_transaction_v1.rs b/node/src/types/transaction/meta_transaction/meta_transaction_v1.rs index ead27028f4..179000aa1c 100644 --- a/node/src/types/transaction/meta_transaction/meta_transaction_v1.rs +++ b/node/src/types/transaction/meta_transaction/meta_transaction_v1.rs @@ -1,10 +1,10 @@ use super::transaction_lane::{calculate_transaction_lane, TransactionLane}; use crate::types::transaction::arg_handling; use casper_types::{ - bytesrepr::ToBytes, crypto, Approval, Chainspec, Digest, DisplayIter, Gas, HashAddr, - InitiatorAddr, InvalidTransaction, InvalidTransactionV1, PricingHandling, PricingMode, - TimeDiff, Timestamp, TransactionArgs, TransactionConfig, TransactionEntryPoint, - TransactionRuntime, TransactionScheduling, TransactionTarget, TransactionV1, + bytesrepr::ToBytes, crypto, Approval, Chainspec, ContractRuntimeTag, Digest, DisplayIter, Gas, + HashAddr, InitiatorAddr, InvalidTransaction, InvalidTransactionV1, PricingHandling, + PricingMode, TimeDiff, Timestamp, TransactionArgs, TransactionConfig, TransactionEntryPoint, + TransactionRuntimeParams, TransactionScheduling, TransactionTarget, TransactionV1, TransactionV1ExcessiveSizeError, TransactionV1Hash, U512, }; use core::fmt::{self, Debug, Display, Formatter}; @@ -110,11 +110,20 @@ impl MetaTransactionV1 { } pub(crate) fn is_v2_wasm(&self) -> bool { - match self.target { + match &self.target { TransactionTarget::Native => false, - TransactionTarget::Stored { runtime, .. } - | TransactionTarget::Session { runtime, .. } => { - matches!(runtime, TransactionRuntime::VmCasperV2) + TransactionTarget::Stored { + runtime: stored_runtime, + .. + } => { + matches!(stored_runtime, TransactionRuntimeParams::VmCasperV2 { .. }) + && (!self.is_native_mint() && !self.is_native_auction()) + } + TransactionTarget::Session { + runtime: session_runtime, + .. + } => { + matches!(session_runtime, TransactionRuntimeParams::VmCasperV2 { .. }) && (!self.is_native_mint() && !self.is_native_auction()) } } @@ -279,11 +288,11 @@ impl MetaTransactionV1 { self.ttl } /// Returns the scheduling of the transaction. - pub(crate) fn transaction_runtime(&self) -> Option { - match self.target { + pub(crate) fn contract_runtime_tag(&self) -> Option { + match &self.target { TransactionTarget::Native => None, - TransactionTarget::Stored { runtime, .. } => Some(runtime), - TransactionTarget::Session { runtime, .. } => Some(runtime), + TransactionTarget::Stored { runtime, .. } => Some(runtime.contract_runtime_tag()), + TransactionTarget::Session { runtime, .. } => Some(runtime.contract_runtime_tag()), } } @@ -298,8 +307,8 @@ impl MetaTransactionV1 { ) -> Result<(), InvalidTransactionV1> { let transaction_config = chainspec.transaction_config.clone(); - match self.transaction_runtime() { - Some(expected_runtime @ TransactionRuntime::VmCasperV1) => { + match self.contract_runtime_tag() { + Some(expected_runtime @ ContractRuntimeTag::VmCasperV1) => { if !transaction_config.runtime_config.vm_casper_v1 { // NOTE: In current implementation native transactions should be executed on // both VmCasperV1 and VmCasperV2. This may change once we @@ -311,7 +320,7 @@ impl MetaTransactionV1 { }); } } - Some(expected_runtime @ TransactionRuntime::VmCasperV2) => { + Some(expected_runtime @ ContractRuntimeTag::VmCasperV2) => { if !transaction_config.runtime_config.vm_casper_v2 { // NOTE: In current implementation native transactions should be executed on // both VmCasperV1 and VmCasperV2. This may change once we @@ -639,18 +648,12 @@ impl MetaTransactionV1 { pub(crate) fn seed(&self) -> Option<[u8; 32]> { match &self.target { TransactionTarget::Native => None, - TransactionTarget::Stored { - id: _, - runtime: _, - transferred_value: _, - } => None, + TransactionTarget::Stored { id: _, runtime: _ } => None, TransactionTarget::Session { is_install_upgrade: _, - runtime: _, + runtime, module_bytes: _, - transferred_value: _, - seed, - } => *seed, + } => runtime.seed(), } } @@ -658,18 +661,23 @@ impl MetaTransactionV1 { pub fn transferred_value(&self) -> u64 { match &self.target { TransactionTarget::Native => 0, - TransactionTarget::Stored { - id: _, - runtime: _, - transferred_value, - } => *transferred_value, + TransactionTarget::Stored { id: _, runtime } => match runtime { + TransactionRuntimeParams::VmCasperV1 => 0, + TransactionRuntimeParams::VmCasperV2 { + transferred_value, .. + } => *transferred_value, + }, TransactionTarget::Session { is_install_upgrade: _, - runtime: _, + runtime, module_bytes: _, - transferred_value, - seed: _, - } => *transferred_value, + } => match runtime { + TransactionRuntimeParams::VmCasperV1 => 0, + TransactionRuntimeParams::VmCasperV2 { + transferred_value, + seed: _, + } => *transferred_value, + }, } } } diff --git a/node/src/types/transaction/meta_transaction/transaction_lane.rs b/node/src/types/transaction/meta_transaction/transaction_lane.rs index 18a240c430..66cbc54db1 100644 --- a/node/src/types/transaction/meta_transaction/transaction_lane.rs +++ b/node/src/types/transaction/meta_transaction/transaction_lane.rs @@ -5,7 +5,7 @@ use core::{ use casper_types::{ InvalidTransaction, InvalidTransactionV1, TransactionConfig, TransactionEntryPoint, - TransactionRuntime, TransactionTarget, TransactionV1Config, AUCTION_LANE_ID, + TransactionRuntimeParams, TransactionTarget, TransactionV1Config, AUCTION_LANE_ID, INSTALL_UPGRADE_LANE_ID, MINT_LANE_ID, }; use datasize::DataSize; @@ -118,7 +118,7 @@ pub(crate) fn calculate_transaction_lane( }, TransactionTarget::Session { is_install_upgrade, - runtime: TransactionRuntime::VmCasperV1, + runtime: TransactionRuntimeParams::VmCasperV1, .. } => match entry_point { TransactionEntryPoint::Call => { @@ -150,7 +150,7 @@ pub(crate) fn calculate_transaction_lane( }, TransactionTarget::Session { is_install_upgrade, - runtime: TransactionRuntime::VmCasperV2, + runtime: TransactionRuntimeParams::VmCasperV2 { .. }, .. } => match entry_point { TransactionEntryPoint::Call | TransactionEntryPoint::Custom(_) => { diff --git a/node/src/types/transaction/transaction_v1_builder.rs b/node/src/types/transaction/transaction_v1_builder.rs index e793319d3f..b065fd7433 100644 --- a/node/src/types/transaction/transaction_v1_builder.rs +++ b/node/src/types/transaction/transaction_v1_builder.rs @@ -5,7 +5,7 @@ use crate::types::transaction::initiator_addr_and_secret_key::InitiatorAddrAndSe use casper_types::{ bytesrepr::{Bytes, ToBytes}, Digest, InitiatorAddr, PricingMode, RuntimeArgs, SecretKey, TimeDiff, Timestamp, - TransactionArgs, TransactionEntryPoint, TransactionRuntime, TransactionScheduling, + TransactionArgs, TransactionEntryPoint, TransactionRuntimeParams, TransactionScheduling, TransactionTarget, TransactionV1, TransactionV1Payload, }; #[cfg(test)] @@ -153,10 +153,7 @@ impl<'a> TransactionV1Builder<'a> { /// /// A new `TransactionV1Builder` instance. pub(crate) fn new() -> Self { - #[cfg(any(feature = "std-fs-io", test))] let timestamp = Timestamp::now(); - #[cfg(not(any(feature = "std-fs-io", test)))] - let timestamp = Timestamp::zero(); TransactionV1Builder { args: TransactionArgs::Named(RuntimeArgs::new()), @@ -272,14 +269,9 @@ impl<'a> TransactionV1Builder<'a> { fn new_targeting_stored>( id: TransactionInvocationTarget, entry_point: E, - runtime: TransactionRuntime, - transferred_value: u64, + runtime: TransactionRuntimeParams, ) -> Self { - let target = TransactionTarget::Stored { - id, - runtime, - transferred_value, - }; + let target = TransactionTarget::Stored { id, runtime }; let mut builder = TransactionV1Builder::new(); builder.args = TransactionArgs::Named(RuntimeArgs::new()); builder.target = target; @@ -294,11 +286,10 @@ impl<'a> TransactionV1Builder<'a> { pub fn new_targeting_invocable_entity>( hash: AddressableEntityHash, entry_point: E, - runtime: TransactionRuntime, - transferred_value: u64, + runtime: TransactionRuntimeParams, ) -> Self { let id = TransactionInvocationTarget::new_invocable_entity(hash); - Self::new_targeting_stored(id, entry_point, runtime, transferred_value) + Self::new_targeting_stored(id, entry_point, runtime) } /// Returns a new `TransactionV1Builder` suitable for building a transaction targeting a stored @@ -307,11 +298,10 @@ impl<'a> TransactionV1Builder<'a> { pub fn new_targeting_invocable_entity_via_alias, E: Into>( alias: A, entry_point: E, - runtime: TransactionRuntime, - transferred_value: u64, + runtime: TransactionRuntimeParams, ) -> Self { let id = TransactionInvocationTarget::new_invocable_entity_alias(alias.into()); - Self::new_targeting_stored(id, entry_point, runtime, transferred_value) + Self::new_targeting_stored(id, entry_point, runtime) } /// Returns a new `TransactionV1Builder` suitable for building a transaction targeting a @@ -321,11 +311,10 @@ impl<'a> TransactionV1Builder<'a> { hash: PackageHash, version: Option, entry_point: E, - runtime: TransactionRuntime, - transferred_value: u64, + runtime: TransactionRuntimeParams, ) -> Self { let id = TransactionInvocationTarget::new_package(hash, version); - Self::new_targeting_stored(id, entry_point, runtime, transferred_value) + Self::new_targeting_stored(id, entry_point, runtime) } /// Returns a new `TransactionV1Builder` suitable for building a transaction targeting a @@ -335,11 +324,10 @@ impl<'a> TransactionV1Builder<'a> { alias: A, version: Option, entry_point: E, - runtime: TransactionRuntime, - transferred_value: u64, + runtime: TransactionRuntimeParams, ) -> Self { let id = TransactionInvocationTarget::new_package_alias(alias.into(), version); - Self::new_targeting_stored(id, entry_point, runtime, transferred_value) + Self::new_targeting_stored(id, entry_point, runtime) } /// Returns a new `TransactionV1Builder` suitable for building a transaction for running session @@ -347,16 +335,12 @@ impl<'a> TransactionV1Builder<'a> { pub fn new_session( is_install_upgrade: bool, module_bytes: Bytes, - runtime: TransactionRuntime, - transferred_value: u64, - seed: Option<[u8; 32]>, + runtime: TransactionRuntimeParams, ) -> Self { let target = TransactionTarget::Session { is_install_upgrade, module_bytes, runtime, - transferred_value, - seed, }; let mut builder = TransactionV1Builder::new(); builder.args = TransactionArgs::Named(RuntimeArgs::new()); @@ -638,8 +622,6 @@ fn build_transaction( } use core::fmt::{self, Display, Formatter}; -#[cfg(feature = "std")] -use std::error::Error as StdError; /// Errors returned while building a [`TransactionV1`] using a [`TransactionV1Builder`]. #[derive(Clone, Eq, PartialEq, Debug)] diff --git a/node/src/utils/specimen.rs b/node/src/utils/specimen.rs index 92e9fa107b..a411c4dc0a 100644 --- a/node/src/utils/specimen.rs +++ b/node/src/utils/specimen.rs @@ -27,8 +27,9 @@ use casper_types::{ ExecutableDeployItem, FinalitySignature, FinalitySignatureId, FinalitySignatureV2, PackageHash, ProtocolVersion, RewardedSignatures, RuntimeArgs, SecretKey, SemVer, SignedBlockHeader, SingleBlockRewardedSignatures, TimeDiff, Timestamp, Transaction, TransactionHash, - TransactionId, TransactionRuntime, TransactionV1, TransactionV1Hash, URef, AUCTION_LANE_ID, - INSTALL_UPGRADE_LANE_ID, KEY_HASH_LENGTH, LARGE_WASM_LANE_ID, MINT_LANE_ID, U512, + TransactionId, TransactionRuntimeParams, TransactionV1, TransactionV1Hash, URef, + AUCTION_LANE_ID, INSTALL_UPGRADE_LANE_ID, KEY_HASH_LENGTH, LARGE_WASM_LANE_ID, MINT_LANE_ID, + U512, }; use crate::{ @@ -1019,9 +1020,7 @@ impl LargestSpecimen for TransactionV1 { max_size_with_margin, cache, )), - TransactionRuntime::VmCasperV1, - 0, - None, + TransactionRuntimeParams::VmCasperV1, ) .with_secret_key(&LargestSpecimen::largest_specimen(estimator, cache)) .with_timestamp(LargestSpecimen::largest_specimen(estimator, cache)) diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index a47357346d..8f7fa9ebf8 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -4433,7 +4433,7 @@ ], "properties": { "SmartContract": { - "$ref": "#/definitions/TransactionRuntime" + "$ref": "#/definitions/ContractRuntimeTag" } }, "additionalProperties": false @@ -4473,23 +4473,12 @@ } ] }, - "TransactionRuntime": { + "ContractRuntimeTag": { "description": "Runtime used to execute a Transaction.", - "oneOf": [ - { - "description": "The Casper Version 1 Virtual Machine.", - "type": "string", - "enum": [ - "VmCasperV1" - ] - }, - { - "description": "The Casper Version 2 Virtual Machine.", - "type": "string", - "enum": [ - "VmCasperV2" - ] - } + "type": "string", + "enum": [ + "VmCasperV1", + "VmCasperV2" ] }, "PackageHash": { diff --git a/storage/src/tracking_copy/ext_entity.rs b/storage/src/tracking_copy/ext_entity.rs index 3dfdede86d..07ba48ed12 100644 --- a/storage/src/tracking_copy/ext_entity.rs +++ b/storage/src/tracking_copy/ext_entity.rs @@ -9,10 +9,10 @@ use casper_types::{ handle_payment::ACCUMULATION_PURSE_KEY, SystemEntityType, AUCTION, HANDLE_PAYMENT, MINT, }, AccessRights, Account, AddressableEntity, AddressableEntityHash, ByteCode, ByteCodeAddr, - ByteCodeHash, CLValue, ContextAccessRights, EntityAddr, EntityKind, EntityVersions, - EntryPointAddr, EntryPointValue, EntryPoints, Groups, HashAddr, Key, Package, PackageHash, - PackageStatus, Phase, ProtocolVersion, PublicKey, RuntimeFootprint, StoredValue, - StoredValueTypeMismatch, TransactionRuntime, URef, U512, + ByteCodeHash, CLValue, ContextAccessRights, ContractRuntimeTag, EntityAddr, EntityKind, + EntityVersions, EntryPointAddr, EntryPointValue, EntryPoints, Groups, HashAddr, Key, Package, + PackageHash, PackageStatus, Phase, ProtocolVersion, PublicKey, RuntimeFootprint, StoredValue, + StoredValueTypeMismatch, URef, U512, }; use crate::{ @@ -813,7 +813,7 @@ where purse, AssociatedKeys::default(), ActionThresholds::default(), - EntityKind::SmartContract(TransactionRuntime::VmCasperV1), + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1), ); let entry_points = contract.entry_points().clone(); diff --git a/storage/src/tracking_copy/tests.rs b/storage/src/tracking_copy/tests.rs index 09d4360527..dfb413bbc6 100644 --- a/storage/src/tracking_copy/tests.rs +++ b/storage/src/tracking_copy/tests.rs @@ -13,8 +13,8 @@ use casper_types::{ gens::*, global_state::TrieMerkleProof, handle_stored_dictionary_value, AccessRights, AddressableEntity, ByteCodeHash, CLValue, - CLValueDictionary, CLValueError, EntityAddr, EntityKind, HashAddr, Key, KeyTag, PackageHash, - ProtocolVersion, StoredValue, TransactionRuntime, URef, U256, U512, UREF_ADDR_LENGTH, + CLValueDictionary, CLValueError, ContractRuntimeTag, EntityAddr, EntityKind, HashAddr, Key, + KeyTag, PackageHash, ProtocolVersion, StoredValue, URef, U256, U512, UREF_ADDR_LENGTH, }; use super::{ @@ -553,7 +553,7 @@ proptest! { URef::default(), AssociatedKeys::default(), ActionThresholds::default(), - EntityKind::SmartContract(TransactionRuntime::VmCasperV1) + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1) )); let contract_key = Key::AddressableEntity(EntityAddr::SmartContract(hash)); @@ -644,7 +644,7 @@ proptest! { URef::default(), AssociatedKeys::default(), ActionThresholds::default(), - EntityKind::SmartContract(TransactionRuntime::VmCasperV1) + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1) )); let contract_key = Key::AddressableEntity(EntityAddr::SmartContract(hash)); let contract_named_key = NamedKeyAddr::new_from_string(EntityAddr::SmartContract(hash), state_name.clone()) @@ -740,7 +740,7 @@ fn query_for_circular_references_should_fail() { URef::default(), AssociatedKeys::default(), ActionThresholds::default(), - EntityKind::SmartContract(TransactionRuntime::VmCasperV1), + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1), )); let name_key_cl_value = Key::NamedKey( @@ -813,7 +813,7 @@ fn validate_query_proof_should_work() { URef::default(), AssociatedKeys::default(), ActionThresholds::default(), - EntityKind::SmartContract(TransactionRuntime::VmCasperV1), + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1), )); let c_nk = "abc".to_string(); @@ -1071,7 +1071,7 @@ fn query_with_large_depth_with_fixed_path_should_fail() { URef::default(), AssociatedKeys::default(), ActionThresholds::default(), - EntityKind::SmartContract(TransactionRuntime::VmCasperV1), + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1), )); pairs.push((contract_key, contract)); contract_keys.push(contract_key); @@ -1137,7 +1137,7 @@ fn query_with_large_depth_with_urefs_should_fail() { URef::default(), AssociatedKeys::default(), ActionThresholds::default(), - EntityKind::SmartContract(casper_types::TransactionRuntime::VmCasperV1), + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1), )); let contract_key = Key::AddressableEntity(contract_addr); pairs.push((contract_key, contract)); diff --git a/types/benches/bytesrepr_bench.rs b/types/benches/bytesrepr_bench.rs index ed3e0b45ca..3203f8b360 100644 --- a/types/benches/bytesrepr_bench.rs +++ b/types/benches/bytesrepr_bench.rs @@ -13,11 +13,11 @@ use casper_types::{ Bid, BidKind, Delegator, DelegatorBid, DelegatorKind, EraInfo, SeigniorageAllocation, ValidatorBid, }, - AccessRights, AddressableEntityHash, ByteCodeHash, CLTyped, CLValue, DeployHash, DeployInfo, - EntityVersionKey, EntityVersions, Gas, Group, Groups, InitiatorAddr, Key, Package, PackageHash, - PackageStatus, ProtocolVersion, PublicKey, SecretKey, TransactionHash, TransactionRuntime, - TransactionV1Hash, TransferAddr, TransferV2, URef, KEY_HASH_LENGTH, TRANSFER_ADDR_LENGTH, U128, - U256, U512, UREF_ADDR_LENGTH, + AccessRights, AddressableEntityHash, ByteCodeHash, CLTyped, CLValue, ContractRuntimeTag, + DeployHash, DeployInfo, EntityVersionKey, EntityVersions, Gas, Group, Groups, InitiatorAddr, + Key, Package, PackageHash, PackageStatus, ProtocolVersion, PublicKey, SecretKey, + TransactionHash, TransactionV1Hash, TransferAddr, TransferV2, URef, KEY_HASH_LENGTH, + TRANSFER_ADDR_LENGTH, U128, U256, U512, UREF_ADDR_LENGTH, }; static KB: usize = 1024; @@ -468,7 +468,7 @@ fn sample_contract() -> AddressableEntity { URef::default(), AssociatedKeys::default(), ActionThresholds::default(), - EntityKind::SmartContract(TransactionRuntime::VmCasperV1), + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1), ) } diff --git a/types/src/addressable_entity.rs b/types/src/addressable_entity.rs index ca28a17512..5b7ddf21ff 100644 --- a/types/src/addressable_entity.rs +++ b/types/src/addressable_entity.rs @@ -67,7 +67,6 @@ use crate::{ contract_messages::TopicNameHash, contracts::{Contract, ContractHash}, system::SystemEntityType, - transaction::TransactionRuntime, uref::{self, URef}, AccessRights, ApiError, CLType, CLTyped, CLValue, CLValueError, ContextAccessRights, HashAddr, Key, NamedKeys, PackageHash, ProtocolVersion, PublicKey, Tagged, BLAKE2B_DIGEST_LENGTH, @@ -507,6 +506,73 @@ impl Distribution for Standard { } } +#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize, Debug)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr( + feature = "json-schema", + derive(JsonSchema), + schemars(description = "Runtime used to execute a Transaction.") +)] +#[serde(deny_unknown_fields)] +#[repr(u8)] +pub enum ContractRuntimeTag { + VmCasperV1, + VmCasperV2, +} + +#[cfg(any(feature = "testing", test))] +impl Distribution for Standard { + fn sample(&self, rng: &mut R) -> ContractRuntimeTag { + match rng.gen_range(0..=1) { + 0 => ContractRuntimeTag::VmCasperV1, + 1 => ContractRuntimeTag::VmCasperV2, + _ => unreachable!(), + } + } +} + +impl ToBytes for ContractRuntimeTag { + fn to_bytes(&self) -> Result, bytesrepr::Error> { + (*self as u8).to_bytes() + } + + fn serialized_length(&self) -> usize { + U8_SERIALIZED_LENGTH + } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + (*self as u8).write_bytes(writer) + } +} + +impl FromBytes for ContractRuntimeTag { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (tag, remainder) = u8::from_bytes(bytes)?; + if tag == ContractRuntimeTag::VmCasperV1 as u8 { + Ok((ContractRuntimeTag::VmCasperV1, remainder)) + } else if tag == ContractRuntimeTag::VmCasperV2 as u8 { + Ok((ContractRuntimeTag::VmCasperV2, remainder)) + } else { + Err(bytesrepr::Error::Formatting) + } + } +} + +impl Display for ContractRuntimeTag { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + ContractRuntimeTag::VmCasperV1 => write!(f, "vm-casper-v1"), + ContractRuntimeTag::VmCasperV2 => write!(f, "vm-casper-v2"), + } + } +} +impl ContractRuntimeTag { + /// Returns the tag of the [`ContractRuntimeTag`]. + pub fn tag(&self) -> u8 { + *self as u8 + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] @@ -517,7 +583,7 @@ pub enum EntityKind { /// Package associated with an Account hash. Account(AccountHash), /// Packages associated with Wasm stored on chain. - SmartContract(TransactionRuntime), + SmartContract(ContractRuntimeTag), } impl EntityKind { @@ -632,7 +698,7 @@ impl FromBytes for EntityKind { Ok((EntityKind::Account(account_hash), remainder)) } EntityKindTag::SmartContract => { - let (transaction_runtime, remainder) = TransactionRuntime::from_bytes(remainder)?; + let (transaction_runtime, remainder) = FromBytes::from_bytes(remainder)?; Ok((EntityKind::SmartContract(transaction_runtime), remainder)) } } @@ -1670,7 +1736,7 @@ impl Default for AddressableEntity { main_purse: URef::default(), action_thresholds: ActionThresholds::default(), associated_keys: AssociatedKeys::default(), - entity_kind: EntityKind::SmartContract(TransactionRuntime::VmCasperV1), + entity_kind: EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1), } } } @@ -1684,7 +1750,7 @@ impl From for AddressableEntity { URef::default(), AssociatedKeys::default(), ActionThresholds::default(), - EntityKind::SmartContract(TransactionRuntime::VmCasperV1), + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1), ) } } @@ -1865,7 +1931,7 @@ mod tests { associated_keys, ActionThresholds::new(Weight::new(1), Weight::new(1), Weight::new(1)) .expect("should create thresholds"), - EntityKind::SmartContract(TransactionRuntime::VmCasperV1), + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1), ); let access_rights = contract.extract_access_rights(entity_hash, &named_keys); let expected_uref = URef::new([42; UREF_ADDR_LENGTH], AccessRights::READ_ADD_WRITE); diff --git a/types/src/gens.rs b/types/src/gens.rs index 71661bf71c..59f728f164 100644 --- a/types/src/gens.rs +++ b/types/src/gens.rs @@ -18,7 +18,7 @@ use crate::{ }, addressable_entity::{ action_thresholds::gens::action_thresholds_arb, associated_keys::gens::associated_keys_arb, - MessageTopics, NamedKeyAddr, NamedKeyValue, Parameters, Weight, + ContractRuntimeTag, MessageTopics, NamedKeyAddr, NamedKeyValue, Parameters, Weight, }, block::BlockGlobalAddr, byte_code::ByteCodeKind, @@ -47,7 +47,7 @@ use crate::{ }, transaction::{ gens::deploy_hash_arb, FieldsContainer, InitiatorAddrAndSecretKey, TransactionArgs, - TransactionV1Payload, + TransactionRuntimeParams, TransactionV1Payload, }, transfer::{ gens::{transfer_v1_addr_arb, transfer_v1_arb}, @@ -58,8 +58,8 @@ use crate::{ EntryPointPayment, EntryPointType, EntryPoints, EraId, Group, InitiatorAddr, Key, NamedArg, Package, Parameter, Phase, PricingMode, ProtocolVersion, PublicKey, RuntimeArgs, SemVer, StoredValue, TimeDiff, Timestamp, Transaction, TransactionEntryPoint, - TransactionInvocationTarget, TransactionRuntime, TransactionScheduling, TransactionTarget, - TransactionV1, URef, U128, U256, U512, + TransactionInvocationTarget, TransactionScheduling, TransactionTarget, TransactionV1, URef, + U128, U256, U512, }; use proptest::{ array, bits, bool, @@ -627,10 +627,10 @@ pub fn system_entity_type_arb() -> impl Strategy { ] } -pub fn transaction_runtime_arb() -> impl Strategy { +pub fn contract_runtime_arb() -> impl Strategy { prop_oneof![ - Just(TransactionRuntime::VmCasperV1), - Just(TransactionRuntime::VmCasperV2), + Just(ContractRuntimeTag::VmCasperV1), + Just(ContractRuntimeTag::VmCasperV2), ] } @@ -638,7 +638,7 @@ pub fn entity_kind_arb() -> impl Strategy { prop_oneof![ system_entity_type_arb().prop_map(EntityKind::System), account_hash_arb().prop_map(EntityKind::Account), - transaction_runtime_arb().prop_map(EntityKind::SmartContract), + contract_runtime_arb().prop_map(EntityKind::SmartContract), ] } @@ -1108,25 +1108,58 @@ pub fn transaction_invocation_target_arb() -> impl Strategy impl Strategy { ( transaction_invocation_target_arb(), - transaction_runtime_arb(), - any::(), + transaction_stored_runtime_params_arb(), ) - .prop_map(|(target, runtime, transferred_value)| { - TransactionTarget::new_stored(target, runtime, transferred_value) - }) + .prop_map(|(id, runtime)| TransactionTarget::Stored { id, runtime }) +} + +fn transferred_value_arb() -> impl Strategy { + any::() +} + +fn seed_arb() -> impl Strategy> { + option::of(array::uniform32(any::())) } pub fn session_transaction_target() -> impl Strategy { ( any::(), Just(Bytes::from(vec![1; 10])), - transaction_runtime_arb(), - any::(), - any::>(), + transaction_session_runtime_params_arb(), ) - .prop_map(|(target, module_bytes, runtime, transferred_value, seed)| { - TransactionTarget::new_session(target, module_bytes, runtime, transferred_value, seed) + .prop_map( + |(is_install_upgrade, module_bytes, runtime)| TransactionTarget::Session { + is_install_upgrade, + module_bytes, + runtime, + }, + ) +} + +pub(crate) fn transaction_stored_runtime_params_arb( +) -> impl Strategy { + prop_oneof![ + Just(TransactionRuntimeParams::VmCasperV1), + transferred_value_arb().prop_map(|transferred_value| { + TransactionRuntimeParams::VmCasperV2 { + transferred_value, + seed: None, + } + }), + ] +} + +pub(crate) fn transaction_session_runtime_params_arb( +) -> impl Strategy { + prop_oneof![ + Just(TransactionRuntimeParams::VmCasperV1), + (transferred_value_arb(), seed_arb()).prop_map(|(transferred_value, seed)| { + TransactionRuntimeParams::VmCasperV2 { + transferred_value, + seed, + } }) + ] } pub fn transaction_target_arb() -> impl Strategy { @@ -1134,34 +1167,21 @@ pub fn transaction_target_arb() -> impl Strategy { Just(TransactionTarget::Native), ( transaction_invocation_target_arb(), - transaction_runtime_arb(), - any::(), + transaction_stored_runtime_params_arb(), ) - .prop_map( - |(target, runtime, transferred_value)| TransactionTarget::new_stored( - target, - runtime, - transferred_value - ) - ), + .prop_map(|(id, runtime)| TransactionTarget::Stored { id, runtime }), ( any::(), Just(Bytes::from(vec![1; 10])), - transaction_runtime_arb(), - any::(), - any::>(), + transaction_session_runtime_params_arb(), ) - .prop_map( - |(is_install_upgrade, module_bytes, runtime, transferred_value, seed)| { - TransactionTarget::new_session( - is_install_upgrade, - module_bytes, - runtime, - transferred_value, - seed, - ) + .prop_map(|(is_install_upgrade, module_bytes, runtime)| { + TransactionTarget::Session { + is_install_upgrade, + module_bytes, + runtime, } - ) + }) ] } diff --git a/types/src/key.rs b/types/src/key.rs index e2d91fd755..455cf5bce8 100644 --- a/types/src/key.rs +++ b/types/src/key.rs @@ -1002,8 +1002,8 @@ impl Key { // } // } - /// Returns the inner bytes of `self` if `self` is of type [`Key::Package`], otherwise returns - /// `None`. + /// Returns the inner bytes of `self` if `self` is of type [`Key::SmartContract`], otherwise + /// returns `None`. pub fn into_package_addr(self) -> Option { match self { Key::Hash(hash) => Some(hash), @@ -1019,7 +1019,7 @@ impl Key { Some(AddressableEntityHash::new(entity_addr)) } - /// Returns [`PackageHash`] of `self` if `self` is of type [`Key::Package`], otherwise + /// Returns [`PackageHash`] of `self` if `self` is of type [`Key::SmartContract`], otherwise /// returns `None`. pub fn into_package_hash(self) -> Option { let package_addr = self.into_package_addr()?; diff --git a/types/src/lib.rs b/types/src/lib.rs index 89691c7317..fddd2454a2 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -88,9 +88,9 @@ pub use access_rights::{ pub use account::Account; #[doc(inline)] pub use addressable_entity::{ - AddressableEntity, AddressableEntityHash, EntityAddr, EntityKind, EntryPoint, EntryPointAccess, - EntryPointAddr, EntryPointPayment, EntryPointType, EntryPointValue, EntryPoints, Parameter, - Parameters, DEFAULT_ENTRY_POINT_NAME, + AddressableEntity, AddressableEntityHash, ContractRuntimeTag, EntityAddr, EntityKind, + EntryPoint, EntryPointAccess, EntryPointAddr, EntryPointPayment, EntryPointType, + EntryPointValue, EntryPoints, Parameter, Parameters, DEFAULT_ENTRY_POINT_NAME, }; #[doc(inline)] pub use api_error::ApiError; @@ -197,7 +197,7 @@ pub use transaction::{ InvalidDeploy, InvalidTransaction, InvalidTransactionV1, NamedArg, PackageIdentifier, PricingMode, PricingModeError, RuntimeArgs, Transaction, TransactionArgs, TransactionEntryPoint, TransactionHash, TransactionId, TransactionInvocationTarget, - TransactionRuntime, TransactionScheduling, TransactionTarget, TransactionV1, + TransactionRuntimeParams, TransactionScheduling, TransactionTarget, TransactionV1, TransactionV1DecodeFromJsonError, TransactionV1Error, TransactionV1ExcessiveSizeError, TransactionV1Hash, TransactionV1Payload, TransferTarget, }; diff --git a/types/src/runtime_footprint.rs b/types/src/runtime_footprint.rs index bbc4f75ec0..0da5669453 100644 --- a/types/src/runtime_footprint.rs +++ b/types/src/runtime_footprint.rs @@ -1,10 +1,10 @@ use crate::{ account::AccountHash, - addressable_entity::{AssociatedKeys, Weight}, + addressable_entity::{AssociatedKeys, ContractRuntimeTag, Weight}, contracts::{ContractHash, NamedKeys}, system::SystemEntityType, Account, AddressableEntity, ContextAccessRights, Contract, EntityAddr, EntityKind, EntryPoints, - HashAddr, Key, ProtocolVersion, TransactionRuntime, URef, + HashAddr, Key, ProtocolVersion, URef, }; use alloc::{ collections::{BTreeMap, BTreeSet}, @@ -164,7 +164,7 @@ impl RuntimeFootprint { let associated_keys = AssociatedKeys::empty_keys(); let entity_kind = match system_entity_type { - None => EntityKind::SmartContract(TransactionRuntime::VmCasperV1), + None => EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1), Some(kind) => EntityKind::System(kind), }; diff --git a/types/src/transaction.rs b/types/src/transaction.rs index 7eb3b0eda9..1f5398b2e5 100644 --- a/types/src/transaction.rs +++ b/types/src/transaction.rs @@ -15,7 +15,6 @@ mod transaction_entry_point; mod transaction_hash; mod transaction_id; mod transaction_invocation_target; -mod transaction_runtime; mod transaction_scheduling; mod transaction_target; mod transaction_v1; @@ -80,9 +79,8 @@ pub use transaction_entry_point::TransactionEntryPoint; pub use transaction_hash::TransactionHash; pub use transaction_id::TransactionId; pub use transaction_invocation_target::TransactionInvocationTarget; -pub use transaction_runtime::TransactionRuntime; pub use transaction_scheduling::TransactionScheduling; -pub use transaction_target::TransactionTarget; +pub use transaction_target::{TransactionRuntimeParams, TransactionTarget}; #[cfg(feature = "json-schema")] pub(crate) use transaction_v1::arg_handling; #[cfg(any(feature = "std", feature = "testing", feature = "gens", test))] diff --git a/types/src/transaction/transaction_runtime.rs b/types/src/transaction/transaction_runtime.rs deleted file mode 100644 index 5a07c3977f..0000000000 --- a/types/src/transaction/transaction_runtime.rs +++ /dev/null @@ -1,113 +0,0 @@ -use alloc::vec::Vec; -use core::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}; - -#[cfg(doc)] -use super::Transaction; -use crate::bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}; -#[cfg(any(all(feature = "std", feature = "testing"), test))] -use crate::testing::TestRng; - -/// The runtime used to execute a [`Transaction`]. -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize, Debug)] -#[cfg_attr(feature = "datasize", derive(DataSize))] -#[cfg_attr( - feature = "json-schema", - derive(JsonSchema), - schemars(description = "Runtime used to execute a Transaction.") -)] -#[serde(deny_unknown_fields)] -#[repr(u8)] -pub enum TransactionRuntime { - /// The Casper Version 1 Virtual Machine. - VmCasperV1, - /// The Casper Version 2 Virtual Machine. - VmCasperV2, -} - -impl Display for TransactionRuntime { - fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { - match self { - TransactionRuntime::VmCasperV1 => write!(formatter, "vm-casper-v1"), - TransactionRuntime::VmCasperV2 => write!(formatter, "vm-casper-v2"), - } - } -} - -impl ToBytes for TransactionRuntime { - fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - (*self as u8).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 - } -} - -impl FromBytes for TransactionRuntime { - fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (tag, remainder) = u8::from_bytes(bytes)?; - match tag { - v if v == TransactionRuntime::VmCasperV1 as u8 => { - Ok((TransactionRuntime::VmCasperV1, remainder)) - } - v if v == TransactionRuntime::VmCasperV2 as u8 => { - Ok((TransactionRuntime::VmCasperV2, remainder)) - } - _ => Err(bytesrepr::Error::Formatting), - } - } -} - -#[cfg(any(all(feature = "std", feature = "testing"), test))] -impl TransactionRuntime { - /// Generates a random instance using a `TestRng`. - pub fn random(rng: &mut TestRng) -> Self { - match rng.gen_range(0..=1) { - 0 => TransactionRuntime::VmCasperV1, - 1 => TransactionRuntime::VmCasperV2, - _ => unreachable!(), - } - } -} - -#[cfg(any(feature = "testing", test))] -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> TransactionRuntime { - match rng.gen_range(0..=1) { - 0 => TransactionRuntime::VmCasperV1, - 1 => TransactionRuntime::VmCasperV2, - _ => unreachable!(), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn bytesrepr_roundtrip() { - for transaction_runtime in [ - TransactionRuntime::VmCasperV1, - TransactionRuntime::VmCasperV2, - ] { - bytesrepr::test_serialization_roundtrip(&transaction_runtime); - } - } -} diff --git a/types/src/transaction/transaction_target.rs b/types/src/transaction/transaction_target.rs index 9fd2f77942..ef22eb1dcb 100644 --- a/types/src/transaction/transaction_target.rs +++ b/types/src/transaction/transaction_target.rs @@ -1,9 +1,7 @@ use alloc::vec::Vec; use core::fmt::{self, Debug, Display, Formatter}; -use super::{ - serialization::CalltableSerializationEnvelope, TransactionInvocationTarget, TransactionRuntime, -}; +use super::{serialization::CalltableSerializationEnvelope, TransactionInvocationTarget}; #[cfg(any(feature = "testing", test))] use crate::testing::TestRng; use crate::{ @@ -13,7 +11,7 @@ use crate::{ FromBytes, ToBytes, }, transaction::serialization::CalltableSerializationEnvelopeBuilder, - HashAddr, + ContractRuntimeTag, HashAddr, }; #[cfg(feature = "datasize")] use datasize::DataSize; @@ -23,6 +21,154 @@ use rand::{Rng, RngCore}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +const VM_CASPER_V1_TAG: u8 = 0; +const VM_CASPER_V2_TAG: u8 = 1; +const TRANSFERRED_VALUE_INDEX: u16 = 1; +const SEED_VALUE_INDEX: u16 = 2; + +#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize, Debug)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr( + feature = "json-schema", + derive(JsonSchema), + schemars(description = "Session params of a TransactionTarget.") +)] +#[serde(deny_unknown_fields)] +pub enum TransactionRuntimeParams { + VmCasperV1, + VmCasperV2 { + /// The amount of motes to transfer before code is executed. + /// + /// This is for protection against phishing attack where a malicious session code drains + /// the balance of the caller account. The amount stated here is the maximum amount + /// that can be transferred from the caller account to the session account. + transferred_value: u64, + /// The seed for the session code that is used for an installer. + seed: Option<[u8; 32]>, + }, +} + +impl TransactionRuntimeParams { + /// Returns the contract runtime tag. + pub fn contract_runtime_tag(&self) -> ContractRuntimeTag { + match self { + TransactionRuntimeParams::VmCasperV1 => ContractRuntimeTag::VmCasperV1, + TransactionRuntimeParams::VmCasperV2 { .. } => ContractRuntimeTag::VmCasperV2, + } + } + + pub fn seed(&self) -> Option<[u8; 32]> { + match self { + TransactionRuntimeParams::VmCasperV1 => None, + TransactionRuntimeParams::VmCasperV2 { seed, .. } => *seed, + } + } + + pub fn serialized_field_lengths(&self) -> Vec { + match self { + TransactionRuntimeParams::VmCasperV1 => vec![crate::bytesrepr::U8_SERIALIZED_LENGTH], + TransactionRuntimeParams::VmCasperV2 { + transferred_value, + seed, + } => { + vec![ + crate::bytesrepr::U8_SERIALIZED_LENGTH, + transferred_value.serialized_length(), + seed.serialized_length(), + ] + } + } + } +} + +impl ToBytes for TransactionRuntimeParams { + fn to_bytes(&self) -> Result, Error> { + match self { + TransactionRuntimeParams::VmCasperV1 => { + CalltableSerializationEnvelopeBuilder::new(self.serialized_field_lengths())? + .add_field(TAG_FIELD_INDEX, &VM_CASPER_V1_TAG)? + .binary_payload_bytes() + } + TransactionRuntimeParams::VmCasperV2 { + transferred_value, + seed, + } => CalltableSerializationEnvelopeBuilder::new(self.serialized_field_lengths())? + .add_field(TAG_FIELD_INDEX, &VM_CASPER_V2_TAG)? + .add_field(TRANSFERRED_VALUE_INDEX, transferred_value)? + .add_field(SEED_VALUE_INDEX, seed)? + .binary_payload_bytes(), + } + } + + fn serialized_length(&self) -> usize { + match self { + TransactionRuntimeParams::VmCasperV1 => { + CalltableSerializationEnvelope::estimate_size(vec![ + crate::bytesrepr::U8_SERIALIZED_LENGTH, + ]) + } + TransactionRuntimeParams::VmCasperV2 { + transferred_value, + seed, + } => CalltableSerializationEnvelope::estimate_size(vec![ + crate::bytesrepr::U8_SERIALIZED_LENGTH, + transferred_value.serialized_length(), + seed.serialized_length(), + ]), + } + } +} + +impl FromBytes for TransactionRuntimeParams { + fn from_bytes(bytes: &[u8]) -> Result<(TransactionRuntimeParams, &[u8]), Error> { + let (binary_payload, remainder) = CalltableSerializationEnvelope::from_bytes(3, bytes)?; + let window = binary_payload.start_consuming()?.ok_or(Formatting)?; + window.verify_index(TAG_FIELD_INDEX)?; + let (tag, window) = window.deserialize_and_maybe_next::()?; + let to_ret = match tag { + VM_CASPER_V1_TAG => { + if window.is_some() { + return Err(Formatting); + } + Ok(TransactionRuntimeParams::VmCasperV1) + } + VM_CASPER_V2_TAG => { + let window = window.ok_or(Formatting)?; + window.verify_index(TRANSFERRED_VALUE_INDEX)?; + let (transferred_value, window) = window.deserialize_and_maybe_next::()?; + let window = window.ok_or(Formatting)?; + window.verify_index(SEED_VALUE_INDEX)?; + let (seed, window) = window.deserialize_and_maybe_next::>()?; + if window.is_some() { + return Err(Formatting); + } + Ok(TransactionRuntimeParams::VmCasperV2 { + transferred_value, + seed, + }) + } + _ => Err(Formatting), + }; + to_ret.map(|endpoint| (endpoint, remainder)) + } +} + +impl Display for TransactionRuntimeParams { + fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { + match self { + TransactionRuntimeParams::VmCasperV1 => write!(formatter, "vm-casper-v1"), + TransactionRuntimeParams::VmCasperV2 { + transferred_value, + seed, + } => write!( + formatter, + "vm-casper-v2 {{ transferred_value: {}, seed: {:?} }}", + transferred_value, seed + ), + } + } +} + /// The execution target of a [`crate::Transaction`]. #[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize)] #[cfg_attr(feature = "datasize", derive(DataSize))] @@ -40,26 +186,16 @@ pub enum TransactionTarget { /// The identifier of the stored execution target. id: TransactionInvocationTarget, /// The execution runtime to use. - runtime: TransactionRuntime, - /// The amount of motes to transfer before code is executed. - transferred_value: u64, + runtime: TransactionRuntimeParams, }, /// The execution target is the included module bytes, i.e. compiled Wasm. Session { /// Flag determining if the Wasm is an install/upgrade. is_install_upgrade: bool, - /// The execution runtime to use. - runtime: TransactionRuntime, /// The compiled Wasm. module_bytes: Bytes, - /// The amount of motes to transfer before code is executed. - /// - /// This is for protection against phishing attack where a malicious session code drains - /// the balance of the caller account. The amount stated here is the maximum amount - /// that can be transferred from the caller account to the session account. - transferred_value: u64, - /// The seed for the session code that is used for an installer. - seed: Option<[u8; 32]>, + /// The execution runtime to use. + runtime: TransactionRuntimeParams, }, } @@ -69,67 +205,28 @@ impl TransactionTarget { TransactionTarget::Native } - /// Returns a new `TransactionTarget::Stored`. - pub fn new_stored( - id: TransactionInvocationTarget, - runtime: TransactionRuntime, - transferred_value: u64, - ) -> Self { - TransactionTarget::Stored { - id, - runtime, - transferred_value, - } - } - - /// Returns a new `TransactionTarget::Session`. - pub fn new_session( - is_install_upgrade: bool, - module_bytes: Bytes, - runtime: TransactionRuntime, - transferred_value: u64, - seed: Option<[u8; 32]>, - ) -> Self { - TransactionTarget::Session { - is_install_upgrade, - module_bytes, - runtime, - transferred_value, - seed, - } - } - fn serialized_field_lengths(&self) -> Vec { match self { TransactionTarget::Native => { vec![crate::bytesrepr::U8_SERIALIZED_LENGTH] } - TransactionTarget::Stored { - id, - runtime, - transferred_value, - } => { + TransactionTarget::Stored { id, runtime } => { vec![ crate::bytesrepr::U8_SERIALIZED_LENGTH, id.serialized_length(), runtime.serialized_length(), - transferred_value.serialized_length(), ] } TransactionTarget::Session { is_install_upgrade, - runtime, - transferred_value, - seed, module_bytes, + runtime, } => { vec![ crate::bytesrepr::U8_SERIALIZED_LENGTH, is_install_upgrade.serialized_length(), runtime.serialized_length(), module_bytes.serialized_length(), - transferred_value.serialized_length(), - seed.serialized_length(), ] } } @@ -157,22 +254,19 @@ impl TransactionTarget { pub fn random(rng: &mut TestRng) -> Self { match rng.gen_range(0..3) { 0 => TransactionTarget::Native, - 1 => TransactionTarget::new_stored( - TransactionInvocationTarget::random(rng), - TransactionRuntime::VmCasperV1, - rng.gen(), - ), + 1 => TransactionTarget::Stored { + id: TransactionInvocationTarget::random(rng), + runtime: TransactionRuntimeParams::VmCasperV1, + }, 2 => { let mut buffer = vec![0u8; rng.gen_range(0..100)]; rng.fill_bytes(buffer.as_mut()); let is_install_upgrade = rng.gen(); - TransactionTarget::new_session( + TransactionTarget::Session { is_install_upgrade, - Bytes::from(buffer), - TransactionRuntime::VmCasperV1, - rng.gen(), - None, - ) + module_bytes: Bytes::from(buffer), + runtime: TransactionRuntimeParams::VmCasperV1, + } } _ => unreachable!(), } @@ -194,14 +288,11 @@ const NATIVE_VARIANT: u8 = 0; const STORED_VARIANT: u8 = 1; const STORED_ID_INDEX: u16 = 1; const STORED_RUNTIME_INDEX: u16 = 2; -const STORED_TRANSFERRED_VALUE_INDEX: u16 = 3; const SESSION_VARIANT: u8 = 2; const SESSION_IS_INSTALL_INDEX: u16 = 1; const SESSION_RUNTIME_INDEX: u16 = 2; const SESSION_MODULE_BYTES_INDEX: u16 = 3; -const SESSION_TRANSFERRED_VALUE_INDEX: u16 = 4; -const SESSION_SEED_INDEX: u16 = 5; impl ToBytes for TransactionTarget { fn to_bytes(&self) -> Result, Error> { @@ -211,29 +302,22 @@ impl ToBytes for TransactionTarget { .add_field(TAG_FIELD_INDEX, &NATIVE_VARIANT)? .binary_payload_bytes() } - TransactionTarget::Stored { - id, - runtime, - transferred_value, - } => CalltableSerializationEnvelopeBuilder::new(self.serialized_field_lengths())? - .add_field(TAG_FIELD_INDEX, &STORED_VARIANT)? - .add_field(STORED_ID_INDEX, &id)? - .add_field(STORED_RUNTIME_INDEX, &runtime)? - .add_field(STORED_TRANSFERRED_VALUE_INDEX, transferred_value)? - .binary_payload_bytes(), + TransactionTarget::Stored { id, runtime } => { + CalltableSerializationEnvelopeBuilder::new(self.serialized_field_lengths())? + .add_field(TAG_FIELD_INDEX, &STORED_VARIANT)? + .add_field(STORED_ID_INDEX, &id)? + .add_field(STORED_RUNTIME_INDEX, &runtime)? + .binary_payload_bytes() + } TransactionTarget::Session { is_install_upgrade, module_bytes, runtime, - transferred_value, - seed, } => CalltableSerializationEnvelopeBuilder::new(self.serialized_field_lengths())? .add_field(TAG_FIELD_INDEX, &SESSION_VARIANT)? .add_field(SESSION_IS_INSTALL_INDEX, &is_install_upgrade)? .add_field(SESSION_RUNTIME_INDEX, &runtime)? .add_field(SESSION_MODULE_BYTES_INDEX, &module_bytes)? - .add_field(SESSION_TRANSFERRED_VALUE_INDEX, transferred_value)? - .add_field(SESSION_SEED_INDEX, seed)? .binary_payload_bytes(), } } @@ -264,18 +348,11 @@ impl FromBytes for TransactionTarget { let window = window.ok_or(Formatting)?; window.verify_index(STORED_RUNTIME_INDEX)?; let (runtime, window) = - window.deserialize_and_maybe_next::()?; - let window = window.ok_or(Formatting)?; - window.verify_index(STORED_TRANSFERRED_VALUE_INDEX)?; - let (transferred_value, window) = window.deserialize_and_maybe_next::()?; + window.deserialize_and_maybe_next::()?; if window.is_some() { return Err(Formatting); } - Ok(TransactionTarget::Stored { - id, - runtime, - transferred_value, - }) + Ok(TransactionTarget::Stored { id, runtime }) } SESSION_VARIANT => { let window = window.ok_or(Formatting)?; @@ -284,18 +361,10 @@ impl FromBytes for TransactionTarget { let window = window.ok_or(Formatting)?; window.verify_index(SESSION_RUNTIME_INDEX)?; let (runtime, window) = - window.deserialize_and_maybe_next::()?; + window.deserialize_and_maybe_next::()?; let window = window.ok_or(Formatting)?; window.verify_index(SESSION_MODULE_BYTES_INDEX)?; let (module_bytes, window) = window.deserialize_and_maybe_next::()?; - let window = window.ok_or(Formatting)?; - - window.verify_index(SESSION_TRANSFERRED_VALUE_INDEX)?; - let (transferred_value, window) = window.deserialize_and_maybe_next::()?; - let window = window.ok_or(Formatting)?; - - window.verify_index(SESSION_SEED_INDEX)?; - let (seed, window) = window.deserialize_and_maybe_next::>()?; if window.is_some() { return Err(Formatting); @@ -304,8 +373,6 @@ impl FromBytes for TransactionTarget { is_install_upgrade, module_bytes, runtime, - transferred_value, - seed, }) } _ => Err(Formatting), @@ -318,31 +385,19 @@ impl Display for TransactionTarget { fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { match self { TransactionTarget::Native => write!(formatter, "native"), - TransactionTarget::Stored { - id, - runtime, - transferred_value, - } => { - write!( - formatter, - "stored({}, {}, {})", - id, runtime, transferred_value - ) + TransactionTarget::Stored { id, runtime } => { + write!(formatter, "stored({}, {})", id, runtime,) } TransactionTarget::Session { is_install_upgrade, module_bytes, runtime, - transferred_value, - seed, } => write!( formatter, - "session({} module bytes, runtime: {}, is_install_upgrade: {}, transferred_value: {}, seed: {:?})", + "session({} module bytes, runtime: {}, is_install_upgrade: {})", module_bytes.len(), runtime, is_install_upgrade, - transferred_value, - seed, ), } } @@ -352,22 +407,15 @@ impl Debug for TransactionTarget { fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { match self { TransactionTarget::Native => formatter.debug_struct("Native").finish(), - TransactionTarget::Stored { - id, - runtime, - transferred_value, - } => formatter + TransactionTarget::Stored { id, runtime } => formatter .debug_struct("Stored") .field("id", id) .field("runtime", runtime) - .field("transferred_value", transferred_value) .finish(), TransactionTarget::Session { is_install_upgrade, module_bytes, runtime, - transferred_value, - seed, } => { struct BytesLen(usize); impl Debug for BytesLen { @@ -379,10 +427,8 @@ impl Debug for TransactionTarget { formatter .debug_struct("Session") .field("module_bytes", &BytesLen(module_bytes.len())) - .field("runtime", runtime) .field("is_install_upgrade", is_install_upgrade) - .field("transferred_value", transferred_value) - .field("seed", seed) + .field("runtime", runtime) .finish() } } diff --git a/types/src/transaction/transaction_v1/errors_v1.rs b/types/src/transaction/transaction_v1/errors_v1.rs index aa48151e3a..afa9589df7 100644 --- a/types/src/transaction/transaction_v1/errors_v1.rs +++ b/types/src/transaction/transaction_v1/errors_v1.rs @@ -13,8 +13,8 @@ use serde::Serialize; #[cfg(doc)] use super::TransactionV1; use crate::{ - bytesrepr, crypto, CLType, DisplayIter, PricingMode, TimeDiff, Timestamp, - TransactionEntryPoint, TransactionRuntime, U512, + addressable_entity::ContractRuntimeTag, bytesrepr, crypto, CLType, DisplayIter, PricingMode, + TimeDiff, Timestamp, TransactionEntryPoint, U512, }; #[derive(Clone, Eq, PartialEq, Debug)] @@ -196,7 +196,7 @@ pub enum InvalidTransaction { /// The transaction runtime is invalid. InvalidTransactionRuntime { /// The expected runtime as specified by the chainspec. - expected: TransactionRuntime, + expected: ContractRuntimeTag, }, /// The transaction is missing a seed field. MissingSeed, diff --git a/types/src/transaction/transaction_v1/fields_container.rs b/types/src/transaction/transaction_v1/fields_container.rs index 9a714d436a..985f31da8e 100644 --- a/types/src/transaction/transaction_v1/fields_container.rs +++ b/types/src/transaction/transaction_v1/fields_container.rs @@ -8,8 +8,8 @@ use crate::{ }; #[cfg(any(feature = "testing", test))] use crate::{ - PublicKey, RuntimeArgs, TransactionInvocationTarget, TransactionRuntime, TransferTarget, - AUCTION_LANE_ID, INSTALL_UPGRADE_LANE_ID, MINT_LANE_ID, + PublicKey, RuntimeArgs, TransactionInvocationTarget, TransferTarget, AUCTION_LANE_ID, + INSTALL_UPGRADE_LANE_ID, MINT_LANE_ID, }; #[cfg(any(feature = "std", feature = "testing", test))] use alloc::collections::BTreeMap; @@ -194,9 +194,7 @@ impl FieldsContainer { let target = TransactionTarget::Session { is_install_upgrade, module_bytes: Bytes::from(buffer), - runtime: TransactionRuntime::VmCasperV1, - transferred_value: rng.gen(), - seed: rng.gen(), + runtime: crate::TransactionRuntimeParams::VmCasperV1, }; FieldsContainer::new( TransactionArgs::Named(RuntimeArgs::random(rng)), @@ -239,10 +237,8 @@ impl FieldsContainer { fn random_install_upgrade(rng: &mut TestRng) -> Self { let target = TransactionTarget::Session { module_bytes: Bytes::from(rng.random_vec(0..100)), - runtime: TransactionRuntime::VmCasperV1, + runtime: crate::TransactionRuntimeParams::VmCasperV1, is_install_upgrade: true, - transferred_value: 0, - seed: None, }; FieldsContainer::new( TransactionArgs::Named(RuntimeArgs::random(rng)), @@ -282,8 +278,7 @@ impl FieldsContainer { fn random_standard(rng: &mut TestRng) -> Self { let target = TransactionTarget::Stored { id: TransactionInvocationTarget::random(rng), - runtime: TransactionRuntime::VmCasperV1, - transferred_value: rng.gen(), + runtime: crate::transaction::transaction_target::TransactionRuntimeParams::VmCasperV1, }; FieldsContainer::new( TransactionArgs::Named(RuntimeArgs::random(rng)), diff --git a/utils/validation/src/generators.rs b/utils/validation/src/generators.rs index c2f98cbddf..4df366bf48 100644 --- a/utils/validation/src/generators.rs +++ b/utils/validation/src/generators.rs @@ -18,10 +18,10 @@ use casper_types::{ mint::BalanceHoldAddr, }, AccessRights, AddressableEntityHash, BlockTime, ByteCode, ByteCodeHash, ByteCodeKind, CLType, - CLTyped, CLValue, DeployHash, DeployInfo, EntityVersionKey, EntityVersions, EntryPoint, - EntryPointAccess, EntryPointPayment, EntryPointType, EntryPointValue, EraId, Group, Groups, - Key, Package, PackageHash, PackageStatus, Parameter, ProtocolVersion, PublicKey, SecretKey, - StoredValue, TransactionRuntime, TransferAddr, TransferV1, URef, U512, + CLTyped, CLValue, ContractRuntimeTag, DeployHash, DeployInfo, EntityVersionKey, EntityVersions, + EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, EntryPointValue, EraId, Group, + Groups, Key, Package, PackageHash, PackageStatus, Parameter, ProtocolVersion, PublicKey, + SecretKey, StoredValue, TransferAddr, TransferV1, URef, U512, }; use casper_validation::{ abi::{ABIFixture, ABITestCase}, @@ -395,7 +395,7 @@ pub fn make_abi_test_fixtures() -> Result { URef::default(), AssociatedKeys::default(), ActionThresholds::default(), - EntityKind::SmartContract(TransactionRuntime::VmCasperV1), + EntityKind::SmartContract(ContractRuntimeTag::VmCasperV1), ); stored_value.insert( "AddressableEntity".to_string(),