diff --git a/Cargo.lock b/Cargo.lock index f60a05e5f3..8de18c6d49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4810,6 +4810,14 @@ dependencies = [ "winreg", ] +[[package]] +name = "ret-uref" +version = "0.1.0" +dependencies = [ + "casper-contract", + "casper-types", +] + [[package]] name = "revert" version = "0.1.0" @@ -6052,6 +6060,22 @@ dependencies = [ "casper-types", ] +[[package]] +name = "upgrade-threshold" +version = "0.1.0" +dependencies = [ + "casper-contract", + "casper-types", +] + +[[package]] +name = "upgrade-threshold-upgrader" +version = "0.1.0" +dependencies = [ + "casper-contract", + "casper-types", +] + [[package]] name = "url" version = "2.4.0" diff --git a/execution_engine/benches/trie_bench.rs b/execution_engine/benches/trie_bench.rs index 99a55bc5fa..2209796734 100644 --- a/execution_engine/benches/trie_bench.rs +++ b/execution_engine/benches/trie_bench.rs @@ -4,11 +4,15 @@ use casper_storage::global_state::trie::{Pointer, PointerBlock, Trie}; use casper_types::{ account::AccountHash, bytesrepr::{FromBytes, ToBytes}, - CLValue, ContractHash, Digest, Key, StoredValue, + package::PackageKindTag, + AddressableEntityHash, CLValue, Digest, Key, StoredValue, }; fn serialize_trie_leaf(b: &mut Bencher) { - let contract_key: Key = ContractHash::new([42; 32]).into(); + let contract_key = Key::addressable_entity_key( + PackageKindTag::SmartContract, + AddressableEntityHash::new([42; 32]), + ); let leaf = Trie::Leaf { key: Key::Account(AccountHash::new([0; 32])), value: StoredValue::CLValue(CLValue::from_t(contract_key).unwrap()), @@ -17,7 +21,10 @@ fn serialize_trie_leaf(b: &mut Bencher) { } fn deserialize_trie_leaf(b: &mut Bencher) { - let contract_key: Key = ContractHash::new([42; 32]).into(); + let contract_key: Key = Key::addressable_entity_key( + PackageKindTag::SmartContract, + AddressableEntityHash::new([42; 32]), + ); let leaf = Trie::Leaf { key: Key::Account(AccountHash::new([0; 32])), value: StoredValue::CLValue(CLValue::from_t(contract_key).unwrap()), diff --git a/execution_engine/src/engine_state/error.rs b/execution_engine/src/engine_state/error.rs index 9f9ca20f76..13813d4444 100644 --- a/execution_engine/src/engine_state/error.rs +++ b/execution_engine/src/engine_state/error.rs @@ -4,8 +4,8 @@ use thiserror::Error; use casper_storage::global_state::{self, state::CommitError}; use casper_types::{ - account::AccountHash, bytesrepr, system::mint, ApiError, ContractPackageHash, Digest, Key, - KeyTag, ProtocolVersion, + account::AccountHash, bytesrepr, system::mint, ApiError, Digest, Key, KeyTag, PackageHash, + ProtocolVersion, }; use crate::{ @@ -107,7 +107,7 @@ pub enum Error { MissingContractByAccountHash(AccountHash), /// Failed to retrieve the entity's package #[error("Failed to retrieve the entity package as {0}")] - MissingEntityPackage(ContractPackageHash), + MissingEntityPackage(PackageHash), /// Failed to retrieve accumulation purse from handle payment system contract. #[error("Failed to retrieve accumulation purse from the handle payment contract")] FailedToRetrieveAccumulationPurse, diff --git a/execution_engine/src/engine_state/execution_kind.rs b/execution_engine/src/engine_state/execution_kind.rs index e20c6ee524..474c86246e 100644 --- a/execution_engine/src/engine_state/execution_kind.rs +++ b/execution_engine/src/engine_state/execution_kind.rs @@ -4,8 +4,8 @@ use std::{cell::RefCell, rc::Rc}; use casper_storage::global_state::state::StateReader; use casper_types::{ - addressable_entity::NamedKeys, bytesrepr::Bytes, ContractHash, ContractPackageHash, - ContractVersionKey, ExecutableDeployItem, Key, Package, Phase, ProtocolVersion, StoredValue, + addressable_entity::NamedKeys, bytesrepr::Bytes, AddressableEntityHash, EntityVersionKey, + ExecutableDeployItem, Key, Package, PackageHash, Phase, ProtocolVersion, StoredValue, }; use crate::{ @@ -21,8 +21,8 @@ pub(crate) enum ExecutionKind { Module(Bytes), /// Stored contract. Contract { - /// Contract's hash. - contract_hash: ContractHash, + /// AddressableEntity's hash. + entity_hash: AddressableEntityHash, /// Entry point's name. entry_point_name: String, }, @@ -35,9 +35,12 @@ impl ExecutionKind { } /// Returns a new contract variant of `ExecutionKind`. - pub fn new_contract(contract_hash: ContractHash, entry_point_name: String) -> Self { + pub fn new_addressable_entity( + entity_hash: AddressableEntityHash, + entry_point_name: String, + ) -> Self { ExecutionKind::Contract { - contract_hash, + entity_hash, entry_point_name, } } @@ -56,8 +59,7 @@ impl ExecutionKind { R: StateReader, R::Error: Into, { - let contract_hash: ContractHash; - let contract_package: Package; + let package: Package; let is_payment_phase = phase == Phase::Payment; @@ -77,18 +79,25 @@ impl ExecutionKind { } ExecutableDeployItem::StoredContractByHash { hash, entry_point, .. - } => Ok(ExecutionKind::new_contract(hash, entry_point)), + } => Ok(ExecutionKind::new_addressable_entity(hash, entry_point)), ExecutableDeployItem::StoredContractByName { name, entry_point, .. } => { - let contract_key = named_keys.get(&name).cloned().ok_or_else(|| { + let entity_key = named_keys.get(&name).cloned().ok_or_else(|| { Error::Exec(execution::Error::NamedKeyNotFound(name.to_string())) })?; - contract_hash = - ContractHash::new(contract_key.into_hash().ok_or(Error::InvalidKeyVariant)?); + let entity_hash = match entity_key { + Key::Hash(hash) | Key::AddressableEntity((_, hash)) => { + AddressableEntityHash::new(hash) + } + _ => return Err(Error::InvalidKeyVariant), + }; - Ok(ExecutionKind::new_contract(contract_hash, entry_point)) + Ok(ExecutionKind::new_addressable_entity( + entity_hash, + entry_point, + )) } ExecutableDeployItem::StoredVersionedContractByName { name, @@ -96,82 +105,75 @@ impl ExecutionKind { entry_point, .. } => { - let contract_package_hash: ContractPackageHash = { - named_keys - .get(&name) - .cloned() - .ok_or_else(|| { - Error::Exec(execution::Error::NamedKeyNotFound(name.to_string())) - })? - .into_hash() - .ok_or(Error::InvalidKeyVariant)? - .into() + 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), }; - contract_package = tracking_copy - .borrow_mut() - .get_contract_package(contract_package_hash)?; + package = tracking_copy.borrow_mut().get_package(package_hash)?; let maybe_version_key = - version.map(|ver| ContractVersionKey::new(protocol_version.value().major, ver)); + version.map(|ver| EntityVersionKey::new(protocol_version.value().major, ver)); let contract_version_key = maybe_version_key - .or_else(|| contract_package.current_contract_version()) - .ok_or(Error::Exec(execution::Error::NoActiveContractVersions( - contract_package_hash, + .or_else(|| package.current_entity_version()) + .ok_or(Error::Exec(execution::Error::NoActiveEntityVersions( + package_hash, )))?; - if !contract_package.is_version_enabled(contract_version_key) { - return Err(Error::Exec(execution::Error::InvalidContractVersion( + if !package.is_version_enabled(contract_version_key) { + return Err(Error::Exec(execution::Error::InvalidEntityVersion( contract_version_key, ))); } - let looked_up_contract_hash: ContractHash = contract_package - .lookup_contract_hash(contract_version_key) - .ok_or(Error::Exec(execution::Error::InvalidContractVersion( + let looked_up_entity_hash: AddressableEntityHash = package + .lookup_entity_hash(contract_version_key) + .ok_or(Error::Exec(execution::Error::InvalidEntityVersion( contract_version_key, )))? .to_owned(); - Ok(ExecutionKind::new_contract( - looked_up_contract_hash, + Ok(ExecutionKind::new_addressable_entity( + looked_up_entity_hash, entry_point, )) } ExecutableDeployItem::StoredVersionedContractByHash { - hash: contract_package_hash, + hash: package_hash, version, entry_point, .. } => { - contract_package = tracking_copy - .borrow_mut() - .get_contract_package(contract_package_hash)?; + package = tracking_copy.borrow_mut().get_package(package_hash)?; let maybe_version_key = - version.map(|ver| ContractVersionKey::new(protocol_version.value().major, ver)); + version.map(|ver| EntityVersionKey::new(protocol_version.value().major, ver)); let contract_version_key = maybe_version_key - .or_else(|| contract_package.current_contract_version()) - .ok_or(Error::Exec(execution::Error::NoActiveContractVersions( - contract_package_hash, + .or_else(|| package.current_entity_version()) + .ok_or(Error::Exec(execution::Error::NoActiveEntityVersions( + package_hash, )))?; - if !contract_package.is_version_enabled(contract_version_key) { - return Err(Error::Exec(execution::Error::InvalidContractVersion( + if !package.is_version_enabled(contract_version_key) { + return Err(Error::Exec(execution::Error::InvalidEntityVersion( contract_version_key, ))); } - let looked_up_contract_hash = *contract_package - .lookup_contract_hash(contract_version_key) - .ok_or(Error::Exec(execution::Error::InvalidContractVersion( + let looked_up_entity_hash = *package + .lookup_entity_hash(contract_version_key) + .ok_or(Error::Exec(execution::Error::InvalidEntityVersion( contract_version_key, )))?; - Ok(ExecutionKind::new_contract( - looked_up_contract_hash, + Ok(ExecutionKind::new_addressable_entity( + looked_up_entity_hash, entry_point, )) } diff --git a/execution_engine/src/engine_state/genesis.rs b/execution_engine/src/engine_state/genesis.rs index d51dc48271..2afa6731b7 100644 --- a/execution_engine/src/engine_state/genesis.rs +++ b/execution_engine/src/engine_state/genesis.rs @@ -19,7 +19,7 @@ use casper_storage::global_state::state::StateProvider; use casper_types::{ addressable_entity::{ActionThresholds, NamedKeys}, execution::Effects, - package::{ContractPackageKind, ContractPackageStatus, ContractVersions, Groups}, + package::{EntityVersions, Groups, PackageKind, PackageStatus}, system::{ auction::{ self, BidAddr, BidKind, DelegationRate, Delegator, SeigniorageRecipient, @@ -30,12 +30,12 @@ use casper_types::{ }, handle_payment::{self, ACCUMULATION_PURSE_KEY}, mint::{self, ARG_ROUND_SEIGNIORAGE_RATE, ROUND_SEIGNIORAGE_RATE_KEY, TOTAL_SUPPLY_KEY}, - standard_payment, SystemContractType, AUCTION, HANDLE_PAYMENT, MINT, STANDARD_PAYMENT, + SystemEntityType, AUCTION, HANDLE_PAYMENT, MINT, }, - AccessRights, AddressableEntity, AdministratorAccount, CLValue, Chainspec, ChainspecRegistry, - ContractHash, ContractPackageHash, ContractWasm, ContractWasmHash, Digest, EntryPoints, EraId, - FeeHandling, GenesisAccount, Key, Motes, Package, Phase, ProtocolVersion, PublicKey, - RefundHandling, StoredValue, SystemConfig, URef, WasmConfig, U512, + AccessRights, AddressableEntity, AddressableEntityHash, AdministratorAccount, ByteCode, + ByteCodeHash, ByteCodeKind, CLValue, Chainspec, ChainspecRegistry, Digest, EntryPoints, EraId, + FeeHandling, GenesisAccount, Key, Motes, Package, PackageHash, Phase, ProtocolVersion, + PublicKey, RefundHandling, StoredValue, SystemConfig, Tagged, URef, WasmConfig, U512, }; use crate::{ @@ -593,8 +593,8 @@ where fn setup_system_account(&mut self) -> Result<(), Box> { let system_account_addr = PublicKey::System.to_account_hash(); - self.store_contract( - ContractPackageKind::Account(system_account_addr), + self.store_addressable_entity( + PackageKind::Account(system_account_addr), NO_WASM, None, None, @@ -660,14 +660,14 @@ where let contract_hash = self.store_system_contract( named_keys, entry_points, - ContractPackageKind::System(SystemContractType::Mint), + PackageKind::System(SystemEntityType::Mint), )?; { // Insert a partial registry into global state. // This allows for default values to be accessible when the remaining system contracts // call the `call_host_mint` function during their creation. - let mut partial_registry = BTreeMap::::new(); + let mut partial_registry = BTreeMap::::new(); partial_registry.insert(MINT.to_string(), contract_hash); partial_registry.insert(HANDLE_PAYMENT.to_string(), DEFAULT_ADDRESS.into()); let cl_registry = CLValue::from_t(partial_registry) @@ -684,7 +684,7 @@ where fn create_handle_payment( &self, handle_payment_payment_purse: URef, - ) -> Result> { + ) -> Result> { let named_keys = { let mut named_keys = NamedKeys::new(); let named_key = Key::URef(handle_payment_payment_purse); @@ -706,7 +706,7 @@ where let contract_hash = self.store_system_contract( named_keys, entry_points, - ContractPackageKind::System(SystemContractType::HandlePayment), + PackageKind::System(SystemEntityType::HandlePayment), )?; self.store_system_contract_registry(HANDLE_PAYMENT, contract_hash)?; @@ -714,7 +714,10 @@ where Ok(contract_hash) } - fn create_auction(&self, total_supply_key: Key) -> Result> { + fn create_auction( + &self, + total_supply_key: Key, + ) -> Result> { let locked_funds_period_millis = self.exec_config.locked_funds_period_millis(); let auction_delay: u64 = self.exec_config.auction_delay(); let genesis_timestamp_millis: u64 = self.exec_config.genesis_timestamp_millis(); @@ -971,7 +974,7 @@ where let contract_hash = self.store_system_contract( named_keys, entry_points, - ContractPackageKind::System(SystemContractType::Auction), + PackageKind::System(SystemEntityType::Auction), )?; self.store_system_contract_registry(AUCTION, contract_hash)?; @@ -979,22 +982,6 @@ where Ok(contract_hash) } - fn create_standard_payment(&self) -> Result> { - let named_keys = NamedKeys::new(); - - let entry_points = standard_payment::standard_payment_entry_points(); - - let contract_hash = self.store_system_contract( - named_keys, - entry_points, - ContractPackageKind::System(SystemContractType::HandlePayment), - )?; - - self.store_system_contract_registry(STANDARD_PAYMENT, contract_hash)?; - - Ok(contract_hash) - } - pub(crate) fn create_accounts( &self, total_supply_key: Key, @@ -1034,8 +1021,8 @@ where _ => self.create_purse(account_starting_balance)?, }; - self.store_contract( - ContractPackageKind::Account(account.account_hash()), + self.store_addressable_entity( + PackageKind::Account(account.account_hash()), NO_WASM, None, None, @@ -1107,9 +1094,9 @@ where &self, named_keys: NamedKeys, entry_points: EntryPoints, - contract_package_kind: ContractPackageKind, - ) -> Result> { - self.store_contract( + contract_package_kind: PackageKind, + ) -> Result> { + self.store_addressable_entity( contract_package_kind, NO_WASM, Some(named_keys), @@ -1118,33 +1105,32 @@ where ) } - fn store_contract( + fn store_addressable_entity( &self, - contract_package_kind: ContractPackageKind, + package_kind: PackageKind, no_wasm: bool, maybe_named_keys: Option, maybe_entry_points: Option, main_purse: URef, - ) -> Result> { + ) -> Result> { let protocol_version = self.protocol_version; - let contract_wasm_hash = if no_wasm { - ContractWasmHash::new(DEFAULT_ADDRESS) + let byte_code_hash = if no_wasm { + ByteCodeHash::new(DEFAULT_ADDRESS) } else { - ContractWasmHash::new(self.address_generator.borrow_mut().new_hash_address()) + ByteCodeHash::new(self.address_generator.borrow_mut().new_hash_address()) }; - let contract_hash = if contract_package_kind.is_system_account() { + let entity_hash = if package_kind.is_system_account() { let entity_hash_addr = PublicKey::System.to_account_hash().value(); - ContractHash::new(entity_hash_addr) + AddressableEntityHash::new(entity_hash_addr) } else { - ContractHash::new(self.address_generator.borrow_mut().new_hash_address()) + AddressableEntityHash::new(self.address_generator.borrow_mut().new_hash_address()) }; - let contract_package_hash = - ContractPackageHash::new(self.address_generator.borrow_mut().new_hash_address()); + let package_hash = PackageHash::new(self.address_generator.borrow_mut().new_hash_address()); - let contract_wasm = ContractWasm::new(vec![]); - let associated_keys = contract_package_kind.associated_keys(); - let maybe_account_hash = contract_package_kind.maybe_account_hash(); + let byte_code = ByteCode::new(ByteCodeKind::Empty, vec![]); + let associated_keys = package_kind.associated_keys(); + let maybe_account_hash = package_kind.maybe_account_hash(); let named_keys = maybe_named_keys.unwrap_or_default(); let entry_points = match maybe_entry_points { Some(entry_points) => entry_points, @@ -1158,8 +1144,8 @@ where }; let entity = AddressableEntity::new( - contract_package_hash, - contract_wasm_hash, + package_hash, + byte_code_hash, named_keys, entry_points, protocol_version, @@ -1175,47 +1161,51 @@ where // Genesis contracts can be versioned contracts. let contract_package = { - let mut contract_package = Package::new( + let mut package = Package::new( access_key, - ContractVersions::new(), + EntityVersions::new(), BTreeSet::default(), Groups::default(), - ContractPackageStatus::default(), - contract_package_kind, + PackageStatus::default(), + package_kind, ); - contract_package.insert_contract_version(protocol_version.value().major, contract_hash); - contract_package + package.insert_entity_version(protocol_version.value().major, entity_hash); + package }; - self.tracking_copy.borrow_mut().write( - contract_wasm_hash.into(), - StoredValue::ContractWasm(contract_wasm), - ); + let byte_code_key = Key::ByteCode((ByteCodeKind::Empty, byte_code_hash.value())); + self.tracking_copy .borrow_mut() - .write(contract_hash.into(), StoredValue::AddressableEntity(entity)); - self.tracking_copy.borrow_mut().write( - contract_package_hash.into(), - StoredValue::ContractPackage(contract_package), - ); + .write(byte_code_key, StoredValue::ByteCode(byte_code)); + + let entity_key = Key::AddressableEntity((package_kind.tag(), entity_hash.value())); + + self.tracking_copy + .borrow_mut() + .write(entity_key, StoredValue::AddressableEntity(entity)); + + self.tracking_copy + .borrow_mut() + .write(package_hash.into(), StoredValue::Package(contract_package)); + if let Some(account_hash) = maybe_account_hash { - let contract_key: Key = contract_hash.into(); - let contract_by_account = CLValue::from_t(contract_key) + let entity_by_account = CLValue::from_t(entity_key) .map_err(|error| GenesisError::CLValue(error.to_string()))?; self.tracking_copy.borrow_mut().write( Key::Account(account_hash), - StoredValue::CLValue(contract_by_account), + StoredValue::CLValue(entity_by_account), ); } - Ok(contract_hash) + Ok(entity_hash) } fn store_system_contract_registry( &self, contract_name: &str, - contract_hash: ContractHash, + contract_hash: AddressableEntityHash, ) -> Result<(), Box> { let partial_cl_registry = self .tracking_copy @@ -1278,9 +1268,6 @@ where // Create handle payment self.create_handle_payment(payment_purse_uref)?; - // Create standard payment - self.create_standard_payment()?; - self.store_chainspec_registry(chainspec_registry)?; Ok(()) diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index 6ead43e172..0e313e7226 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -19,9 +19,10 @@ mod transfer; pub mod upgrade; use itertools::Itertools; + use std::{ cell::RefCell, - collections::{btree_map::Entry, BTreeMap, BTreeSet}, + collections::{BTreeMap, BTreeSet}, convert::TryFrom, rc::Rc, }; @@ -29,7 +30,7 @@ use std::{ use num_rational::Ratio; use num_traits::Zero; use once_cell::sync::Lazy; -use tracing::{debug, error, trace, warn}; +use tracing::{debug, error, info, trace, warn}; use casper_storage::{ data_access_layer::DataAccessLayer, @@ -43,27 +44,28 @@ use casper_storage::{ trie_store::operations::PruneResult as GlobalStatePruneResult, }, }; + use casper_types::{ account::{Account, AccountHash}, addressable_entity::{AssociatedKeys, NamedKeys}, bytesrepr::ToBytes, execution::Effects, - package::{ContractPackageKind, ContractPackageStatus, ContractVersions, Groups}, + package::{EntityVersions, Groups, PackageKind, PackageKindTag, PackageStatus}, system::{ auction::{ - BidAddr, BidKind, EraValidators, UnbondingPurse, ValidatorBid, WithdrawPurse, - ARG_ERA_END_TIMESTAMP_MILLIS, ARG_EVICTED_VALIDATORS, ARG_REWARDS_MAP, - ARG_VALIDATOR_PUBLIC_KEYS, AUCTION_DELAY_KEY, ERA_ID_KEY, LOCKED_FUNDS_PERIOD_KEY, - SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY, UNBONDING_DELAY_KEY, VALIDATOR_SLOTS_KEY, + BidAddr, BidKind, EraValidators, ValidatorBid, ARG_ERA_END_TIMESTAMP_MILLIS, + ARG_EVICTED_VALIDATORS, ARG_REWARDS_MAP, ARG_VALIDATOR_PUBLIC_KEYS, AUCTION_DELAY_KEY, + LOCKED_FUNDS_PERIOD_KEY, SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY, UNBONDING_DELAY_KEY, + VALIDATOR_SLOTS_KEY, }, handle_payment::{self, ACCUMULATION_PURSE_KEY}, mint::{self, ROUND_SEIGNIORAGE_RATE_KEY}, - AUCTION, HANDLE_PAYMENT, MINT, STANDARD_PAYMENT, + AUCTION, HANDLE_PAYMENT, MINT, }, - AccessRights, AddressableEntity, ApiError, BlockTime, CLValue, ChainspecRegistry, ContractHash, - ContractPackageHash, ContractWasmHash, DeployHash, DeployInfo, Digest, EntryPoints, EraId, - ExecutableDeployItem, FeeHandling, Gas, Key, KeyTag, Motes, Package, Phase, ProtocolVersion, - PublicKey, RuntimeArgs, StoredValue, URef, UpgradeConfig, U512, + AccessRights, AddressableEntity, AddressableEntityHash, ApiError, BlockTime, ByteCodeHash, + CLValue, ChainspecRegistry, DeployHash, DeployInfo, Digest, EntryPoints, ExecutableDeployItem, + FeeHandling, Gas, Key, KeyTag, Motes, Package, PackageHash, Phase, ProtocolVersion, PublicKey, + RuntimeArgs, StoredValue, URef, UpgradeConfig, U512, }; use self::transfer::NewTransferTargetMode; @@ -100,7 +102,7 @@ use crate::{ execution::{self, AddressGenerator, DirectSystemContractCall, Executor}, runtime::RuntimeStack, system::auction, - tracking_copy::{TrackingCopy, TrackingCopyExt}, + tracking_copy::{TrackingCopy, TrackingCopyExt, TrackingCopyQueryResult}, }; const DEFAULT_ADDRESS: [u8; 32] = [0; 32]; @@ -114,8 +116,8 @@ pub const MAX_PAYMENT_AMOUNT: u64 = 2_500_000_000; pub static MAX_PAYMENT: Lazy = Lazy::new(|| U512::from(MAX_PAYMENT_AMOUNT)); /// A special contract wasm hash for contracts representing Accounts. -pub static ACCOUNT_WASM_HASH: Lazy = - Lazy::new(|| ContractWasmHash::new(DEFAULT_ADDRESS)); +pub static ACCOUNT_BYTE_CODE_HASH: Lazy = + Lazy::new(|| ByteCodeHash::new(DEFAULT_ADDRESS)); /// Gas/motes conversion rate of wasmless transfer cost is always 1 regardless of what user wants to /// pay. @@ -343,7 +345,7 @@ where return Err(Error::InvalidProtocolVersion(new_protocol_version)); } - let registry = if let Ok(registry) = tracking_copy.borrow_mut().get_system_contracts() { + let mut registry = if let Ok(registry) = tracking_copy.borrow_mut().get_system_contracts() { registry } else { // Check the upgrade config for the registry @@ -369,23 +371,36 @@ where } }; - let mint_hash = registry.get(MINT).ok_or_else(|| { + let mint_hash = *registry.get(MINT).ok_or_else(|| { error!("Missing system mint contract hash"); Error::MissingSystemContractHash(MINT.to_string()) })?; - let auction_hash = registry.get(AUCTION).ok_or_else(|| { + let auction_hash = *registry.get(AUCTION).ok_or_else(|| { error!("Missing system auction contract hash"); Error::MissingSystemContractHash(AUCTION.to_string()) })?; - let standard_payment_hash = registry.get(STANDARD_PAYMENT).ok_or_else(|| { - error!("Missing system standard payment contract hash"); - Error::MissingSystemContractHash(STANDARD_PAYMENT.to_string()) - })?; - let handle_payment_hash = registry.get(HANDLE_PAYMENT).ok_or_else(|| { + + let handle_payment_hash = *registry.get(HANDLE_PAYMENT).ok_or_else(|| { error!("Missing system handle payment contract hash"); Error::MissingSystemContractHash(HANDLE_PAYMENT.to_string()) })?; + if let Some(standard_payment_hash) = registry.remove_standard_payment() { + // Write the chainspec registry to global state + let cl_value_chainspec_registry = + CLValue::from_t(registry).map_err(|error| Error::Bytesrepr(error.to_string()))?; + + tracking_copy.borrow_mut().write( + Key::SystemContractRegistry, + StoredValue::CLValue(cl_value_chainspec_registry), + ); + + // Prune away standard payment from global state. + tracking_copy + .borrow_mut() + .prune(Key::Hash(standard_payment_hash.value())); + }; + // Write the chainspec registry to global state let cl_value_chainspec_registry = CLValue::from_t(upgrade_config.chainspec_registry().clone()) @@ -407,22 +422,19 @@ where system_upgrader.migrate_system_account(pre_state_hash)?; system_upgrader - .create_accumulation_purse_if_required(handle_payment_hash, &self.config) + .create_accumulation_purse_if_required(&handle_payment_hash, &self.config) .map_err(Error::ProtocolUpgrade)?; system_upgrader - .refresh_system_contracts( - mint_hash, - auction_hash, - handle_payment_hash, - standard_payment_hash, - ) + .refresh_system_contracts(&mint_hash, &auction_hash, &handle_payment_hash) .map_err(Error::ProtocolUpgrade)?; + // Prune away the standard payment record. + // 3.1.1.1.1.7 new total validator slots is optional if let Some(new_validator_slots) = upgrade_config.new_validator_slots() { // 3.1.2.4 if new total validator slots is provided, update auction contract state - let auction_contract = tracking_copy.borrow_mut().get_contract(*auction_hash)?; + let auction_contract = tracking_copy.borrow_mut().get_contract(auction_hash)?; let validator_slots_key = auction_contract .named_keys() @@ -439,7 +451,7 @@ where if let Some(new_auction_delay) = upgrade_config.new_auction_delay() { debug!(%new_auction_delay, "Auction delay changed as part of the upgrade"); - let auction_contract = tracking_copy.borrow_mut().get_contract(*auction_hash)?; + let auction_contract = tracking_copy.borrow_mut().get_contract(auction_hash)?; let auction_delay_key = auction_contract .named_keys() @@ -453,7 +465,7 @@ where } if let Some(new_locked_funds_period) = upgrade_config.new_locked_funds_period_millis() { - let auction_contract = tracking_copy.borrow_mut().get_contract(*auction_hash)?; + let auction_contract = tracking_copy.borrow_mut().get_contract(auction_hash)?; let locked_funds_period_key = auction_contract .named_keys() @@ -474,7 +486,7 @@ where Ratio::new(numer.into(), denom.into()) }; - let mint_contract = tracking_copy.borrow_mut().get_contract(*mint_hash)?; + let mint_contract = tracking_copy.borrow_mut().get_contract(mint_hash)?; let locked_funds_period_key = mint_contract .named_keys() @@ -547,92 +559,10 @@ where tracking_copy.borrow_mut().write(*key, value.clone()); } - // This is a one time data transformation which will be removed - // in a following upgrade. - // TODO: CRef={https://github.com/casper-network/casper-node/issues/2479} - { - let withdraw_keys = tracking_copy - .borrow_mut() - .get_keys(&KeyTag::Withdraw) - .map_err(|_| Error::FailedToGetKeys(KeyTag::Withdraw))?; - - let (unbonding_delay, current_era_id) = { - let auction_contract = tracking_copy.borrow_mut().get_contract(*auction_hash)?; - - let unbonding_delay_key = auction_contract - .named_keys() - .get(UNBONDING_DELAY_KEY) - .expect("unbonding_delay key must exist in auction contract's named keys"); - let delay = tracking_copy - .borrow_mut() - .read(unbonding_delay_key) - .map_err(|error| error.into())? - .ok_or(Error::FailedToRetrieveUnbondingDelay)? - .into_cl_value() - .ok_or_else(|| Error::Bytesrepr("unbonding_delay".to_string()))? - .into_t::() - .map_err(execution::Error::from)?; - - let era_id_key = auction_contract - .named_keys() - .get(ERA_ID_KEY) - .expect("era_id key must exist in auction contract's named keys"); - - let era_id = tracking_copy - .borrow_mut() - .read(era_id_key) - .map_err(|error| error.into())? - .ok_or(Error::FailedToRetrieveEraId)? - .into_cl_value() - .ok_or_else(|| Error::Bytesrepr("era_id".to_string()))? - .into_t::() - .map_err(execution::Error::from)?; - - (delay, era_id) - }; - - for key in withdraw_keys { - // Transform only those withdraw purses that are still to be - // processed in the unbonding queue. - let withdraw_purses = tracking_copy - .borrow_mut() - .read(&key) - .map_err(|_| Error::FailedToGetKeys(KeyTag::Withdraw))? - .ok_or(Error::FailedToGetStoredWithdraws)? - .into_withdraw() - .ok_or(Error::FailedToGetWithdrawPurses)?; - - // Ensure that sufficient balance exists for all unbond purses that are to be - // migrated. - Self::fail_upgrade_if_withdraw_purses_lack_sufficient_balance( - &withdraw_purses, - &tracking_copy, - )?; - - let unbonding_purses: Vec = withdraw_purses - .into_iter() - .filter_map(|purse| { - if purse.era_of_creation() + unbonding_delay >= current_era_id { - return Some(UnbondingPurse::from(purse)); - } - None - }) - .collect(); - - let unbonding_key = key - .withdraw_to_unbond() - .ok_or_else(|| Error::Bytesrepr("unbond".to_string()))?; - - tracking_copy - .borrow_mut() - .write(unbonding_key, StoredValue::Unbonding(unbonding_purses)); - } - } - // We insert the new unbonding delay once the purses to be paid out have been transformed // based on the previous unbonding delay. if let Some(new_unbonding_delay) = upgrade_config.new_unbonding_delay() { - let auction_contract = tracking_copy.borrow_mut().get_contract(*auction_hash)?; + let auction_contract = tracking_copy.borrow_mut().get_contract(auction_hash)?; let unbonding_delay_key = auction_contract .named_keys() @@ -753,10 +683,27 @@ where let tracking_copy = tracking_copy.borrow(); - Ok(tracking_copy - .query(self.config(), query_request.key(), query_request.path()) - .map_err(|err| Error::Exec(err.into()))? - .into()) + match tracking_copy.query(self.config(), query_request.key(), query_request.path()) { + Ok(TrackingCopyQueryResult::ValueNotFound(result_string)) => { + let key = query_request.key(); + + if !key.is_system_key() { + return Ok(TrackingCopyQueryResult::ValueNotFound(result_string).into()); + } + + let new_query_key = Key::Hash( + key.into_entity_addr() + .ok_or_else(|| Error::InvalidKeyVariant)?, + ); + info!("Compensating for AddressableEntity move"); + let result = tracking_copy + .query(self.config(), new_query_key, query_request.path()) + .map_err(|err| Error::Exec(err.into()))?; + Ok(result.into()) + } + Ok(result) => Ok(result.into()), + Err(error) => Err(Error::Exec(error.into())), + } } /// Runs a deploy execution request. @@ -808,7 +755,7 @@ where protocol_version: ProtocolVersion, authorization_keys: &BTreeSet, tracking_copy: Rc::Reader>>>, - ) -> Result<(AddressableEntity, ContractHash), Error> { + ) -> Result<(AddressableEntity, AddressableEntityHash), Error> { let entity_record = match tracking_copy .borrow_mut() .get_addressable_entity_by_account_hash(protocol_version, account_hash) @@ -817,7 +764,7 @@ where Err(_) => return Err(Error::MissingContractByAccountHash(account_hash)), }; - let entity_hash: ContractHash = match tracking_copy + let entity_hash: AddressableEntityHash = match tracking_copy .borrow_mut() .get_entity_hash_by_account_hash(account_hash) { @@ -858,16 +805,16 @@ where let mut generator = AddressGenerator::new(account.main_purse().addr().as_ref(), Phase::System); - let contract_wasm_hash = *ACCOUNT_WASM_HASH; - let contract_hash = ContractHash::new(generator.new_hash_address()); - let contract_package_hash = ContractPackageHash::new(generator.new_hash_address()); + let contract_wasm_hash = *ACCOUNT_BYTE_CODE_HASH; + 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 entity = AddressableEntity::new( - contract_package_hash, + package_hash, contract_wasm_hash, account.named_keys().clone(), entry_points, @@ -879,28 +826,26 @@ where let access_key = generator.new_uref(AccessRights::READ_ADD_WRITE); - let contract_package = { - let mut contract_package = Package::new( + let package = { + let mut package = Package::new( access_key, - ContractVersions::default(), + EntityVersions::default(), BTreeSet::default(), Groups::default(), - ContractPackageStatus::Locked, - ContractPackageKind::Account(account_hash), + PackageStatus::Locked, + PackageKind::Account(account_hash), ); - contract_package.insert_contract_version(protocol_version.value().major, contract_hash); - contract_package + package.insert_entity_version(protocol_version.value().major, entity_hash); + package }; - let contract_key: Key = contract_hash.into(); + let entity_key: Key = Key::addressable_entity_key(PackageKindTag::Account, entity_hash); + tracking_copy.borrow_mut().write(entity_key, entity.into()); tracking_copy .borrow_mut() - .write(contract_key, entity.into()); - tracking_copy - .borrow_mut() - .write(contract_package_hash.into(), contract_package.into()); - let contract_by_account = match CLValue::from_t(contract_key) { + .write(package_hash.into(), package.into()); + let contract_by_account = match CLValue::from_t(entity_key) { Ok(cl_value) => cl_value, Err(_) => return Err(Error::Bytesrepr("Failed to convert to CLValue".to_string())), }; @@ -958,15 +903,15 @@ where /// Return the package kind. pub fn get_entity_package_kind( &self, - entity_package_address: ContractPackageHash, + entity_package_address: PackageHash, tracking_copy: Rc::Reader>>>, - ) -> Result { + ) -> Result { let entity_package = match tracking_copy .borrow_mut() .read(&entity_package_address.into()) .map_err(Into::into)? { - Some(StoredValue::ContractPackage(entity_package)) => entity_package, + Some(StoredValue::Package(entity_package)) => entity_package, Some(_) | None => return Err(Error::MissingEntityPackage(entity_package_address)), }; @@ -1016,12 +961,11 @@ where Err(e) => return Ok(ExecutionResult::precondition_failure(e)), }; - let package_kind = match self - .get_entity_package_kind(entity.contract_package_hash(), Rc::clone(&tracking_copy)) - { - Ok(package_kind) => package_kind, - Err(e) => return Ok(ExecutionResult::precondition_failure(e)), - }; + let package_kind = + match self.get_entity_package_kind(entity.package_hash(), Rc::clone(&tracking_copy)) { + Ok(package_kind) => package_kind, + Err(e) => return Ok(ExecutionResult::precondition_failure(e)), + }; let system_contract_registry = tracking_copy.borrow_mut().get_system_contracts()?; @@ -1120,7 +1064,6 @@ where // All wasmless transfer preconditions are met. // Any error that occurs in logic below this point would result in a charge for user error. - let mut runtime_args_builder = TransferRuntimeArgsBuilder::new(deploy_item.session.args().clone()); @@ -1173,12 +1116,13 @@ where } NewTransferTargetMode::CreateAccount(account_hash) => { let create_purse_stack = self.get_new_system_call_stack(); + let (maybe_uref, execution_result): (Option, ExecutionResult) = executor .call_system_contract( DirectSystemContractCall::CreatePurse, RuntimeArgs::new(), // mint create takes no arguments &entity, - package_kind.clone(), + package_kind, authorization_keys.clone(), account_hash, blocktime, @@ -1271,7 +1215,7 @@ where DirectSystemContractCall::GetPaymentPurse, RuntimeArgs::default(), &entity, - package_kind.clone(), + package_kind, authorization_keys.clone(), account_hash, blocktime, @@ -1315,7 +1259,7 @@ where DirectSystemContractCall::Transfer, runtime_args, &entity, - package_kind.clone(), + package_kind, authorization_keys.clone(), account_hash, blocktime, @@ -1468,7 +1412,7 @@ where DirectSystemContractCall::FinalizePayment, handle_payment_args, &system_addressable_entity, - ContractPackageKind::Account(PublicKey::System.to_account_hash()), + PackageKind::Account(PublicKey::System.to_account_hash()), authorization_keys, PublicKey::System.to_account_hash(), blocktime, @@ -1570,12 +1514,12 @@ where &authorization_keys, Rc::clone(&tracking_copy), ) { - Ok((contract, contract_hash)) => (contract, contract_hash), + Ok((addressable_entity, entity_hash)) => (addressable_entity, entity_hash), Err(e) => return Ok(ExecutionResult::precondition_failure(e)), } }; - let package_address = entity.contract_package_hash(); + let package_address = entity.package_hash(); let package_kind = match self.get_entity_package_kind(package_address, Rc::clone(&tracking_copy)) { Ok(package_kind) => package_kind, @@ -1687,6 +1631,26 @@ where // [`ExecutionResultBuilder`] handles merging of multiple execution results let mut execution_result_builder = execution_result::ExecutionResultBuilder::new(); + let rewards_target_purse = + match self.get_rewards_purse(protocol_version, proposer, prestate_hash) { + Ok(target_purse) => target_purse, + Err(error) => return Ok(ExecutionResult::precondition_failure(error)), + }; + + let rewards_target_purse_balance_key = { + // Get reward purse Key from handle payment contract + // payment_code_spec_6: system contract validity + match tracking_copy + .borrow_mut() + .get_purse_balance_key(rewards_target_purse.into()) + { + Ok(key) => key, + Err(error) => { + return Ok(ExecutionResult::precondition_failure(error.into())); + } + } + }; + // Execute provided payment code let payment_result = { // payment_code_spec_1: init pay environment w/ gas limit == (max_payment_cost / @@ -1718,13 +1682,10 @@ where if payment.is_standard_payment(phase) { // Todo potentially could be moved to Executor::Exec - executor.exec_standard_payment( + match executor.exec_standard_payment( payment_args, - entity_hash, &entity, - package_kind.clone(), - &mut payment_named_keys, - payment_access_rights, + package_kind, authorization_keys.clone(), account_hash, blocktime, @@ -1732,9 +1693,13 @@ where 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)); + } + } } else { let payment_execution_kind = match ExecutionKind::new( Rc::clone(&tracking_copy), @@ -1753,7 +1718,7 @@ where payment_args, entity_hash, &entity, - package_kind.clone(), + package_kind, &mut payment_named_keys, payment_access_rights, authorization_keys.clone(), @@ -1770,26 +1735,6 @@ where }; log_execution_result("payment result", &payment_result); - let rewards_target_purse = - match self.get_rewards_purse(protocol_version, proposer, prestate_hash) { - Ok(target_purse) => target_purse, - Err(error) => return Ok(ExecutionResult::precondition_failure(error)), - }; - - let rewards_target_purse_balance_key = { - // Get reward purse Key from handle payment contract - // payment_code_spec_6: system contract validity - match tracking_copy - .borrow_mut() - .get_purse_balance_key(rewards_target_purse.into()) - { - Ok(key) => key, - Err(error) => { - return Ok(ExecutionResult::precondition_failure(error.into())); - } - } - }; - // If provided wasm file was malformed, we should charge. if should_charge_for_errors_in_wasm(&payment_result) { let error = payment_result @@ -2077,7 +2022,7 @@ where DirectSystemContractCall::FinalizePayment, handle_payment_args, &system_addressable_entity, - ContractPackageKind::Account(system_account_hash), + PackageKind::Account(system_account_hash), authorization_keys, system_account_hash, blocktime, @@ -2225,9 +2170,11 @@ where .copied() .ok_or_else(|| Error::MissingSystemContractHash(AUCTION.to_string()))?; + let auction_key = Key::addressable_entity_key(PackageKindTag::System, auction_hash); + let query_request = QueryRequest::new( state_root_hash, - auction_hash.into(), + auction_key, vec![SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY.to_string()], ); @@ -2339,7 +2286,7 @@ where DirectSystemContractCall::DistributeAccumulatedFees, RuntimeArgs::default(), &virtual_system_contract_by_account, - ContractPackageKind::Account(system_account_hash), + PackageKind::Account(system_account_hash), authorization_keys.clone(), system_account_hash, BlockTime::default(), @@ -2368,7 +2315,7 @@ where DirectSystemContractCall::DistributeRewards, runtime_args, &virtual_system_contract_by_account, - ContractPackageKind::Account(system_account_hash), + PackageKind::Account(system_account_hash), authorization_keys, system_account_hash, BlockTime::default(), @@ -2448,7 +2395,7 @@ where DirectSystemContractCall::Slash, slash_args, &system_addressable_entity, - ContractPackageKind::Account(system_account_hash), + PackageKind::Account(system_account_hash), authorization_keys.clone(), system_account_hash, BlockTime::default(), @@ -2489,7 +2436,7 @@ where DirectSystemContractCall::RunAuction, run_auction_args, &system_addressable_entity, - ContractPackageKind::Account(system_account_hash), + PackageKind::Account(system_account_hash), authorization_keys, system_account_hash, BlockTime::default(), @@ -2536,7 +2483,7 @@ where let account_addr = public_key.to_account_hash(); - let contract_hash = match tracking_copy + let entity_hash = match tracking_copy .borrow_mut() .get_entity_hash_by_account_hash(account_addr) { @@ -2544,9 +2491,16 @@ where Err(error) => return Err(error.into()), }; - let account = match tracking_copy.borrow_mut().get_contract(contract_hash) { - Ok(contract) => contract, - Err(error) => return Err(error.into()), + let account = match tracking_copy + .borrow_mut() + .read(&Key::addressable_entity_key( + PackageKindTag::Account, + entity_hash, + )) + .map_err(|_| Error::InvalidKeyVariant)? + { + Some(StoredValue::AddressableEntity(account)) => account, + Some(_) | None => return Err(Error::InvalidKeyVariant), }; let main_purse_balance_key = { @@ -2593,7 +2547,7 @@ where } /// Returns mint system contract hash. - pub fn get_system_mint_hash(&self, state_hash: Digest) -> Result { + pub fn get_system_mint_hash(&self, state_hash: Digest) -> Result { let registry = self.get_system_contract_registry(state_hash)?; let mint_hash = registry.get(MINT).ok_or_else(|| { error!("Missing system mint contract hash"); @@ -2603,7 +2557,10 @@ where } /// Returns auction system contract hash. - pub fn get_system_auction_hash(&self, state_hash: Digest) -> Result { + pub fn get_system_auction_hash( + &self, + state_hash: Digest, + ) -> Result { let registry = self.get_system_contract_registry(state_hash)?; let auction_hash = registry.get(AUCTION).ok_or_else(|| { error!("Missing system auction contract hash"); @@ -2613,7 +2570,10 @@ where } /// Returns handle payment system contract hash. - pub fn get_handle_payment_hash(&self, state_hash: Digest) -> Result { + pub fn get_handle_payment_hash( + &self, + state_hash: Digest, + ) -> Result { let registry = self.get_system_contract_registry(state_hash)?; let handle_payment = registry.get(HANDLE_PAYMENT).ok_or_else(|| { error!("Missing system handle payment contract hash"); @@ -2622,16 +2582,6 @@ where Ok(*handle_payment) } - /// Returns standard payment system contract hash. - pub fn get_standard_payment_hash(&self, state_hash: Digest) -> Result { - let registry = self.get_system_contract_registry(state_hash)?; - let standard_payment = registry.get(STANDARD_PAYMENT).ok_or_else(|| { - error!("Missing system standard payment contract hash"); - Error::MissingSystemContractHash(STANDARD_PAYMENT.to_string()) - })?; - Ok(*standard_payment) - } - fn get_new_system_call_stack(&self) -> RuntimeStack { let max_height = self.config.max_runtime_call_stack_height() as usize; RuntimeStack::new_system_call_stack(max_height) @@ -2671,48 +2621,6 @@ where .map_err(Into::into)?; maybe_proof.ok_or(Error::MissingChecksumRegistry) } - - /// As the name suggests, used to ensure commit_upgrade fails if we lack sufficient balances. - fn fail_upgrade_if_withdraw_purses_lack_sufficient_balance( - withdraw_purses: &[WithdrawPurse], - tracking_copy: &Rc::Reader>>>, - ) -> Result<(), Error> { - let mut balances = BTreeMap::new(); - for purse in withdraw_purses.iter() { - match balances.entry(*purse.bonding_purse()) { - Entry::Vacant(entry) => { - entry.insert(*purse.amount()); - } - Entry::Occupied(mut entry) => { - let value = entry.get_mut(); - let new_val = value.checked_add(*purse.amount()).ok_or_else(|| { - Error::Mint("overflowed a u512 during unbond migration".into()) - })?; - *value = new_val; - } - } - } - for (unbond_purse_uref, unbond_amount) in balances { - let key = match tracking_copy - .borrow_mut() - .get_purse_balance_key(unbond_purse_uref.into()) - { - Ok(key) => key, - Err(_) => return Err(Error::Mint("purse balance not found".into())), - }; - let current_balance = tracking_copy.borrow_mut().get_purse_balance(key)?.value(); - - if unbond_amount > current_balance { - // If we don't have enough balance to migrate, the only thing we can do - // is to fail the upgrade. - error!(%current_balance, %unbond_purse_uref, %unbond_amount, "commit_upgrade failed during migration - insufficient in purse to unbond"); - return Err(Error::Mint( - "insufficient balance detected while migrating unbond purses".into(), - )); - } - } - Ok(()) - } } fn log_execution_result(preamble: &'static str, result: &ExecutionResult) { @@ -2760,7 +2668,7 @@ fn should_charge_for_errors_in_wasm(execution_result: &ExecutionResult) -> bool Error::Exec(err) => match err { ExecError::WasmPreprocessing(_) | ExecError::UnsupportedWasmStart => true, ExecError::Storage(_) - | ExecError::InvalidContractWasm(_) + | ExecError::InvalidByteCode(_) | ExecError::WasmOptimizer | ExecError::ParityWasm(_) | ExecError::Interpreter(_) @@ -2783,21 +2691,22 @@ fn should_charge_for_errors_in_wasm(execution_result: &ExecutionResult) -> bool | ExecError::SetThresholdFailure(_) | ExecError::SystemContract(_) | ExecError::DeploymentAuthorizationFailure + | ExecError::UpgradeAuthorizationFailure | ExecError::ExpectedReturnValue | ExecError::UnexpectedReturnValue | ExecError::InvalidContext | ExecError::IncompatibleProtocolMajorVersion { .. } | ExecError::CLValue(_) | ExecError::HostBufferEmpty - | ExecError::NoActiveContractVersions(_) - | ExecError::InvalidContractVersion(_) + | ExecError::NoActiveEntityVersions(_) + | ExecError::InvalidEntityVersion(_) | ExecError::NoSuchMethod(_) | ExecError::TemplateMethod(_) | ExecError::KeyIsNotAURef(_) | ExecError::UnexpectedStoredValueVariant - | ExecError::LockedContract(_) - | ExecError::InvalidContractPackage(_) - | ExecError::InvalidContract(_) + | ExecError::LockedEntity(_) + | ExecError::InvalidPackage(_) + | ExecError::InvalidEntity(_) | ExecError::MissingArgument { .. } | ExecError::DictionaryItemKeyExceedsLength | ExecError::MissingSystemContractRegistry @@ -2805,10 +2714,11 @@ fn should_charge_for_errors_in_wasm(execution_result: &ExecutionResult) -> bool | ExecError::RuntimeStackOverflow | ExecError::ValueTooLarge | ExecError::MissingRuntimeStack - | ExecError::DisabledContract(_) + | ExecError::DisabledEntity(_) | ExecError::UnexpectedKeyVariant(_) - | ExecError::InvalidContractPackageKind(_) - | ExecError::Transform(_) => false, + | ExecError::InvalidPackageKind(_) + | ExecError::Transform(_) + | ExecError::InvalidEntryPointType => false, ExecError::DisabledUnrestrictedTransfers => false, }, Error::WasmPreprocessing(_) => true, diff --git a/execution_engine/src/engine_state/system_contract_registry.rs b/execution_engine/src/engine_state/system_contract_registry.rs index 01fe2469b7..2980873e85 100644 --- a/execution_engine/src/engine_state/system_contract_registry.rs +++ b/execution_engine/src/engine_state/system_contract_registry.rs @@ -7,12 +7,13 @@ use serde::{Deserialize, Serialize}; use casper_types::{ bytesrepr::{self, FromBytes, ToBytes}, - CLType, CLTyped, ContractHash, + system::STANDARD_PAYMENT, + AddressableEntityHash, CLType, CLTyped, }; /// The system contract registry. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Debug, DataSize)] -pub struct SystemContractRegistry(BTreeMap); +pub struct SystemContractRegistry(BTreeMap); impl SystemContractRegistry { /// Returns a new `SystemContractRegistry`. @@ -22,21 +23,26 @@ impl SystemContractRegistry { } /// Inserts a contract's details into the registry. - pub fn insert(&mut self, contract_name: String, contract_hash: ContractHash) { + pub fn insert(&mut self, contract_name: String, contract_hash: AddressableEntityHash) { self.0.insert(contract_name, contract_hash); } /// Gets a contract's hash from the registry. - pub fn get(&self, contract_name: &str) -> Option<&ContractHash> { + pub fn get(&self, contract_name: &str) -> Option<&AddressableEntityHash> { self.0.get(contract_name) } /// Returns `true` if the given contract hash exists as a value in the registry. - pub fn has_contract_hash(&self, contract_hash: &ContractHash) -> bool { + pub fn has_contract_hash(&self, contract_hash: &AddressableEntityHash) -> bool { self.0 .values() .any(|system_contract_hash| system_contract_hash == contract_hash) } + + /// Remove standard payment from the contract registry. + pub fn remove_standard_payment(&mut self) -> Option { + self.0.remove(STANDARD_PAYMENT) + } } impl ToBytes for SystemContractRegistry { @@ -58,7 +64,7 @@ impl FromBytes for SystemContractRegistry { impl CLTyped for SystemContractRegistry { fn cl_type() -> CLType { - BTreeMap::::cl_type() + BTreeMap::::cl_type() } } @@ -69,7 +75,7 @@ mod tests { #[test] fn bytesrepr_roundtrip() { let mut system_contract_registry = SystemContractRegistry::new(); - system_contract_registry.insert("a".to_string(), ContractHash::new([9; 32])); + system_contract_registry.insert("a".to_string(), AddressableEntityHash::new([9; 32])); bytesrepr::test_serialization_roundtrip(&system_contract_registry); } } diff --git a/execution_engine/src/engine_state/upgrade.rs b/execution_engine/src/engine_state/upgrade.rs index 4f09dd678e..fac35aca96 100644 --- a/execution_engine/src/engine_state/upgrade.rs +++ b/execution_engine/src/engine_state/upgrade.rs @@ -8,15 +8,15 @@ use casper_types::{ addressable_entity::{ActionThresholds, AssociatedKeys, NamedKeys, Weight}, bytesrepr::{self, ToBytes}, execution::Effects, - package::{ContractPackageKind, ContractPackageStatus, ContractVersions, Groups}, - system::{handle_payment::ACCUMULATION_PURSE_KEY, SystemContractType}, - AccessRights, AddressableEntity, CLValue, CLValueError, ContractHash, ContractPackageHash, - ContractWasm, Digest, EntryPoints, FeeHandling, Key, Package, Phase, ProtocolVersion, - PublicKey, StoredValue, URef, U512, + package::{EntityVersions, Groups, PackageKind, PackageKindTag, PackageStatus}, + system::{handle_payment::ACCUMULATION_PURSE_KEY, SystemEntityType}, + AccessRights, AddressableEntity, AddressableEntityHash, ByteCode, ByteCodeKind, CLValue, + CLValueError, Digest, EntryPoints, FeeHandling, Key, Package, PackageHash, Phase, + ProtocolVersion, PublicKey, StoredValue, URef, U512, }; use crate::{ - engine_state::ACCOUNT_WASM_HASH, execution::AddressGenerator, tracking_copy::TrackingCopy, + engine_state::ACCOUNT_BYTE_CODE_HASH, execution::AddressGenerator, tracking_copy::TrackingCopy, }; use super::EngineConfig; @@ -107,20 +107,15 @@ where /// Bump major version and/or update the entry points for system contracts. pub(crate) fn refresh_system_contracts( &self, - mint_hash: &ContractHash, - auction_hash: &ContractHash, - handle_payment_hash: &ContractHash, - standard_payment_hash: &ContractHash, + mint_hash: &AddressableEntityHash, + auction_hash: &AddressableEntityHash, + handle_payment_hash: &AddressableEntityHash, ) -> Result<(), ProtocolUpgradeError> { - self.refresh_system_contract_entry_points(*mint_hash, SystemContractType::Mint)?; - self.refresh_system_contract_entry_points(*auction_hash, SystemContractType::Auction)?; + self.refresh_system_contract_entry_points(*mint_hash, SystemEntityType::Mint)?; + self.refresh_system_contract_entry_points(*auction_hash, SystemEntityType::Auction)?; self.refresh_system_contract_entry_points( *handle_payment_hash, - SystemContractType::HandlePayment, - )?; - self.refresh_system_contract_entry_points( - *standard_payment_hash, - SystemContractType::StandardPayment, + SystemEntityType::HandlePayment, )?; Ok(()) @@ -130,53 +125,26 @@ where /// and bump the contract version at a major version upgrade. fn refresh_system_contract_entry_points( &self, - contract_hash: ContractHash, - system_contract_type: SystemContractType, + contract_hash: AddressableEntityHash, + system_contract_type: SystemEntityType, ) -> Result<(), ProtocolUpgradeError> { let contract_name = system_contract_type.contract_name(); let entry_points = system_contract_type.contract_entry_points(); let mut contract = self.retrieve_system_contract(contract_hash, system_contract_type)?; - let contract_package_key = Key::Hash(contract.contract_package_hash().value()); + let mut package = + self.retrieve_system_package(contract.package_hash(), system_contract_type)?; - let mut contract_package = if let StoredValue::ContractPackage(contract_package) = self - .tracking_copy - .borrow_mut() - .read(&contract_package_key) - .map_err(|_| { - ProtocolUpgradeError::UnableToRetrieveSystemContractPackage( - contract_name.to_string(), - ) - })? - .ok_or_else(|| { - ProtocolUpgradeError::UnableToRetrieveSystemContractPackage( - contract_name.to_string(), - ) - })? { - contract_package - } else { - return Err(ProtocolUpgradeError::UnableToRetrieveSystemContractPackage( - contract_name, - )); - }; - - // Update the package kind from legacy to system contract - if contract_package.is_legacy() { - contract_package.update_package_kind(ContractPackageKind::System(system_contract_type)) - } - - contract_package - .disable_contract_version(contract_hash) - .map_err(|_| { - ProtocolUpgradeError::FailedToDisablePreviousVersion(contract_name.to_string()) - })?; + package.disable_entity_version(contract_hash).map_err(|_| { + ProtocolUpgradeError::FailedToDisablePreviousVersion(contract_name.to_string()) + })?; contract.set_protocol_version(self.new_protocol_version); let new_entity = AddressableEntity::new( - contract.contract_package_hash(), - contract.contract_wasm_hash(), + contract.package_hash(), + contract.byte_code_hash(), contract.named_keys().clone(), entry_points, self.new_protocol_version, @@ -184,45 +152,106 @@ where AssociatedKeys::default(), ActionThresholds::default(), ); - self.tracking_copy.borrow_mut().write( - contract_hash.into(), - StoredValue::AddressableEntity(new_entity), - ); - contract_package - .insert_contract_version(self.new_protocol_version.value().major, contract_hash); + let byte_code_key = + Key::byte_code_key(ByteCodeKind::Empty, contract.byte_code_hash().value()); + let byte_code = ByteCode::new(ByteCodeKind::Empty, vec![]); + + self.tracking_copy + .borrow_mut() + .write(byte_code_key, StoredValue::ByteCode(byte_code)); + + let entity_key = Key::addressable_entity_key(PackageKindTag::System, contract_hash); + + self.tracking_copy + .borrow_mut() + .write(entity_key, StoredValue::AddressableEntity(new_entity)); + + package.insert_entity_version(self.new_protocol_version.value().major, contract_hash); self.tracking_copy.borrow_mut().write( - contract_package_key, - StoredValue::ContractPackage(contract_package), + Key::Package(contract.package_hash().value()), + StoredValue::Package(package), ); Ok(()) } + fn retrieve_system_package( + &self, + package_hash: PackageHash, + system_contract_type: SystemEntityType, + ) -> Result { + if let Some(StoredValue::Package(system_entity)) = self + .tracking_copy + .borrow_mut() + .read(&Key::Package(package_hash.value())) + .map_err(|_| { + ProtocolUpgradeError::UnableToRetrieveSystemContractPackage( + system_contract_type.to_string(), + ) + })? + { + return Ok(system_entity); + } + + if let Some(StoredValue::ContractPackage(contract_package)) = self + .tracking_copy + .borrow_mut() + .read(&Key::Hash(package_hash.value())) + .map_err(|_| { + ProtocolUpgradeError::UnableToRetrieveSystemContractPackage( + system_contract_type.to_string(), + ) + })? + { + let mut package: Package = contract_package.into(); + package.update_package_kind(PackageKind::System(system_contract_type)); + return Ok(package); + } + + Err(ProtocolUpgradeError::UnableToRetrieveSystemContractPackage( + system_contract_type.to_string(), + )) + } + fn retrieve_system_contract( &self, - contract_hash: ContractHash, - system_contract_type: SystemContractType, + contract_hash: AddressableEntityHash, + system_contract_type: SystemEntityType, ) -> Result { - match self + if let Some(StoredValue::AddressableEntity(system_entity)) = self + .tracking_copy + .borrow_mut() + .read(&Key::AddressableEntity(( + PackageKindTag::System, + contract_hash.value(), + ))) + .map_err(|_| { + ProtocolUpgradeError::UnableToRetrieveSystemContract( + system_contract_type.to_string(), + ) + })? + { + return Ok(system_entity); + } + + if let Some(StoredValue::Contract(system_contract)) = self .tracking_copy .borrow_mut() - .read(&contract_hash.into()) + .read(&Key::Hash(contract_hash.value())) .map_err(|_| { ProtocolUpgradeError::UnableToRetrieveSystemContract( system_contract_type.to_string(), ) - })? { - None => Err(ProtocolUpgradeError::UnableToRetrieveSystemContract( - system_contract_type.to_string(), - )), - Some(StoredValue::AddressableEntity(entity)) => Ok(entity), - Some(StoredValue::Contract(contract)) => Ok(contract.into()), - Some(_) => Err(ProtocolUpgradeError::UnableToRetrieveSystemContract( - system_contract_type.to_string(), - )), + })? + { + return Ok(system_contract.into()); } + + Err(ProtocolUpgradeError::UnableToRetrieveSystemContract( + system_contract_type.to_string(), + )) } pub(crate) fn migrate_system_account( @@ -231,11 +260,11 @@ where ) -> Result<(), ProtocolUpgradeError> { let mut address_generator = AddressGenerator::new(pre_state_hash.as_ref(), Phase::System); - let contract_wasm_hash = *ACCOUNT_WASM_HASH; - let contract_hash = ContractHash::new(address_generator.new_hash_address()); - let contract_package_hash = ContractPackageHash::new(address_generator.new_hash_address()); + let byte_code_hash = *ACCOUNT_BYTE_CODE_HASH; + let entity_hash = AddressableEntityHash::new(address_generator.new_hash_address()); + let package_hash = PackageHash::new(address_generator.new_hash_address()); - let contract_wasm = ContractWasm::new(vec![]); + let byte_code = ByteCode::new(ByteCodeKind::Empty, vec![]); let account_hash = PublicKey::System.to_account_hash(); let associated_keys = AssociatedKeys::new(account_hash, Weight::new(1)); @@ -260,8 +289,8 @@ where }; let contract = AddressableEntity::new( - contract_package_hash, - contract_wasm_hash, + package_hash, + byte_code_hash, NamedKeys::new(), EntryPoints::new(), self.new_protocol_version, @@ -275,32 +304,32 @@ where let contract_package = { let mut contract_package = Package::new( access_key, - ContractVersions::default(), + EntityVersions::default(), BTreeSet::default(), Groups::default(), - ContractPackageStatus::default(), - ContractPackageKind::Account(account_hash), + PackageStatus::default(), + PackageKind::Account(account_hash), ); contract_package - .insert_contract_version(self.new_protocol_version.value().major, contract_hash); + .insert_entity_version(self.new_protocol_version.value().major, entity_hash); contract_package }; - self.tracking_copy.borrow_mut().write( - contract_wasm_hash.into(), - StoredValue::ContractWasm(contract_wasm), - ); - self.tracking_copy.borrow_mut().write( - contract_hash.into(), - StoredValue::AddressableEntity(contract), - ); - self.tracking_copy.borrow_mut().write( - contract_package_hash.into(), - StoredValue::ContractPackage(contract_package), - ); + let byte_code_key = Key::ByteCode((ByteCodeKind::Empty, byte_code_hash.value())); + self.tracking_copy + .borrow_mut() + .write(byte_code_key, StoredValue::ByteCode(byte_code)); + + let entity_key = Key::addressable_entity_key(PackageKindTag::Account, entity_hash); + self.tracking_copy + .borrow_mut() + .write(entity_key, StoredValue::AddressableEntity(contract)); - let contract_key: Key = contract_hash.into(); - let contract_by_account = CLValue::from_t(contract_key) + self.tracking_copy + .borrow_mut() + .write(package_hash.into(), StoredValue::Package(contract_package)); + + let contract_by_account = CLValue::from_t(entity_key) .map_err(|error| ProtocolUpgradeError::CLValue(error.to_string()))?; self.tracking_copy.borrow_mut().write( @@ -318,7 +347,7 @@ where /// create an accumulation purse. pub(crate) fn create_accumulation_purse_if_required( &self, - handle_payment_hash: &ContractHash, + handle_payment_hash: &AddressableEntityHash, engine_config: &EngineConfig, ) -> Result<(), ProtocolUpgradeError> { match engine_config.fee_handling() { @@ -330,7 +359,7 @@ where let phase = Phase::System; AddressGenerator::new(&seed_bytes, phase) }; - let system_contract = SystemContractType::HandlePayment; + let system_contract = SystemEntityType::HandlePayment; let mut addressable_entity = self.retrieve_system_contract(*handle_payment_hash, system_contract)?; @@ -351,8 +380,12 @@ where let mut new_named_keys = NamedKeys::new(); new_named_keys.insert(ACCUMULATION_PURSE_KEY.into(), Key::from(purse_uref)); addressable_entity.named_keys_append(new_named_keys); + + let entity_key = + Key::addressable_entity_key(PackageKindTag::System, *handle_payment_hash); + self.tracking_copy.borrow_mut().write( - (*handle_payment_hash).into(), + entity_key, StoredValue::AddressableEntity(addressable_entity), ); } diff --git a/execution_engine/src/execution/error.rs b/execution_engine/src/execution/error.rs index 8b2ac82207..c4fe45e367 100644 --- a/execution_engine/src/execution/error.rs +++ b/execution_engine/src/execution/error.rs @@ -7,9 +7,9 @@ use casper_types::{ addressable_entity::{AddKeyFailure, RemoveKeyFailure, SetThresholdFailure, UpdateKeyFailure}, bytesrepr, execution::TransformError, - package::ContractPackageKind, - system, AccessRights, ApiError, CLType, CLValueError, ContractHash, ContractPackageHash, - ContractVersionKey, ContractWasmHash, Key, StoredValueTypeMismatch, URef, + package::PackageKind, + system, AccessRights, AddressableEntityHash, ApiError, ByteCodeHash, CLType, CLValueError, + EntityVersionKey, Key, PackageHash, StoredValueTypeMismatch, URef, }; use crate::{ @@ -66,7 +66,7 @@ pub enum Error { /// Execution exceeded the gas limit. #[error("Out of gas error")] GasLimit, - /// A stored smart contract incorrectly called a ret function. + /// A stored smart contract called a ret function. #[error("Return")] Ret(Vec), /// Error using WASM host function resolver. @@ -121,10 +121,10 @@ pub enum Error { UnsupportedWasmStart, /// Contract package has no active contract versions. #[error("No active contract versions for contract package")] - NoActiveContractVersions(ContractPackageHash), - /// Invalid contract version supplied. - #[error("Invalid contract version: {}", _0)] - InvalidContractVersion(ContractVersionKey), + NoActiveEntityVersions(PackageHash), + /// Invalid entity version supplied. + #[error("Invalid entity version: {}", _0)] + InvalidEntityVersion(EntityVersionKey), /// Contract does not have specified entry point. #[error("No such method: {}", _0)] NoSuchMethod(String), @@ -142,16 +142,16 @@ pub enum Error { UnexpectedStoredValueVariant, /// Error upgrading a locked contract package. #[error("A locked contract cannot be upgraded")] - LockedContract(ContractPackageHash), + LockedEntity(PackageHash), /// Unable to find a contract package by a specified hash address. - #[error("Invalid contract package: {}", _0)] - InvalidContractPackage(ContractPackageHash), + #[error("Invalid package: {}", _0)] + InvalidPackage(PackageHash), /// Unable to find a contract by a specified hash address. #[error("Invalid contract: {}", _0)] - InvalidContract(ContractHash), + InvalidEntity(AddressableEntityHash), /// Unable to find the WASM bytes specified by a hash address. #[error("Invalid contract WASM: {}", _0)] - InvalidContractWasm(ContractWasmHash), + InvalidByteCode(ByteCodeHash), /// Error calling a smart contract with a missing argument. #[error("Missing argument: {name}")] MissingArgument { @@ -178,7 +178,7 @@ pub enum Error { MissingRuntimeStack, /// Contract is disabled. #[error("Contract is disabled")] - DisabledContract(ContractHash), + DisabledEntity(AddressableEntityHash), /// Transform error. #[error(transparent)] Transform(TransformError), @@ -187,10 +187,16 @@ pub enum Error { UnexpectedKeyVariant(Key), /// Invalid Contract package kind. #[error("Invalid contract package kind: {0}")] - InvalidContractPackageKind(ContractPackageKind), + InvalidPackageKind(PackageKind), /// Failed to transfer tokens on a private chain. #[error("Failed to transfer with unrestricted transfers disabled")] DisabledUnrestrictedTransfers, + /// Weight of all used associated keys does not meet entity's upgrade threshold. + #[error("Deployment authorization failure")] + UpgradeAuthorizationFailure, + /// The EntryPoints contains an invalid entry. + #[error("The EntryPoints contains an invalid entry")] + InvalidEntryPointType, } impl From for Error { diff --git a/execution_engine/src/execution/executor.rs b/execution_engine/src/execution/executor.rs index 301e434ec0..e1a2fd97ff 100644 --- a/execution_engine/src/execution/executor.rs +++ b/execution_engine/src/execution/executor.rs @@ -1,18 +1,24 @@ -use std::{cell::RefCell, collections::BTreeSet, rc::Rc}; +use std::{cell::RefCell, collections::BTreeSet, convert::TryFrom, rc::Rc}; use casper_storage::global_state::state::StateReader; + use casper_types::{ account::AccountHash, addressable_entity::NamedKeys, bytesrepr::FromBytes, - package::ContractPackageKind, + package::PackageKind, system::{auction, handle_payment, mint, AUCTION, HANDLE_PAYMENT, MINT}, - AddressableEntity, BlockTime, CLTyped, ContextAccessRights, ContractHash, DeployHash, - EntryPointType, Gas, Key, Phase, ProtocolVersion, RuntimeArgs, StoredValue, U512, + AddressableEntity, AddressableEntityHash, ApiError, BlockTime, CLTyped, ContextAccessRights, + DeployHash, EntryPointType, Gas, Key, Phase, ProtocolVersion, RuntimeArgs, StoredValue, Tagged, + URef, U512, }; +use crate::engine_state::TransferArgs; + use crate::{ - engine_state::{execution_kind::ExecutionKind, EngineConfig, ExecutionResult}, + engine_state::{ + execution_kind::ExecutionKind, EngineConfig, Error as EngineStateError, ExecutionResult, + }, execution::{address_generator::AddressGenerator, Error}, runtime::{Runtime, RuntimeStack}, runtime_context::RuntimeContext, @@ -45,9 +51,9 @@ impl Executor { &self, execution_kind: ExecutionKind, args: RuntimeArgs, - contract_hash: ContractHash, + entity_hash: AddressableEntityHash, entity: &AddressableEntity, - package_kind: ContractPackageKind, + package_kind: PackageKind, named_keys: &mut NamedKeys, access_rights: ContextAccessRights, authorization_keys: BTreeSet, @@ -76,10 +82,12 @@ impl Executor { Rc::new(RefCell::new(generator)) }; + let entity_key = Key::addressable_entity_key(package_kind.tag(), entity_hash); + let context = self.create_runtime_context( named_keys, entity, - contract_hash, + entity_key, authorization_keys, access_rights, package_kind, @@ -103,21 +111,13 @@ impl Executor { runtime.execute_module_bytes(&module_bytes, stack) } ExecutionKind::Contract { - contract_hash, + entity_hash: contract_hash, entry_point_name, } => { // 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`). - match runtime.migrate_contract_and_contract_package(contract_hash) { - Ok(()) => runtime.call_contract_with_stack( - contract_hash, - &entry_point_name, - args, - stack, - ), - Err(error) => Err(error), - } + runtime.call_contract_with_stack(contract_hash, &entry_point_name, args, stack) } }; @@ -136,83 +136,6 @@ impl Executor { } } - /// Executes standard payment code natively. - #[allow(clippy::too_many_arguments)] - pub(crate) fn exec_standard_payment( - &self, - payment_args: RuntimeArgs, - payment_base_key: ContractHash, - entity: &AddressableEntity, - package_kind: ContractPackageKind, - payment_named_keys: &mut NamedKeys, - access_rights: ContextAccessRights, - authorization_keys: BTreeSet, - account_hash: AccountHash, - blocktime: BlockTime, - deploy_hash: DeployHash, - payment_gas_limit: Gas, - protocol_version: ProtocolVersion, - tracking_copy: Rc>>, - phase: Phase, - stack: RuntimeStack, - ) -> ExecutionResult - where - R: StateReader, - R::Error: Into, - { - let spending_limit: U512 = match try_get_amount(&payment_args) { - Ok(spending_limit) => spending_limit, - Err(error) => { - return ExecutionResult::precondition_failure(error.into()); - } - }; - - let address_generator = { - let generator = AddressGenerator::new(deploy_hash.as_ref(), phase); - Rc::new(RefCell::new(generator)) - }; - - let runtime_context = self.create_runtime_context( - payment_named_keys, - entity, - payment_base_key, - authorization_keys, - access_rights, - package_kind, - account_hash, - address_generator, - Rc::clone(&tracking_copy), - blocktime, - protocol_version, - deploy_hash, - phase, - payment_args, - payment_gas_limit, - spending_limit, - EntryPointType::Session, - ); - - let effects = tracking_copy.borrow().effects(); - - // Standard payment is executed in the calling account's context; the stack already - // captures that. - let mut runtime = Runtime::new(runtime_context); - - match runtime.call_host_standard_payment(stack) { - Ok(()) => ExecutionResult::Success { - effects: runtime.context().effects(), - transfers: runtime.context().transfers().to_owned(), - cost: runtime.context().gas_counter(), - }, - Err(error) => ExecutionResult::Failure { - effects, - error: error.into(), - transfers: runtime.context().transfers().to_owned(), - cost: runtime.context().gas_counter(), - }, - } - } - /// Handles necessary address resolution and orchestration to securely call a system contract /// using the runtime. #[allow(clippy::too_many_arguments)] @@ -221,7 +144,7 @@ impl Executor { direct_system_contract_call: DirectSystemContractCall, runtime_args: RuntimeArgs, entity: &AddressableEntity, - package_kind: ContractPackageKind, + package_kind: PackageKind, authorization_keys: BTreeSet, account_hash: AccountHash, blocktime: BlockTime, @@ -257,7 +180,7 @@ impl Executor { let entry_point_name = direct_system_contract_call.entry_point_name(); - let contract_hash = match direct_system_contract_call { + let entity_hash = match direct_system_contract_call { DirectSystemContractCall::Slash | DirectSystemContractCall::RunAuction | DirectSystemContractCall::DistributeRewards => { @@ -282,18 +205,19 @@ impl Executor { } }; - let contract = match tracking_copy.borrow_mut().get_contract(contract_hash) { + let contract = match tracking_copy.borrow_mut().get_contract(entity_hash) { Ok(contract) => contract, Err(error) => return (None, ExecutionResult::precondition_failure(error.into())), }; let mut named_keys = contract.named_keys().clone(); - let access_rights = contract.extract_access_rights(contract_hash); + let access_rights = contract.extract_access_rights(entity_hash); + let entity_address = Key::addressable_entity_key(package_kind.tag(), entity_hash); let runtime_context = self.create_runtime_context( &mut named_keys, entity, - contract_hash, + entity_address, authorization_keys, access_rights, package_kind, @@ -307,7 +231,7 @@ impl Executor { runtime_args.clone(), gas_limit, remaining_spending_limit, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let mut runtime = Runtime::new(runtime_context); @@ -318,7 +242,7 @@ impl Executor { // contracts, to force all such security checks for usage via the executor into a single // execution path. let result = - runtime.call_contract_with_stack(contract_hash, entry_point_name, runtime_args, stack); + runtime.call_contract_with_stack(entity_hash, entry_point_name, runtime_args, stack); match result { Ok(value) => match value.into_t() { @@ -352,10 +276,10 @@ impl Executor { &self, named_keys: &'a mut NamedKeys, entity: &'a AddressableEntity, - entity_address: ContractHash, + entity_key: Key, authorization_keys: BTreeSet, access_rights: ContextAccessRights, - package_kind: ContractPackageKind, + package_kind: PackageKind, account_hash: AccountHash, address_generator: Rc>, tracking_copy: Rc>>, @@ -378,7 +302,7 @@ impl Executor { RuntimeContext::new( named_keys, entity, - entity_address, + entity_key, authorization_keys, access_rights, package_kind, @@ -398,6 +322,185 @@ impl Executor { entry_point_type, ) } + + /// Executes standard payment code natively. + #[allow(clippy::too_many_arguments)] + pub(crate) fn exec_standard_payment( + &self, + payment_args: RuntimeArgs, + entity: &AddressableEntity, + package_kind: PackageKind, + authorization_keys: BTreeSet, + account_hash: AccountHash, + blocktime: BlockTime, + deploy_hash: DeployHash, + 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, + package_kind, + authorization_keys.clone(), + account_hash, + blocktime, + deploy_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( + Error::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, + package_kind, + authorization_keys, + account_hash, + blocktime, + deploy_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, + package_kind: PackageKind, + authorization_keys: BTreeSet, + account_hash: AccountHash, + blocktime: BlockTime, + deploy_hash: DeployHash, + 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, + package_kind, + authorization_keys, + account_hash, + blocktime, + deploy_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, + package_kind: PackageKind, + authorization_keys: BTreeSet, + account_hash: AccountHash, + blocktime: BlockTime, + deploy_hash: DeployHash, + 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, + package_kind, + authorization_keys, + account_hash, + blocktime, + deploy_hash, + gas_limit, + protocol_version, + Rc::clone(&tracking_copy), + Phase::Payment, + stack, + spending_limit, + ) + } } /// Represents a variant of a system contract call. diff --git a/execution_engine/src/execution/mod.rs b/execution_engine/src/execution/mod.rs index f3d88e65aa..69925aaad0 100644 --- a/execution_engine/src/execution/mod.rs +++ b/execution_engine/src/execution/mod.rs @@ -4,8 +4,5 @@ mod error; #[macro_use] mod executor; -pub use self::error::Error; -pub(crate) use self::{ - address_generator::AddressGenerator, - executor::{DirectSystemContractCall, Executor}, -}; +pub(crate) use self::executor::{DirectSystemContractCall, Executor}; +pub use self::{address_generator::AddressGenerator, error::Error}; diff --git a/execution_engine/src/resolvers/v1_function_index.rs b/execution_engine/src/resolvers/v1_function_index.rs index 56625d6e21..d6ff7be557 100644 --- a/execution_engine/src/resolvers/v1_function_index.rs +++ b/execution_engine/src/resolvers/v1_function_index.rs @@ -38,7 +38,7 @@ pub(crate) enum FunctionIndex { GetMainPurseIndex, ReadHostBufferIndex, CreateContractPackageAtHash, - AddContractVersion, + AddPackageVersion, DisableContractVersion, CallVersionedContract, CreateContractUserGroup, @@ -60,6 +60,7 @@ pub(crate) enum FunctionIndex { RandomBytes, DictionaryReadFuncIndex, EnableContractVersion, + AddSessionVersion, } impl From for usize { diff --git a/execution_engine/src/resolvers/v1_resolver.rs b/execution_engine/src/resolvers/v1_resolver.rs index 1c7796baa9..31d49b4987 100644 --- a/execution_engine/src/resolvers/v1_resolver.rs +++ b/execution_engine/src/resolvers/v1_resolver.rs @@ -160,9 +160,9 @@ impl ModuleImportResolver for RuntimeModuleImportResolver { Signature::new(&[ValueType::I32; 8][..], Some(ValueType::I32)), FunctionIndex::CreateContractUserGroup.into(), ), - "casper_add_contract_version" => FuncInstance::alloc_host( - Signature::new(&[ValueType::I32; 10][..], Some(ValueType::I32)), - FunctionIndex::AddContractVersion.into(), + "casper_add_package_version" => FuncInstance::alloc_host( + Signature::new(&[ValueType::I32; 9][..], Some(ValueType::I32)), + FunctionIndex::AddPackageVersion.into(), ), "casper_disable_contract_version" => FuncInstance::alloc_host( Signature::new(&[ValueType::I32; 4][..], Some(ValueType::I32)), @@ -245,6 +245,10 @@ impl ModuleImportResolver for RuntimeModuleImportResolver { Signature::new(&[ValueType::I32; 4][..], Some(ValueType::I32)), FunctionIndex::EnableContractVersion.into(), ), + "casper_add_session_logic" => FuncInstance::alloc_host( + Signature::new(&[ValueType::I32; 2][..], Some(ValueType::I32)), + FunctionIndex::AddSessionVersion.into(), + ), _ => { return Err(InterpreterError::Function(format!( "host module doesn't export function with name {}", diff --git a/execution_engine/src/runtime/externals.rs b/execution_engine/src/runtime/externals.rs index a35379a65f..544a3bee37 100644 --- a/execution_engine/src/runtime/externals.rs +++ b/execution_engine/src/runtime/externals.rs @@ -9,11 +9,11 @@ use casper_types::{ api_error, bytesrepr::{self, ToBytes}, crypto, - package::{ContractPackageKind, ContractPackageStatus}, + package::{PackageKind, PackageStatus}, system::auction::EraInfo, - ApiError, ContractHash, ContractPackageHash, ContractVersion, EraId, Gas, Group, HostFunction, - HostFunctionCost, Key, StoredValue, URef, DEFAULT_HOST_FUNCTION_NEW_DICTIONARY, U512, - UREF_SERIALIZED_LENGTH, + AddressableEntityHash, ApiError, EntityVersion, EraId, Gas, Group, HostFunction, + HostFunctionCost, Key, PackageHash, StoredValue, URef, DEFAULT_HOST_FUNCTION_NEW_DICTIONARY, + U512, UREF_SERIALIZED_LENGTH, }; use super::{args::Args, Error, Runtime}; @@ -545,9 +545,9 @@ where &host_function_costs.create_contract_package_at_hash, [hash_dest_ptr, access_dest_ptr], )?; - let package_status = ContractPackageStatus::new(is_locked); + let package_status = PackageStatus::new(is_locked); let (hash_addr, access_addr) = self - .create_contract_package_at_hash(package_status, ContractPackageKind::Wasm)?; + .create_contract_package_at_hash(package_status, PackageKind::SmartContract)?; self.function_address(hash_addr, hash_dest_ptr)?; self.function_address(access_addr, access_dest_ptr)?; @@ -587,7 +587,7 @@ where ], )?; - let contract_package_hash: ContractPackageHash = + let contract_package_hash: PackageHash = self.t_from_mem(package_key_ptr, package_key_size)?; let label: String = self.t_from_mem(label_ptr, label_size)?; let existing_urefs: BTreeSet = @@ -602,17 +602,30 @@ where )?; Ok(Some(RuntimeValue::I32(api_error::i32_from(ret)))) } + FunctionIndex::AddSessionVersion => { + // args(0) = pointer to entrypoints in wasm memory + // args(1) = size of entrypoints in wasm memory + let (entry_points_ptr, entry_points_size) = Args::parse(args)?; + self.charge_host_function_call( + &host_function_costs.add_session_version, + [entry_points_ptr, entry_points_size], + )?; - FunctionIndex::AddContractVersion => { - // args(0) = pointer to package key in wasm memory - // args(1) = size of package key in wasm memory - // args(2) = pointer to entrypoints in wasm memory - // args(3) = size of entrypoints in wasm memory - // args(4) = pointer to named keys in wasm memory - // args(5) = size of named keys in wasm memory - // args(6) = pointer to output buffer for serialized key - // args(7) = size of output buffer - // args(8) = pointer to bytes written + let entry_points: EntryPoints = + self.t_from_mem(entry_points_ptr, entry_points_size)?; + let ret = self.add_session_version(entry_points)?; + Ok(Some(RuntimeValue::I32(api_error::i32_from(ret)))) + } + FunctionIndex::AddPackageVersion => { + // args(0) = pointer to package hash in wasm memory + // args(1) = size of package hash in wasm memory + // args(2) = pointer to entity version in wasm memory + // args(3) = pointer to entrypoints in wasm memory + // args(4) = size of entrypoints in wasm memory + // args(5) = pointer to named keys in wasm memory + // args(6) = size of named keys in wasm memory + // args(7) = pointer to output buffer for serialized key + // args(8) = size of output buffer let ( contract_package_hash_ptr, contract_package_hash_size, @@ -623,8 +636,8 @@ where named_keys_size, output_ptr, output_size, - bytes_written_ptr, ) = Args::parse(args)?; + self.charge_host_function_call( &host_function_costs.add_contract_version, [ @@ -637,23 +650,28 @@ where named_keys_size, output_ptr, output_size, - bytes_written_ptr, ], )?; - let contract_package_hash: ContractPackageHash = + // Exit if unable to return output. + if output_size < 32 { + // `output_size` must be >= actual length of serialized hash bytes + return Ok(Some(RuntimeValue::I32(api_error::i32_from(Err( + ApiError::BufferTooSmall, + ))))); + } + + let package_hash: PackageHash = self.t_from_mem(contract_package_hash_ptr, contract_package_hash_size)?; let entry_points: EntryPoints = self.t_from_mem(entry_points_ptr, entry_points_size)?; let named_keys: NamedKeys = self.t_from_mem(named_keys_ptr, named_keys_size)?; let ret = self.add_contract_version( - contract_package_hash, + package_hash, + version_ptr, entry_points, named_keys, output_ptr, - output_size as usize, - bytes_written_ptr, - version_ptr, )?; Ok(Some(RuntimeValue::I32(api_error::i32_from(ret)))) } @@ -712,7 +730,7 @@ where ], )?; - let contract_hash: ContractHash = + let contract_hash: AddressableEntityHash = self.t_from_mem(contract_hash_ptr, contract_hash_size)?; let entry_point_name: String = self.t_from_mem(entry_point_name_ptr, entry_point_name_size)?; @@ -766,9 +784,9 @@ where ], )?; - let contract_package_hash: ContractPackageHash = + let contract_package_hash: PackageHash = self.t_from_mem(contract_package_hash_ptr, contract_package_hash_size)?; - let contract_version: Option = + let contract_version: Option = self.t_from_mem(contract_version_ptr, contract_package_size)?; let entry_point_name: String = self.t_from_mem(entry_point_name_ptr, entry_point_name_size)?; diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index e8de34731d..533e33c8d1 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -6,7 +6,6 @@ mod handle_payment_internal; mod host_function_flag; mod mint_internal; pub mod stack; -mod standard_payment_internal; mod utils; mod wasm_prep; @@ -25,35 +24,33 @@ use casper_storage::global_state::state::StateReader; use casper_types::{ account::{Account, AccountHash}, addressable_entity::{ - self, ActionThresholds, ActionType, AddKeyFailure, AddressableEntity, AssociatedKeys, - ContractHash, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys, - Parameter, RemoveKeyFailure, SetThresholdFailure, UpdateKeyFailure, Weight, - DEFAULT_ENTRY_POINT_NAME, + self, ActionThresholds, ActionType, AddKeyFailure, AddressableEntity, + AddressableEntityHash, AssociatedKeys, EntryPoint, EntryPointAccess, EntryPointType, + EntryPoints, NamedKeys, Parameter, RemoveKeyFailure, SetThresholdFailure, UpdateKeyFailure, + Weight, DEFAULT_ENTRY_POINT_NAME, }, bytesrepr::{self, Bytes, FromBytes, ToBytes}, - package::{ContractPackageKind, ContractPackageStatus}, + contracts::ContractPackage, + package::{PackageKind, PackageKindTag, PackageStatus}, system::{ self, auction::{self, EraInfo}, - handle_payment, mint, standard_payment, CallStackElement, SystemContractType, AUCTION, - HANDLE_PAYMENT, MINT, STANDARD_PAYMENT, + handle_payment, mint, CallStackElement, SystemEntityType, AUCTION, HANDLE_PAYMENT, MINT, + STANDARD_PAYMENT, }, - AccessRights, ApiError, CLTyped, CLValue, ContextAccessRights, ContractPackageHash, - ContractVersion, ContractVersionKey, ContractVersions, ContractWasm, DeployHash, Gas, - GrantedAccess, Group, Groups, HostFunction, HostFunctionCost, Key, NamedArg, Package, Phase, - PublicKey, RuntimeArgs, StoredValue, Transfer, TransferResult, TransferredTo, URef, - DICTIONARY_ITEM_KEY_MAX_LENGTH, U512, + AccessRights, ApiError, ByteCode, ByteCodeHash, ByteCodeKind, CLTyped, CLValue, + ContextAccessRights, ContractWasm, DeployHash, 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, }; use crate::{ - engine_state::ACCOUNT_WASM_HASH, + engine_state::ACCOUNT_BYTE_CODE_HASH, execution::{self, Error}, runtime::host_function_flag::HostFunctionFlag, runtime_context::RuntimeContext, - system::{ - auction::Auction, handle_payment::HandlePayment, mint::Mint, - standard_payment::StandardPayment, - }, + system::{auction::Auction, handle_payment::HandlePayment, mint::Mint}, tracking_copy::TrackingCopyExt, }; pub use stack::{RuntimeStack, RuntimeStackFrame, RuntimeStackOverflow}; @@ -62,13 +59,14 @@ pub use wasm_prep::{ DEFAULT_MAX_PARAMETER_COUNT, DEFAULT_MAX_TABLE_SIZE, }; +#[derive(Debug)] enum CallContractIdentifier { Contract { - contract_hash: ContractHash, + contract_hash: AddressableEntityHash, }, ContractPackage { - contract_package_hash: ContractPackageHash, - version: Option, + contract_package_hash: PackageHash, + version: Option, }, } @@ -474,9 +472,8 @@ where } /// Checks if a [`Key`] is a system contract. - #[inline] - fn is_system_contract(&self, contract_hash: ContractHash) -> Result { - self.context.is_system_contract(&contract_hash) + fn is_system_contract(&self, entity_hash: AddressableEntityHash) -> Result { + self.context.is_system_addressable_entity(&entity_hash) } fn get_named_argument( @@ -525,12 +522,13 @@ where let gas_counter = self.gas_counter(); let mint_hash = self.context.get_system_contract(MINT)?; + let mint_key = Key::addressable_entity_key(PackageKindTag::System, mint_hash); let mint_contract = self.context.state().borrow_mut().get_contract(mint_hash)?; let mut named_keys = mint_contract.named_keys().to_owned(); let runtime_context = self.context.new_from_self( - mint_hash, - EntryPointType::Contract, + mint_key, + EntryPointType::AddressableEntity, &mut named_keys, access_rights, runtime_args.to_owned(), @@ -651,6 +649,8 @@ where let gas_counter = self.gas_counter(); let handle_payment_hash = self.context.get_system_contract(HANDLE_PAYMENT)?; + let handle_payment_key = + Key::addressable_entity_key(PackageKindTag::System, handle_payment_hash); let handle_payment_contract = self .context .state() @@ -659,8 +659,8 @@ where let mut named_keys = handle_payment_contract.named_keys().to_owned(); let runtime_context = self.context.new_from_self( - handle_payment_hash, - EntryPointType::Contract, + handle_payment_key, + EntryPointType::AddressableEntity, &mut named_keys, access_rights, runtime_args.to_owned(), @@ -736,18 +736,18 @@ where Ok(ret) } - /// Calls host standard payment contract. - pub(crate) fn call_host_standard_payment(&mut self, stack: RuntimeStack) -> Result<(), Error> { - // NOTE: This method (unlike other call_host_* methods) already runs on its own runtime - // context. - self.stack = Some(stack); - let gas_counter = self.gas_counter(); - let amount: U512 = - Self::get_named_argument(self.context.args(), standard_payment::ARG_AMOUNT)?; - let result = self.pay(amount).map_err(Self::reverter); - self.set_gas_counter(gas_counter); - result - } + // /// Calls host standard payment contract. + // pub(crate) fn call_host_standard_payment(&mut self, stack: RuntimeStack) -> Result<(), Error> + // { // NOTE: This method (unlike other call_host_* methods) already runs on its own + // runtime // context. + // self.stack = Some(stack); + // let gas_counter = self.gas_counter(); + // let amount: U512 = + // Self::get_named_argument(self.context.args(), standard_payment::ARG_AMOUNT)?; + // let result = self.pay(amount).map_err(Self::reverter); + // self.set_gas_counter(gas_counter); + // result + // } /// Calls host auction contract. fn call_host_auction( @@ -760,6 +760,7 @@ where let gas_counter = self.gas_counter(); let auction_hash = self.context.get_system_contract(AUCTION)?; + let auction_key = Key::addressable_entity_key(PackageKindTag::System, auction_hash); let auction_contract = self .context .state() @@ -768,8 +769,8 @@ where let mut named_keys = auction_contract.named_keys().to_owned(); let runtime_context = self.context.new_from_self( - auction_hash, - EntryPointType::Contract, + auction_key, + EntryPointType::AddressableEntity, &mut named_keys, access_rights, runtime_args.to_owned(), @@ -978,12 +979,13 @@ where /// Call a contract by pushing a stack element onto the frame. pub(crate) fn call_contract_with_stack( &mut self, - contract_hash: ContractHash, + contract_hash: AddressableEntityHash, entry_point_name: &str, args: RuntimeArgs, stack: RuntimeStack, ) -> Result { self.stack = Some(stack); + self.call_contract(contract_hash, entry_point_name, args) } @@ -1039,7 +1041,7 @@ where /// Calls contract living under a `key`, with supplied `args`. pub fn call_contract( &mut self, - contract_hash: ContractHash, + contract_hash: AddressableEntityHash, entry_point_name: &str, args: RuntimeArgs, ) -> Result { @@ -1053,8 +1055,8 @@ where /// types given in the contract header. pub fn call_versioned_contract( &mut self, - contract_package_hash: ContractPackageHash, - contract_version: Option, + contract_package_hash: PackageHash, + contract_version: Option, entry_point_name: String, args: RuntimeArgs, ) -> Result { @@ -1068,29 +1070,34 @@ where fn get_context_key_for_contract_call( &self, - contract_hash: ContractHash, + entity_hash: AddressableEntityHash, entry_point: &EntryPoint, - ) -> Result { + ) -> Result { let current = self.context.entry_point_type(); let next = entry_point.entry_point_type(); match (current, next) { - (EntryPointType::Contract, EntryPointType::Session) => { + (EntryPointType::AddressableEntity, EntryPointType::Session) => { // Session code can't be called from Contract code for security reasons. Err(Error::InvalidContext) } - (EntryPointType::Install, EntryPointType::Session) => { + (EntryPointType::Factory, EntryPointType::Session) => { // Session code can't be called from Installer code for security reasons. Err(Error::InvalidContext) } (EntryPointType::Session, EntryPointType::Session) => { // Session code called from session reuses current base key - Ok(self.context.get_entity_address()) + match self.context.get_entity_key().into_entity_hash() { + Some(entity_hash) => Ok(entity_hash), + None => Err(Error::InvalidEntity(entity_hash)), + } + } + (EntryPointType::Session, EntryPointType::AddressableEntity) + | (EntryPointType::AddressableEntity, EntryPointType::AddressableEntity) => { + Ok(entity_hash) } - (EntryPointType::Session, EntryPointType::Contract) - | (EntryPointType::Contract, EntryPointType::Contract) => Ok(contract_hash), _ => { // Any other combination (installer, normal, etc.) is a contract context. - Ok(contract_hash) + Ok(entity_hash) } } } @@ -1117,76 +1124,111 @@ where entry_point_name: &str, args: RuntimeArgs, ) -> Result { - let (contract, contract_hash, contract_package) = match identifier { - CallContractIdentifier::Contract { contract_hash } => { - let contract: AddressableEntity = - self.context.read_gs_typed(&Key::from(contract_hash))?; - let contract_package_key = Key::from(contract.contract_package_hash()); - let contract_package: Package = - self.context.read_gs_typed(&contract_package_key)?; + let (entity, entity_hash, package) = match identifier { + CallContractIdentifier::Contract { + contract_hash: entity_hash, + } => { + let entity_key = if self.context.is_system_addressable_entity(&entity_hash)? { + Key::addressable_entity_key(PackageKindTag::System, entity_hash) + } else { + Key::contract_entity_key(entity_hash) + }; + + let entity = if let Some(StoredValue::AddressableEntity(entity)) = + self.context.read_gs(&entity_key)? + { + entity + } else { + self.migrate_contract_and_contract_package(entity_hash)? + }; + + let package = Key::from(entity.package_hash()); + + let package: Package = self.context.read_gs_typed(&package)?; // System contract hashes are disabled at upgrade point - let is_calling_system_contract = self.is_system_contract(contract_hash)?; + let is_calling_system_contract = self.is_system_contract(entity_hash)?; // Check if provided contract hash is disabled - let is_contract_enabled = contract_package.is_contract_enabled(&contract_hash); + let is_contract_enabled = package.is_entity_enabled(&entity_hash); if !is_calling_system_contract && !is_contract_enabled { - return Err(Error::DisabledContract(contract_hash)); + return Err(Error::DisabledEntity(entity_hash)); } - (contract, contract_hash, contract_package) + (entity, entity_hash, package) } CallContractIdentifier::ContractPackage { contract_package_hash, version, } => { - let contract_package_key = Key::from(contract_package_hash); - let contract_package: Package = - self.context.read_gs_typed(&contract_package_key)?; + let package = self.context.get_package(contract_package_hash)?; let contract_version_key = match version { - Some(version) => ContractVersionKey::new( + Some(version) => EntityVersionKey::new( self.context.protocol_version().value().major, version, ), - None => match contract_package.current_contract_version() { + None => match package.current_entity_version() { Some(v) => v, None => { - return Err(Error::NoActiveContractVersions(contract_package_hash)); + return Err(Error::NoActiveEntityVersions(contract_package_hash)); } }, }; - let contract_hash = contract_package - .lookup_contract_hash(contract_version_key) + let entity_hash = package + .lookup_entity_hash(contract_version_key) .copied() - .ok_or(Error::InvalidContractVersion(contract_version_key))?; + .ok_or(Error::InvalidEntityVersion(contract_version_key))?; + + let entity_key = if self.context.is_system_addressable_entity(&entity_hash)? { + Key::addressable_entity_key(PackageKindTag::System, entity_hash) + } else { + Key::contract_entity_key(entity_hash) + }; - let contract_key = contract_hash.into(); - let contract: AddressableEntity = self.context.read_gs_typed(&contract_key)?; + let entity = if let Some(StoredValue::AddressableEntity(entity)) = + self.context.read_gs(&entity_key)? + { + entity + } else { + self.migrate_contract_and_contract_package(entity_hash)? + }; - (contract, contract_hash, contract_package) + (entity, entity_hash, package) } }; - if let ContractPackageKind::Account(_) = contract_package.get_package_kind() { + if let PackageKind::Account(_) = package.get_package_kind() { return Err(Error::InvalidContext); } - let entry_point = contract + let protocol_version = self.context.protocol_version(); + + // Check for major version compatibility before calling + if !entity.is_compatible_protocol_version(protocol_version) { + return Err(Error::IncompatibleProtocolMajorVersion { + actual: entity.protocol_version().value().major, + expected: protocol_version.value().major, + }); + } + + let entry_point = entity .entry_point(entry_point_name) .cloned() .ok_or_else(|| Error::NoSuchMethod(entry_point_name.to_owned()))?; + let entry_point_type = entry_point.entry_point_type(); + + if entry_point_type.is_invalid_context() { + return Err(Error::InvalidContext); + } + // Get contract entry point hash // if public, allowed // if not public, restricted to user group access // if abstract, not allowed - self.validate_entry_point_access( - &contract_package, - entry_point_name, - entry_point.access(), - )?; + self.validate_entry_point_access(&package, entry_point_name, entry_point.access())?; if self.context.engine_config().strict_argument_checking() { let entry_point_args_lookup: BTreeMap<&str, &Parameter> = entry_point @@ -1222,80 +1264,37 @@ where .engine_config() .administrative_accounts() .is_empty() - && !contract_package.is_contract_enabled(&contract_hash) - && !self.context.is_system_contract(&contract_hash)? + && !package.is_entity_enabled(&entity_hash) + && !self.context.is_system_addressable_entity(&entity_hash)? { - return Err(Error::DisabledContract(contract_hash)); + return Err(Error::DisabledEntity(entity_hash)); } // if session the caller's context // else the called contract's context - let context_contract_hash = - self.get_context_key_for_contract_call(contract_hash, &entry_point)?; - let protocol_version = self.context.protocol_version(); - - // Check for major version compatibility before calling - if !contract.is_compatible_protocol_version(protocol_version) { - return Err(Error::IncompatibleProtocolMajorVersion { - actual: contract.protocol_version().value().major, - expected: protocol_version.value().major, - }); - } - - let (mut named_keys, mut access_rights) = match entry_point.entry_point_type() { - EntryPointType::Session => ( - self.context.entity().named_keys().clone(), - self.context.entity().extract_access_rights(contract_hash), - ), - EntryPointType::Contract | EntryPointType::Install => ( - contract.named_keys().clone(), - contract.extract_access_rights(contract_hash), - ), + let context_entity_hash = + self.get_context_key_for_contract_call(entity_hash, &entry_point)?; + + let (should_attenuate_urefs, should_validate_urefs) = { + // Determines if this call originated from the system account based on a first + // element of the call stack. + let is_system_account = + self.context.get_caller() == PublicKey::System.to_account_hash(); + // Is the immediate caller a system contract, such as when the auction calls the mint. + let is_caller_system_contract = + self.is_system_contract(self.context.access_rights().context_key())?; + // Checks if the contract we're about to call is a system contract. + let is_calling_system_contract = self.is_system_contract(context_entity_hash)?; + // uref attenuation is necessary in the following circumstances: + // the originating account (aka the caller) is not the system account and + // the immediate caller is either a normal account or a normal contract and + // the target contract about to be called is a normal contract + let should_attenuate_urefs = + !is_system_account && !is_caller_system_contract && !is_calling_system_contract; + let should_validate_urefs = !is_caller_system_contract || !is_calling_system_contract; + (should_attenuate_urefs, should_validate_urefs) }; - - let stack = { - let mut stack = self.try_get_stack()?.clone(); - - let call_stack_element = match entry_point.entry_point_type() { - EntryPointType::Session => { - let account_hash = self.context().get_caller(); - - CallStackElement::stored_session( - account_hash, - contract.contract_package_hash(), - contract_hash, - ) - } - EntryPointType::Contract => CallStackElement::stored_contract( - contract.contract_package_hash(), - contract_hash, - ), - EntryPointType::Install => CallStackElement::stored_contract( - contract.contract_package_hash(), - contract_hash, - ), - }; - stack.push(call_stack_element)?; - - stack - }; - - // Determines if this call originated from the system account based on a first - // element of the call stack. - let is_system_account = self.context.get_caller() == PublicKey::System.to_account_hash(); - // Is the immediate caller a system contract, such as when the auction calls the mint. - let is_caller_system_contract = - self.is_system_contract(self.context.access_rights().context_key())?; - // Checks if the contract we're about to call is a system contract. - let is_calling_system_contract = self.is_system_contract(context_contract_hash)?; - // uref attenuation is necessary in the following circumstances: - // the originating account (aka the caller) is not the system account and - // the immediate caller is either a normal account or a normal contract and - // the target contract about to be called is a normal contract - let should_attenuate_urefs = - !is_system_account && !is_caller_system_contract && !is_calling_system_contract; - - let context_args = if should_attenuate_urefs { + let runtime_args = if should_attenuate_urefs { // Main purse URefs should be attenuated only when a non-system contract is executed by // a non-system account to avoid possible phishing attack scenarios. utils::attenuate_uref_in_args( @@ -1309,9 +1308,9 @@ where let extended_access_rights = { let mut all_urefs = vec![]; - for arg in context_args.to_values() { + for arg in runtime_args.to_values() { let urefs = utils::extract_urefs(arg)?; - if !is_caller_system_contract || !is_calling_system_contract { + if should_validate_urefs { for uref in &urefs { self.context.validate_uref(uref)?; } @@ -1321,132 +1320,144 @@ where all_urefs }; - access_rights.extend(&extended_access_rights); + let access_rights = { + let mut access_rights = entity.extract_access_rights(entity_hash); + access_rights.extend(&extended_access_rights); + access_rights + }; + + let stack = { + let mut stack = self.try_get_stack()?.clone(); + + stack.push(CallStackElement::stored_contract( + entity.package_hash(), + entity_hash, + ))?; + + stack + }; + + if let PackageKind::System(system_contract_type) = package.get_package_kind() { + let entry_point_name = entry_point.name(); - if let ContractPackageKind::System(system_contract_type) = - contract_package.get_package_kind() - { match system_contract_type { - SystemContractType::Mint => { + SystemEntityType::Mint => { return self.call_host_mint( - entry_point.name(), - &context_args, + entry_point_name, + &runtime_args, access_rights, stack, ); } - SystemContractType::HandlePayment => { + SystemEntityType::HandlePayment => { return self.call_host_handle_payment( - entry_point.name(), - &context_args, + entry_point_name, + &runtime_args, access_rights, stack, ); } - SystemContractType::StandardPayment => {} - SystemContractType::Auction => { + SystemEntityType::Auction => { return self.call_host_auction( - entry_point.name(), - &context_args, + entry_point_name, + &runtime_args, access_rights, stack, ); } + // Not callable + SystemEntityType::StandardPayment => {} } } let module: Module = { - let wasm_key = contract.contract_wasm_key(); + let byte_code_addr = entity.byte_code_addr(); - let contract_wasm: ContractWasm = match self.context.read_gs(&wasm_key)? { - Some(StoredValue::ContractWasm(contract_wasm)) => contract_wasm, - Some(_) => return Err(Error::InvalidContractWasm(contract.contract_wasm_hash())), - None => return Err(Error::KeyNotFound(Key::from(context_contract_hash))), + let byte_code_key = match package.get_package_kind() { + PackageKind::System(_) | PackageKind::Account(_) => { + Key::ByteCode((ByteCodeKind::Empty, byte_code_addr)) + } + PackageKind::SmartContract => { + Key::ByteCode((ByteCodeKind::V1CasperWasm, byte_code_addr)) + } }; - parity_wasm::deserialize_buffer(contract_wasm.bytes())? + let byte_code: ByteCode = match self.context.read_gs(&byte_code_key)? { + Some(StoredValue::ByteCode(byte_code)) => byte_code, + Some(_) => return Err(Error::InvalidByteCode(entity.byte_code_hash())), + None => return Err(Error::KeyNotFound(byte_code_key)), + }; + + parity_wasm::deserialize_buffer(byte_code.bytes())? }; + let mut named_keys = entity.take_named_keys(); + + let package_tag = package.get_package_kind().tag(); + + let context_entity_key = Key::addressable_entity_key(package_tag, entity_hash); + let context = self.context.new_from_self( - context_contract_hash, + context_entity_key, entry_point.entry_point_type(), &mut named_keys, access_rights, - context_args, + runtime_args, ); - let protocol_version = self.context.protocol_version(); + let (instance, memory) = utils::instance_and_memory( module.clone(), - protocol_version, + self.context.protocol_version(), self.context.engine_config(), )?; let runtime = &mut Runtime::new_invocation_runtime(self, context, module, memory, stack); - let result = instance.invoke_export(entry_point.name(), &[], runtime); - // The `runtime`'s context was initialized with our counter from before the call and any gas // charged by the sub-call was added to its counter - so let's copy the correct value of the // counter from there to our counter. self.context.set_gas_counter(runtime.context.gas_counter()); + let transfers = self.context.transfers_mut(); + *transfers = runtime.context.transfers().to_owned(); - { - let transfers = self.context.transfers_mut(); - *transfers = runtime.context.transfers().to_owned(); - } - - let error = match result { - Err(error) => error, - // If `Ok` and the `host_buffer` is `None`, the contract's execution succeeded but did - // not explicitly call `runtime::ret()`. Treat as though the execution returned the - // unit type `()` as per Rust functions which don't specify a return value. + return match result { Ok(_) => { - if self.context.entry_point_type() == EntryPointType::Session - && runtime.context.entry_point_type() == EntryPointType::Session - { - // Overwrites parent's named keys with child's new named key but only when - // running session code. - *self.context.named_keys_mut() = runtime.context.named_keys().clone(); - } + // If `Ok` and the `host_buffer` is `None`, the contract's execution succeeded but + // did not explicitly call `runtime::ret()`. Treat as though the + // execution returned the unit type `()` as per Rust functions which + // don't specify a return value. self.context .set_remaining_spending_limit(runtime.context.remaining_spending_limit()); - return Ok(runtime.take_host_buffer().unwrap_or(CLValue::from_t(())?)); + Ok(runtime.take_host_buffer().unwrap_or(CLValue::from_t(())?)) } - }; - - if let Some(host_error) = error.as_host_error() { - // If the "error" was in fact a trap caused by calling `ret` then 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(Error::Ret(ref ret_urefs)) => { - // Insert extra urefs returned from call. - // Those returned URef's are guaranteed to be valid as they were already - // validated in the `ret` call inside context we ret from. - self.context.access_rights_extend(ret_urefs); - - if self.context.entry_point_type() == EntryPointType::Session - && runtime.context.entry_point_type() == EntryPointType::Session - { - // Overwrites parent's named keys with child's new named keys but only when - // running session code. - *self.context.named_keys_mut() = runtime.context.named_keys().clone(); + Err(error) => { + if let Some(host_error) = error.as_host_error() { + // If the "error" was in fact a trap caused by calling `ret` then 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(Error::Ret(ref ret_urefs)) => { + // Insert extra urefs returned from call. + // Those returned URef's are guaranteed to be valid as they were already + // validated in the `ret` call inside context we ret from. + self.context.access_rights_extend(ret_urefs); + + // Stored contracts are expected to always call a `ret` function, + // otherwise it's an error. + return runtime.take_host_buffer().ok_or(Error::ExpectedReturnValue); + } + Some(error) => return Err(error.clone()), + None => return Err(Error::Interpreter(host_error.to_string())), } - - // Stored contracts are expected to always call a `ret` function, otherwise it's - // an error. - return runtime.take_host_buffer().ok_or(Error::ExpectedReturnValue); } - Some(error) => return Err(error.clone()), - None => return Err(Error::Interpreter(host_error.to_string())), + Err(Error::Interpreter(error.into())) } - } - - Err(Error::Interpreter(error.into())) + }; } fn call_contract_host_buffer( &mut self, - contract_hash: ContractHash, + contract_hash: AddressableEntityHash, entry_point_name: &str, args_bytes: Vec, result_size_ptr: u32, @@ -1462,8 +1473,8 @@ where fn call_versioned_contract_host_buffer( &mut self, - contract_package_hash: ContractPackageHash, - contract_version: Option, + contract_package_hash: PackageHash, + contract_version: Option, entry_point_name: String, args_bytes: Vec, result_size_ptr: u32, @@ -1568,13 +1579,13 @@ where fn create_contract_package( &mut self, - is_locked: ContractPackageStatus, - contract_package_kind: ContractPackageKind, + is_locked: PackageStatus, + contract_package_kind: PackageKind, ) -> Result<(Package, URef), Error> { let access_key = self.context.new_unit_uref()?; let contract_package = Package::new( access_key, - ContractVersions::new(), + EntityVersions::new(), BTreeSet::new(), Groups::new(), is_locked, @@ -1586,20 +1597,20 @@ where fn create_contract_package_at_hash( &mut self, - lock_status: ContractPackageStatus, - contract_package_kind: ContractPackageKind, + lock_status: PackageStatus, + contract_package_kind: PackageKind, ) -> Result<([u8; 32], [u8; 32]), Error> { let addr = self.context.new_hash_address()?; let (contract_package, access_key) = self.create_contract_package(lock_status, contract_package_kind)?; self.context - .metered_write_gs_unsafe(Key::Hash(addr), contract_package)?; + .metered_write_gs_unsafe(Key::Package(addr), contract_package)?; Ok((addr, access_key.addr())) } fn create_contract_user_group( &mut self, - contract_package_hash: ContractPackageHash, + contract_package_hash: PackageHash, label: String, num_new_urefs: u32, mut existing_urefs: BTreeSet, @@ -1668,75 +1679,109 @@ where Ok(Ok(())) } + fn add_session_version( + &mut self, + entry_points: EntryPoints, + ) -> Result, Error> { + let package_hash = self.context.entity().package_hash(); + + let package = self.context.get_package(package_hash)?; + + if !package.is_account_kind() { + return Err(Error::InvalidContext); + } + + let byte_code_hash = self.context.new_hash_address()?; + + let byte_code = { + let module_bytes = self.get_module_from_entry_points(&entry_points)?; + ByteCode::new(ByteCodeKind::V1CasperWasm, module_bytes) + }; + + let entity_hash = + if let Some(entity_hash) = self.context.get_entity_key().into_entity_hash() { + entity_hash + } else { + return Err(Error::UnexpectedKeyVariant(self.context.get_entity_key())); + }; + + let entity = self.context.entity().clone(); + + let updated_session_entity = + entity.update_session_entity(ByteCodeHash::new(byte_code_hash), entry_points); + + self.context.metered_write_gs_unsafe( + Key::ByteCode((ByteCodeKind::V1CasperWasm, byte_code_hash)), + byte_code, + )?; + + let package_kind = package.get_package_kind(); + + self.context.metered_write_gs_unsafe( + Key::AddressableEntity((package_kind.tag(), entity_hash.value())), + updated_session_entity, + )?; + + self.context + .metered_write_gs_unsafe(package_hash, package)?; + + Ok(Ok(())) + } + #[allow(clippy::too_many_arguments)] fn add_contract_version( &mut self, - package_hash: ContractPackageHash, + package_hash: PackageHash, + version_ptr: u32, entry_points: EntryPoints, mut named_keys: NamedKeys, output_ptr: u32, - output_size: usize, - bytes_written_ptr: u32, - version_ptr: u32, ) -> Result, Error> { - self.context.validate_key(&Key::from(package_hash))?; + if entry_points.contains_stored_session() { + return Err(Error::InvalidEntryPointType); + } - let mut package: Package = self.context.get_validated_package(package_hash)?; + let mut package = self.context.get_package(package_hash)?; - if package.get_package_kind() != ContractPackageKind::Wasm { + if package.get_package_kind() != PackageKind::SmartContract { return Err(Error::InvalidContext); } - let version = package.current_contract_version(); - // Return an error if the contract is locked and has some version associated with it. - if package.is_locked() && version.is_some() { - return Err(Error::LockedContract(package_hash)); + if package.is_locked() { + return Err(Error::LockedEntity(package_hash)); } - let contract_wasm_hash = self.context.new_hash_address()?; - let contract_wasm = { - let module_bytes = self.get_module_from_entry_points(&entry_points)?; - ContractWasm::new(module_bytes) - }; + let (main_purse, previous_named_keys, action_thresholds, associated_keys) = + self.new_version_entity_parts(&package)?; + + // TODO: EE-1032 - Implement different ways of carrying on existing named keys. + named_keys.append(previous_named_keys); + + let byte_code_hash = self.context.new_hash_address()?; let entity_hash = self.context.new_hash_address()?; let protocol_version = self.context.protocol_version(); - let major = protocol_version.value().major; - - // TODO: EE-1032 - Implement different ways of carrying on existing named keys - if let Some(previous_contract_hash) = package.current_contract_hash() { - let previous_contract: AddressableEntity = - self.context.read_gs_typed(&previous_contract_hash.into())?; - let previous_named_keys = previous_contract.take_named_keys(); - named_keys.append(previous_named_keys); - } + let insert_contract_result = + package.insert_entity_version(protocol_version.value().major, entity_hash.into()); - let (main_purse, associated_keys, action_thresholds) = match package.current_contract_hash() - { - Some(previous_contract_hash) => { - let previous_contract: AddressableEntity = - self.context.read_gs_typed(&previous_contract_hash.into())?; - let previous_named_keys = previous_contract.named_keys().clone(); - named_keys.append(previous_named_keys); - ( - previous_contract.main_purse(), - previous_contract.associated_keys().clone(), - previous_contract.action_thresholds().clone(), - ) - } - None => ( - self.create_purse()?, - AssociatedKeys::default(), - ActionThresholds::default(), - ), + let byte_code = { + let module_bytes = self.get_module_from_entry_points(&entry_points)?; + ByteCode::new(ByteCodeKind::V1CasperWasm, module_bytes) }; + self.context.metered_write_gs_unsafe( + Key::ByteCode((ByteCodeKind::V1CasperWasm, byte_code_hash)), + byte_code, + )?; + + let entity_key = Key::AddressableEntity((PackageKindTag::SmartContract, entity_hash)); + let entity = AddressableEntity::new( package_hash, - contract_wasm_hash.into(), + byte_code_hash.into(), named_keys, entry_points, protocol_version, @@ -1745,43 +1790,24 @@ where action_thresholds, ); - let insert_contract_result = package.insert_contract_version(major, entity_hash.into()); - - self.context - .metered_write_gs_unsafe(Key::Hash(contract_wasm_hash), contract_wasm)?; - self.context - .metered_write_gs_unsafe(Key::Hash(entity_hash), entity)?; + self.context.metered_write_gs_unsafe(entity_key, entity)?; self.context .metered_write_gs_unsafe(package_hash, package)?; - // return contract key to caller + // set return values to buffer { - let key_bytes = match entity_hash.to_bytes() { + let hash_bytes = match entity_hash.to_bytes() { Ok(bytes) => bytes, Err(error) => return Ok(Err(error.into())), }; - // `output_size` must be >= actual length of serialized Key bytes - if output_size < key_bytes.len() { - return Ok(Err(ApiError::BufferTooSmall)); - } - - // Set serialized Key bytes into the output buffer - if let Err(error) = self.try_get_memory()?.set(output_ptr, &key_bytes) { + // Set serialized hash bytes into the output buffer + if let Err(error) = self.try_get_memory()?.set(output_ptr, &hash_bytes) { return Err(Error::Interpreter(error.into())); } - // SAFETY: For all practical purposes following conversion is assumed to be safe - let bytes_size: u32 = key_bytes - .len() - .try_into() - .expect("Serialized value should fit within the limit"); - let size_bytes = bytes_size.to_le_bytes(); // Wasm is little-endian - if let Err(error) = self.try_get_memory()?.set(bytes_written_ptr, &size_bytes) { - return Err(Error::Interpreter(error.into())); - } - - let version_value: u32 = insert_contract_result.contract_version(); + // Set version into VM shared memory + let version_value: u32 = insert_contract_result.entity_version(); let version_bytes = version_value.to_le_bytes(); if let Err(error) = self.try_get_memory()?.set(version_ptr, &version_bytes) { return Err(Error::Interpreter(error.into())); @@ -1791,10 +1817,65 @@ where Ok(Ok(())) } + fn new_version_entity_parts( + &mut self, + package: &Package, + ) -> Result<(URef, NamedKeys, ActionThresholds, AssociatedKeys), Error> { + if let Some(previous_entity_key) = package.previous_entity_key() { + let (mut previous_entity, requires_purse_creation) = + self.context.get_contract_entity(previous_entity_key)?; + + let action_thresholds = previous_entity.action_thresholds().clone(); + + let associated_keys = previous_entity.associated_keys().clone(); + + if !previous_entity.can_upgrade_with(self.context.authorization_keys()) { + // Check if the calling entity must be grandfathered into the new + // addressable entity format + let account_hash = self.context.get_caller(); + + if self.context.validate_uref(&package.access_key()).is_ok() + && !associated_keys.contains_key(&account_hash) + { + previous_entity.add_associated_key( + account_hash, + *action_thresholds.upgrade_management(), + )?; + } else { + return Err(Error::UpgradeAuthorizationFailure); + } + } + + let main_purse = if !requires_purse_creation { + self.create_purse()? + } else { + previous_entity.main_purse() + }; + + let associated_keys = previous_entity.associated_keys().clone(); + + let previous_named_keys = previous_entity.take_named_keys(); + + return Ok(( + main_purse, + previous_named_keys, + action_thresholds, + associated_keys, + )); + } + + Ok(( + self.create_purse()?, + NamedKeys::new(), + ActionThresholds::default(), + AssociatedKeys::new(self.context.get_caller(), Weight::new(1)), + )) + } + fn disable_contract_version( &mut self, - contract_package_hash: ContractPackageHash, - contract_hash: ContractHash, + contract_package_hash: PackageHash, + contract_hash: AddressableEntityHash, ) -> Result, Error> { let contract_package_key = contract_package_hash.into(); self.context.validate_key(&contract_package_key)?; @@ -1803,10 +1884,10 @@ where self.context.get_validated_package(contract_package_hash)?; if contract_package.is_locked() { - return Err(Error::LockedContract(contract_package_hash)); + return Err(Error::LockedEntity(contract_package_hash)); } - if let Err(err) = contract_package.disable_contract_version(contract_hash) { + if let Err(err) = contract_package.disable_entity_version(contract_hash) { return Ok(Err(err.into())); } @@ -1818,8 +1899,8 @@ where fn enable_contract_version( &mut self, - contract_package_hash: ContractPackageHash, - contract_hash: ContractHash, + contract_package_hash: PackageHash, + contract_hash: AddressableEntityHash, ) -> Result, Error> { let contract_package_key = contract_package_hash.into(); self.context.validate_key(&contract_package_key)?; @@ -1828,7 +1909,7 @@ where self.context.get_validated_package(contract_package_hash)?; if contract_package.is_locked() { - return Err(Error::LockedContract(contract_package_hash)); + return Err(Error::LockedEntity(contract_package_hash)); } if let Err(err) = contract_package.enable_version(contract_hash) { @@ -1883,7 +1964,7 @@ where amount: U512, id: Option, ) -> Result<(), Error> { - if self.context.get_entity_address() != self.context.get_system_contract(MINT)? { + if self.context.get_entity_key() != self.context.get_system_entity_key(MINT)? { return Err(Error::InvalidContext); } @@ -1913,7 +1994,7 @@ where return Err(Error::InvalidContext); } - if self.context.get_entity_address() != self.context.get_system_contract(AUCTION)? { + if self.context.get_entity_key() != self.context.get_system_entity_key(AUCTION)? { return Err(Error::InvalidContext); } @@ -2130,28 +2211,28 @@ where /// Looks up the public mint contract key in the context's protocol data. /// /// Returned URef is already attenuated depending on the calling account. - fn get_mint_contract(&self) -> Result { + fn get_mint_contract(&self) -> Result { self.context.get_system_contract(MINT) } /// Looks up the public handle payment contract key in the context's protocol data. /// /// Returned URef is already attenuated depending on the calling account. - fn get_handle_payment_contract(&self) -> Result { + fn get_handle_payment_contract(&self) -> Result { self.context.get_system_contract(HANDLE_PAYMENT) } /// Looks up the public standard payment contract key in the context's protocol data. /// /// Returned URef is already attenuated depending on the calling account. - fn get_standard_payment_contract(&self) -> Result { + fn get_standard_payment_contract(&self) -> Result { self.context.get_system_contract(STANDARD_PAYMENT) } /// Looks up the public auction contract key in the context's protocol data. /// /// Returned URef is already attenuated depending on the calling account. - fn get_auction_contract(&self) -> Result { + fn get_auction_contract(&self) -> Result { self.context.get_system_contract(AUCTION) } @@ -2159,7 +2240,7 @@ where /// contract key fn mint_read_base_round_reward( &mut self, - mint_contract_hash: ContractHash, + mint_contract_hash: AddressableEntityHash, ) -> Result { let gas_counter = self.gas_counter(); let call_result = self.call_contract( @@ -2175,7 +2256,11 @@ where /// Calls the `mint` method on the mint contract at the given mint /// contract key - fn mint_mint(&mut self, mint_contract_hash: ContractHash, amount: U512) -> Result { + fn mint_mint( + &mut self, + mint_contract_hash: AddressableEntityHash, + amount: U512, + ) -> Result { let gas_counter = self.gas_counter(); let runtime_args = { let mut runtime_args = RuntimeArgs::new(); @@ -2193,7 +2278,7 @@ where /// contract key fn mint_reduce_total_supply( &mut self, - mint_contract_hash: ContractHash, + mint_contract_hash: AddressableEntityHash, amount: U512, ) -> Result<(), Error> { let gas_counter = self.gas_counter(); @@ -2215,7 +2300,7 @@ where /// Calls the "create" method on the mint contract at the given mint /// contract key - fn mint_create(&mut self, mint_contract_hash: ContractHash) -> Result { + fn mint_create(&mut self, mint_contract_hash: AddressableEntityHash) -> Result { let result = self.call_contract(mint_contract_hash, mint::METHOD_CREATE, RuntimeArgs::new()); let purse = result?.into_t()?; @@ -2231,7 +2316,7 @@ where /// contract key fn mint_transfer( &mut self, - mint_contract_hash: ContractHash, + mint_contract_hash: AddressableEntityHash, to: Option, source: URef, target: URef, @@ -2310,17 +2395,16 @@ where match result? { Ok(()) => { let protocol_version = self.context.protocol_version(); - let contract_wasm_hash = *ACCOUNT_WASM_HASH; - let contract_hash = ContractHash::new(self.context.new_hash_address()?); - let contract_package_hash = - ContractPackageHash::new(self.context.new_hash_address()?); + let contract_wasm_hash = *ACCOUNT_BYTE_CODE_HASH; + let entity_hash = AddressableEntityHash::new(self.context.new_hash_address()?); + let package_hash = PackageHash::new(self.context.new_hash_address()?); let main_purse = target_purse; let associated_keys = AssociatedKeys::new(target, Weight::new(1)); let named_keys = NamedKeys::new(); let entry_points = EntryPoints::new(); - let contract = AddressableEntity::new( - contract_package_hash, + let entity = AddressableEntity::new( + package_hash, contract_wasm_hash, named_keys, entry_points, @@ -2331,35 +2415,31 @@ where ); let access_key = self.context.new_unit_uref()?; - let contract_package = { - let mut contract_package = Package::new( + let package = { + let mut package = Package::new( access_key, - ContractVersions::default(), + EntityVersions::default(), BTreeSet::default(), Groups::default(), - ContractPackageStatus::Locked, - ContractPackageKind::Account(target), + PackageStatus::Locked, + PackageKind::Account(target), ); - contract_package - .insert_contract_version(protocol_version.value().major, contract_hash); - contract_package + package.insert_entity_version(protocol_version.value().major, entity_hash); + package }; - let contract_key: Key = contract_hash.into(); + let entity_key: Key = + Key::addressable_entity_key(package.get_package_kind().tag(), entity_hash); - self.context.metered_write_gs_unsafe( - contract_key, - StoredValue::AddressableEntity(contract), - )?; + self.context + .metered_write_gs_unsafe(entity_key, StoredValue::AddressableEntity(entity))?; - let contract_package_key: Key = contract_package_hash.into(); + let contract_package_key: Key = package_hash.into(); - self.context.metered_write_gs_unsafe( - contract_package_key, - StoredValue::ContractPackage(contract_package), - )?; + self.context + .metered_write_gs_unsafe(contract_package_key, StoredValue::Package(package))?; - let contract_by_account = CLValue::from_t(contract_key)?; + let contract_by_account = CLValue::from_t(entity_key)?; let target_key = Key::Account(target); @@ -2427,19 +2507,21 @@ where } Some(StoredValue::CLValue(account)) => { // Attenuate the target main purse - let contract_key = CLValue::into_t::(account)?; - let contract_hash = - if let Some(contract_hash) = contract_key.into_hash().map(ContractHash::new) { - contract_hash - } else { - return Err(Error::UnexpectedKeyVariant(contract_key)); - }; - let target_uref = if let Some(StoredValue::AddressableEntity(contract)) = - self.context.read_gs(&contract_hash.into())? + let entity_key = CLValue::into_t::(account)?; + let target_uref = if let Some(StoredValue::AddressableEntity(entity)) = + self.context.read_gs(&entity_key)? { - contract.main_purse_add_only() + entity.main_purse_add_only() } else { - return Err(Error::InvalidContract(contract_hash)); + let contract_hash = if let Some(entity_hash) = entity_key + .into_entity_addr() + .map(AddressableEntityHash::new) + { + entity_hash + } else { + return Err(Error::UnexpectedKeyVariant(entity_key)); + }; + return Err(Error::InvalidEntity(contract_hash)); }; if source.with_access_rights(AccessRights::ADD) == target_uref { @@ -2598,14 +2680,14 @@ where dest_ptr: u32, _dest_size: u32, ) -> Result, Trap> { - let contract_hash: ContractHash = match SystemContractType::try_from(system_contract_index) - { - Ok(SystemContractType::Mint) => self.get_mint_contract()?, - Ok(SystemContractType::HandlePayment) => self.get_handle_payment_contract()?, - Ok(SystemContractType::StandardPayment) => self.get_standard_payment_contract()?, - Ok(SystemContractType::Auction) => self.get_auction_contract()?, - Err(error) => return Ok(Err(error)), - }; + let contract_hash: AddressableEntityHash = + match SystemEntityType::try_from(system_contract_index) { + Ok(SystemEntityType::Mint) => self.get_mint_contract()?, + Ok(SystemEntityType::HandlePayment) => self.get_handle_payment_contract()?, + Ok(SystemEntityType::StandardPayment) => self.get_standard_payment_contract()?, + Ok(SystemEntityType::Auction) => self.get_auction_contract()?, + Err(error) => return Ok(Err(error)), + }; match self.try_get_memory()?.set(dest_ptr, contract_hash.as_ref()) { Ok(_) => Ok(Ok(())), @@ -2785,7 +2867,7 @@ where /// Remove a user group from access to a contract fn remove_contract_user_group( &mut self, - package_key: ContractPackageHash, + package_key: PackageHash, label: Group, ) -> Result, Error> { let mut package: Package = self.context.get_validated_package(package_key)?; @@ -2800,11 +2882,12 @@ where // Remove group if it is not referenced by at least one entry_point in active versions. let versions = package.versions(); - for contract_hash in versions.contract_hashes() { + for entity_hash in versions.contract_hashes() { let entry_points = { - let contract: AddressableEntity = - self.context.read_gs_typed(&Key::from(*contract_hash))?; - contract.entry_points().clone().take_entry_points() + let entity: AddressableEntity = self.context.read_gs_typed( + &Key::addressable_entity_key(package.get_package_kind().tag(), *entity_hash), + )?; + entity.entry_points().clone().take_entry_points() }; for entry_point in entry_points { match entry_point.access() { @@ -2903,8 +2986,7 @@ where urefs_ptr: u32, urefs_size: u32, ) -> Result, Error> { - let contract_package_hash: ContractPackageHash = - self.t_from_mem(package_ptr, package_size)?; + let contract_package_hash: PackageHash = self.t_from_mem(package_ptr, package_size)?; let label: String = self.t_from_mem(label_ptr, label_size)?; let urefs: BTreeSet = self.t_from_mem(urefs_ptr, urefs_size)?; @@ -3110,10 +3192,10 @@ where // This case can happen during genesis where we're setting up purses for accounts. Ok(account_hash == &PublicKey::System.to_account_hash()) } - CallStackElement::StoredSession { contract_hash, .. } - | CallStackElement::StoredContract { contract_hash, .. } => { - Ok(self.context.is_system_contract(contract_hash)?) - } + CallStackElement::AddressableEntity { + entity_hash: contract_hash, + .. + } => Ok(self.context.is_system_addressable_entity(contract_hash)?), } } @@ -3169,50 +3251,67 @@ where pub(crate) fn migrate_contract_and_contract_package( &mut self, - contract_hash: ContractHash, - ) -> Result<(), Error> { - let contract_key: Key = contract_hash.into(); - let maybe_legacy_contract = self.context.read_gs(&contract_key)?; + contract_hash: AddressableEntityHash, + ) -> Result { + let maybe_legacy_contract = self.context.read_gs(&Key::Hash(contract_hash.value()))?; match maybe_legacy_contract { Some(StoredValue::Contract(contract)) => { let contract_package_key = Key::Hash(contract.contract_package_hash().value()); - let mut legacy_contract_package: Package = + let legacy_contract_package: ContractPackage = self.context.read_gs_typed(&contract_package_key)?; - // Update the contract package from Legacy to Wasm - legacy_contract_package.update_package_kind(ContractPackageKind::Wasm); - legacy_contract_package.insert_contract_version( - self.context.protocol_version().value().major, - contract_hash, - ); - if legacy_contract_package.is_legacy() { - return Err(Error::InvalidContractPackageKind( - legacy_contract_package.get_package_kind(), - )); - } + let package: Package = legacy_contract_package.into(); + + let access_uref = &package.access_key(); + + let package_key = Key::Package(contract.contract_package_hash().value()); + + let package_kind = package.get_package_kind(); self.context - .metered_write_gs(contract_package_key, legacy_contract_package)?; + .metered_write_gs_unsafe(package_key, StoredValue::Package(package))?; let entity_main_purse = self.create_purse()?; + let associated_keys = if self.context.validate_uref(access_uref).is_ok() { + AssociatedKeys::new(self.context.get_caller(), Weight::new(1)) + } else { + AssociatedKeys::default() + }; + let updated_entity = AddressableEntity::new( - contract.contract_package_hash(), - contract.contract_wasm_hash(), + PackageHash::new(contract.contract_package_hash().value()), + ByteCodeHash::new(contract.contract_wasm_hash().value()), contract.named_keys().clone(), contract.entry_points().clone(), self.context.protocol_version(), entity_main_purse, - AssociatedKeys::default(), + associated_keys, ActionThresholds::default(), ); - self.context.metered_write_gs(contract_key, updated_entity) + let previous_wasm = self.context.read_gs_typed::(&Key::Hash( + contract.contract_wasm_hash().value(), + ))?; + + let byte_code_key = + Key::byte_code_key(ByteCodeKind::V1CasperWasm, updated_entity.byte_code_addr()); + + let byte_code: ByteCode = previous_wasm.into(); + + self.context + .metered_write_gs_unsafe(byte_code_key, StoredValue::ByteCode(byte_code))?; + + let entity_key = + Key::AddressableEntity((package_kind.tag(), contract_hash.value())); + + self.context + .metered_write_gs_unsafe(entity_key, updated_entity.clone())?; + Ok(updated_entity) } - Some(StoredValue::AddressableEntity(_)) => Ok(()), Some(_) => Err(Error::UnexpectedStoredValueVariant), - None => Err(Error::InvalidContract(contract_hash)), + None => Err(Error::InvalidEntity(contract_hash)), } } } diff --git a/execution_engine/src/runtime/stack.rs b/execution_engine/src/runtime/stack.rs index 87eeb098a7..7e37d8a080 100644 --- a/execution_engine/src/runtime/stack.rs +++ b/execution_engine/src/runtime/stack.rs @@ -11,7 +11,7 @@ use casper_types::{account::AccountHash, system::CallStackElement, PublicKey}; pub type RuntimeStackFrame = CallStackElement; /// The runtime stack. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct RuntimeStack { frames: Vec, max_height: usize, diff --git a/execution_engine/src/runtime/standard_payment_internal.rs b/execution_engine/src/runtime/standard_payment_internal.rs index d28a432d3c..a7a3f3dcfe 100644 --- a/execution_engine/src/runtime/standard_payment_internal.rs +++ b/execution_engine/src/runtime/standard_payment_internal.rs @@ -5,14 +5,7 @@ use casper_types::{ ApiError, Key, RuntimeArgs, StoredValue, TransferredTo, URef, U512, }; -use crate::{ - execution, - runtime::Runtime, - system::standard_payment::{ - account_provider::AccountProvider, handle_payment_provider::HandlePaymentProvider, - mint_provider::MintProvider, StandardPayment, - }, -}; +use crate::{execution, runtime::Runtime}; pub(crate) const METHOD_GET_PAYMENT_PURSE: &str = "get_payment_purse"; diff --git a/execution_engine/src/runtime_context/mod.rs b/execution_engine/src/runtime_context/mod.rs index a222bf00df..bce5cb50c7 100644 --- a/execution_engine/src/runtime_context/mod.rs +++ b/execution_engine/src/runtime_context/mod.rs @@ -23,12 +23,12 @@ use casper_types::{ }, bytesrepr::ToBytes, execution::Effects, - package::ContractPackageKind, + package::{PackageKind, PackageKindTag}, system::auction::EraInfo, - AccessRights, AddressableEntity, BlockTime, CLType, CLValue, ContextAccessRights, ContractHash, - ContractPackageHash, DeployHash, EntryPointType, Gas, GrantedAccess, Key, KeyTag, Package, - Phase, ProtocolVersion, PublicKey, RuntimeArgs, StoredValue, Transfer, TransferAddr, URef, - URefAddr, DICTIONARY_ITEM_KEY_MAX_LENGTH, KEY_HASH_LENGTH, U512, + AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, CLType, CLValue, + ContextAccessRights, DeployHash, EntryPointType, Gas, GrantedAccess, Key, KeyTag, Package, + PackageHash, Phase, ProtocolVersion, PublicKey, RuntimeArgs, StoredValue, Transfer, + TransferAddr, URef, URefAddr, DICTIONARY_ITEM_KEY_MAX_LENGTH, KEY_HASH_LENGTH, U512, }; use crate::{ @@ -66,8 +66,8 @@ pub struct RuntimeContext<'a, R> { // Original account/contract for read only tasks taken before execution entity: &'a AddressableEntity, // Key pointing to the entity we are currently running - entity_address: ContractHash, - package_kind: ContractPackageKind, + entity_key: Key, + package_kind: PackageKind, account_hash: AccountHash, } @@ -83,10 +83,10 @@ where pub fn new( named_keys: &'a mut NamedKeys, entity: &'a AddressableEntity, - entity_address: ContractHash, + entity_key: Key, authorization_keys: BTreeSet, access_rights: ContextAccessRights, - package_kind: ContractPackageKind, + package_kind: PackageKind, account_hash: AccountHash, address_generator: Rc>, tracking_copy: Rc>>, @@ -109,7 +109,7 @@ where access_rights, args: runtime_args, entity, - entity_address, + entity_key, authorization_keys, account_hash, blocktime, @@ -130,7 +130,7 @@ where #[allow(clippy::too_many_arguments)] pub fn new_from_self( &self, - entity_address: ContractHash, + entity_key: Key, entry_point_type: EntryPointType, named_keys: &'a mut NamedKeys, access_rights: ContextAccessRights, @@ -139,7 +139,7 @@ where let entity = self.entity; let authorization_keys = self.authorization_keys.clone(); let account_hash = self.account_hash; - let package_kind = self.package_kind.clone(); + let package_kind = self.package_kind; let address_generator = self.address_generator.clone(); let tracking_copy = self.state(); @@ -163,7 +163,7 @@ where access_rights, args: runtime_args, entity, - entity_address, + entity_key, authorization_keys, account_hash, blocktime, @@ -211,8 +211,8 @@ where } /// Returns the package kind associated with the current context. - pub fn get_package_kind(&self) -> ContractPackageKind { - self.package_kind.clone() + pub fn get_package_kind(&self) -> PackageKind { + self.package_kind } /// Returns whether the current context is of the system addressable entity. @@ -224,7 +224,7 @@ where } /// Helper function to avoid duplication in `remove_uref`. - fn remove_key_from_contract( + fn remove_key_from_entity( &mut self, key: Key, mut contract: AddressableEntity, @@ -243,10 +243,10 @@ where /// also persistable map (one that is found in the /// TrackingCopy/GlobalState). pub fn remove_key(&mut self, name: &str) -> Result<(), Error> { - let contract_hash = self.get_entity_address(); - let contract: AddressableEntity = self.read_gs_typed(&Key::from(contract_hash))?; + let entity_key = self.get_entity_key(); + let contract: AddressableEntity = self.read_gs_typed(&entity_key)?; self.named_keys.remove(name); - self.remove_key_from_contract(Key::from(contract_hash), contract, name) + self.remove_key_from_entity(entity_key, contract, name) } /// Returns the block time. @@ -308,12 +308,9 @@ where self.gas_counter = new_gas_counter; } - /// Returns the base key. - /// - /// This could be either a [`Key::Account`] or a [`Key::Hash`] depending on the entry point - /// type. - pub fn get_entity_address(&self) -> ContractHash { - self.entity_address + /// Returns the base key of [`Key::AddressableEntity`] + pub fn get_entity_key(&self) -> Key { + self.entity_key } /// Returns the initiater of the call chain. @@ -369,7 +366,7 @@ where // the element stored under `base_key`) is allowed to add new named keys to itself. let named_key_value = StoredValue::CLValue(CLValue::from_t((name.clone(), key))?); self.validate_value(&named_key_value)?; - self.metered_add_gs_unsafe(Key::from(self.get_entity_address()), named_key_value)?; + self.metered_add_gs_unsafe(self.get_entity_key(), named_key_value)?; self.insert_named_key(name, key); Ok(()) } @@ -617,14 +614,14 @@ where match value { StoredValue::CLValue(cl_value) => self.validate_cl_value(cl_value), StoredValue::Account(_) => Ok(()), - StoredValue::ContractWasm(_) => Ok(()), + StoredValue::ByteCode(_) => Ok(()), StoredValue::Contract(_) => Ok(()), StoredValue::AddressableEntity(contract_header) => contract_header .named_keys() .keys() .try_for_each(|key| self.validate_key(key)), // TODO: anything to validate here? - StoredValue::ContractPackage(_) => Ok(()), + StoredValue::Package(_) => Ok(()), StoredValue::Transfer(_) => Ok(()), StoredValue::DeployInfo(_) => Ok(()), StoredValue::EraInfo(_) => Ok(()), @@ -632,6 +629,8 @@ where StoredValue::BidKind(_) => Ok(()), StoredValue::Withdraw(_) => Ok(()), StoredValue::Unbonding(_) => Ok(()), + StoredValue::ContractPackage(_) => Ok(()), + StoredValue::ContractWasm(_) => Ok(()), } } @@ -710,16 +709,25 @@ where | Key::Unbond(_) | Key::ChainspecRegistry | Key::ChecksumRegistry - | Key::BidAddr(_) => true, + | Key::BidAddr(_) + | Key::Package(_) + | Key::AddressableEntity(_) + | Key::ByteCode(_) => true, } } /// Tests whether addition to `key` is valid. pub fn is_addable(&self, key: &Key) -> bool { match key { - Key::Hash(hash) => &self.get_entity_address().value() == hash, // ??? + Key::AddressableEntity((_, entity_addr)) => { + match self.get_entity_key().into_entity_hash() { + Some(entity_hash) => entity_hash == AddressableEntityHash::new(*entity_addr), + None => false, + } + } Key::URef(uref) => uref.is_addable(), - Key::Account(_) + Key::Hash(_) + | Key::Account(_) | Key::Transfer(_) | Key::DeployInfo(_) | Key::EraInfo(_) @@ -732,7 +740,9 @@ where | Key::Unbond(_) | Key::ChainspecRegistry | Key::ChecksumRegistry - | Key::BidAddr(_) => false, + | Key::BidAddr(_) + | Key::Package(_) + | Key::ByteCode(_) => false, } } @@ -754,7 +764,10 @@ where | Key::Unbond(_) | Key::ChainspecRegistry | Key::ChecksumRegistry - | Key::BidAddr(_) => false, + | Key::BidAddr(_) + | Key::Package(_) + | Key::AddressableEntity(_) + | Key::ByteCode(_) => false, } } @@ -767,6 +780,7 @@ where let prev = self.gas_counter(); let gas_limit = self.gas_limit(); let is_system = self.package_kind.is_system(); + // gas charge overflow protection match prev.checked_add(gas.cost(is_system)) { None => { @@ -774,6 +788,7 @@ where Err(Error::GasLimit) } Some(val) if val > gas_limit => { + println!("Val/limit {}/{}", val, gas_limit); self.set_gas_counter(gas_limit); Err(Error::GasLimit) } @@ -784,8 +799,11 @@ where } } - /// Checks if we are calling a system contract. - pub(crate) fn is_system_contract(&self, contract_hash: &ContractHash) -> Result { + /// Checks if we are calling a system addressable entity. + pub(crate) fn is_system_addressable_entity( + &self, + contract_hash: &AddressableEntityHash, + ) -> Result { Ok(self .system_contract_registry()? .has_contract_hash(contract_hash)) @@ -793,10 +811,12 @@ where /// Charges gas for specified amount of bytes used. fn charge_gas_storage(&mut self, bytes_count: usize) -> Result<(), Error> { - let contract_hash = self.get_entity_address(); - if self.is_system_contract(&contract_hash)? { - // Don't charge storage used while executing a system contract. - return Ok(()); + if let Some(base_key) = self.get_entity_key().into_entity_addr() { + let entity_hash = AddressableEntityHash::new(base_key); + if self.is_system_addressable_entity(&entity_hash)? { + // Don't charge storage used while executing a system contract. + return Ok(()); + } } let storage_costs = self.engine_config.wasm_config().storage_costs(); @@ -906,7 +926,12 @@ where account_hash: AccountHash, weight: Weight, ) -> Result<(), Error> { - let entity_key = self.get_entity_address_for_account_hash(self.account_hash)?; + 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)? + } + }; // Check permission to modify associated keys if !self.is_valid_context(entity_key) { @@ -915,11 +940,11 @@ where } // Converts an account's public key into a URef - let key = self.get_entity_address(); + let key = self.get_entity_key(); // Take an addressable entity out of the global state let entity = { - let mut entity: AddressableEntity = self.read_gs_typed(&Key::from(key))?; + let mut entity: AddressableEntity = self.read_gs_typed(&key)?; if entity.associated_keys().len() >= (self.engine_config.max_associated_keys() as usize) { @@ -956,11 +981,10 @@ where } // Converts an account's public key into a URef - // let key = Key::Account(self.contract().account_hash()); - let contract_hash = self.get_entity_address(); + let contract_hash = self.get_entity_key(); // Take an account out of the global state - let mut entity: AddressableEntity = self.read_gs_typed(&Key::from(contract_hash))?; + let mut entity: AddressableEntity = self.read_gs_typed(&contract_hash)?; // Exit early in case of error without updating global state entity @@ -994,10 +1018,10 @@ where } // Converts an account's public key into a URef - let key = self.get_entity_address(); + let key = self.get_entity_key(); // Take an account out of the global state - let mut entity: AddressableEntity = self.read_gs_typed(&Key::from(key))?; + let mut entity: AddressableEntity = self.read_gs_typed(&key)?; // Exit early in case of error without updating global state entity @@ -1025,17 +1049,22 @@ where action_type: ActionType, threshold: Weight, ) -> Result<(), Error> { - let entity_key = self.get_entity_address_for_account_hash(self.account_hash)?; + 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)? + } + }; // Check permission to modify associated keys if !self.is_valid_context(entity_key) { // Exit early with error to avoid mutations return Err(SetThresholdFailure::PermissionDeniedError.into()); } - let key = self.get_entity_address(); + let key = self.get_entity_key(); // Take an addressable entity out of the global state - let mut entity: AddressableEntity = self.read_gs_typed(&Key::from(key))?; + let mut entity: AddressableEntity = self.read_gs_typed(&key)?; // Exit early in case of error without updating global state if self.is_authorized_by_admin() { @@ -1064,11 +1093,9 @@ where pub(crate) fn get_entity_address_for_account_hash( &mut self, account_hash: AccountHash, - ) -> Result { + ) -> Result { let cl_value = self.read_gs_typed::(&Key::Account(account_hash))?; - let key = CLValue::into_t::(cl_value).map_err(Error::CLValue)?; - key.into_contract_hash() - .ok_or(Error::UnexpectedKeyVariant(key)) + CLValue::into_t::(cl_value).map_err(Error::CLValue) } pub(crate) fn read_addressable_entity_by_account_hash( @@ -1092,8 +1119,8 @@ where } /// Checks if the account context is valid. - fn is_valid_context(&self, entity_address: ContractHash) -> bool { - self.get_entity_address() == entity_address + fn is_valid_context(&self, entity_key: Key) -> bool { + self.get_entity_key() == entity_key } /// Gets main purse id @@ -1110,7 +1137,7 @@ where /// Gets given contract package with its access_key validated against current context. pub(crate) fn get_validated_package( &mut self, - package_hash: ContractPackageHash, + package_hash: PackageHash, ) -> Result { let package_hash_key = Key::from(package_hash); self.validate_key(&package_hash_key)?; @@ -1121,6 +1148,29 @@ where Ok(contract_package) } + pub(crate) fn get_package(&mut self, package_hash: PackageHash) -> Result { + self.tracking_copy + .borrow_mut() + .get_package(package_hash) + .map_err(Into::into) + } + + pub(crate) fn get_contract_entity( + &mut self, + entity_key: Key, + ) -> Result<(AddressableEntity, bool), Error> { + let entity_hash = if let Some(entity_hash) = entity_key.into_entity_hash() { + entity_hash + } else { + return Err(Error::UnexpectedKeyVariant(entity_key)); + }; + + self.tracking_copy + .borrow_mut() + .get_contract_entity(entity_hash) + .map_err(Into::into) + } + /// Gets a dictionary item key from a dictionary referenced by a `uref`. pub(crate) fn dictionary_get( &mut self, @@ -1192,7 +1242,7 @@ where } /// Gets system contract by name. - pub(crate) fn get_system_contract(&self, name: &str) -> Result { + pub(crate) fn get_system_contract(&self, name: &str) -> Result { let registry = self.system_contract_registry()?; let hash = registry.get(name).ok_or_else(|| { error!("Missing system contract hash: {}", name); @@ -1201,6 +1251,14 @@ where Ok(*hash) } + pub(crate) fn get_system_entity_key(&self, name: &str) -> Result { + let system_entity_hash = self.get_system_contract(name)?; + Ok(Key::addressable_entity_key( + PackageKindTag::System, + system_entity_hash, + )) + } + /// Returns system contract registry by querying the global state. pub fn system_contract_registry(&self) -> Result { self.tracking_copy diff --git a/execution_engine/src/runtime_context/tests.rs b/execution_engine/src/runtime_context/tests.rs index 713d362e9b..660c2957e0 100644 --- a/execution_engine/src/runtime_context/tests.rs +++ b/execution_engine/src/runtime_context/tests.rs @@ -18,11 +18,11 @@ use casper_types::{ }, bytesrepr::ToBytes, execution::TransformKind, - package::ContractPackageKind, + package::{PackageKind, PackageKindTag}, system::{AUCTION, HANDLE_PAYMENT, MINT, STANDARD_PAYMENT}, - AccessRights, AddressableEntity, BlockTime, CLValue, ContextAccessRights, ContractHash, - ContractPackageHash, ContractWasmHash, DeployHash, EntryPointType, EntryPoints, Gas, Key, - Phase, ProtocolVersion, PublicKey, RuntimeArgs, SecretKey, StoredValue, URef, KEY_HASH_LENGTH, + AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, ByteCodeHash, CLValue, + ContextAccessRights, DeployHash, EntryPointType, EntryPoints, Gas, Key, PackageHash, Phase, + ProtocolVersion, PublicKey, RuntimeArgs, SecretKey, StoredValue, Tagged, URef, KEY_HASH_LENGTH, U256, U512, }; use tempfile::TempDir; @@ -46,17 +46,13 @@ fn test_engine_config() -> EngineConfig { fn new_tracking_copy( account_hash: AccountHash, - init_entity_key: ContractHash, + init_entity_key: Key, init_entity: AddressableEntity, ) -> (TrackingCopy, TempDir) { - let entity_key_cl_value = - CLValue::from_t(Key::from(init_entity_key)).expect("must convert to cl value"); + let entity_key_cl_value = CLValue::from_t(init_entity_key).expect("must convert to cl value"); let (global_state, state_root_hash, tempdir) = state::make_temporary_global_state([ - ( - Key::from(init_entity_key), - StoredValue::AddressableEntity(init_entity), - ), + (init_entity_key, StoredValue::AddressableEntity(init_entity)), ( Key::Account(account_hash), StoredValue::CLValue(entity_key_cl_value), @@ -73,24 +69,40 @@ fn new_tracking_copy( fn new_addressable_entity_with_purse( account_hash: AccountHash, + entity_hash: AddressableEntityHash, + package_kind: PackageKind, purse: [u8; 32], named_keys: NamedKeys, -) -> AddressableEntity { +) -> (Key, Key, AddressableEntity) { let associated_keys = AssociatedKeys::new(account_hash, Weight::new(1)); - AddressableEntity::new( - ContractPackageHash::default(), - ContractWasmHash::default(), + let entity = AddressableEntity::new( + PackageHash::default(), + ByteCodeHash::default(), named_keys, EntryPoints::new_with_default_entry_point(), ProtocolVersion::V1_0_0, URef::new(purse, AccessRights::READ_ADD_WRITE), associated_keys, Default::default(), - ) + ); + let account_key = Key::Account(account_hash); + let contract_key = Key::addressable_entity_key(package_kind.tag(), entity_hash); + + (account_key, contract_key, entity) } -fn new_addressable_entity(account_hash: AccountHash, named_keys: NamedKeys) -> AddressableEntity { - new_addressable_entity_with_purse(account_hash, [0; 32], named_keys) +fn new_addressable_entity( + account_hash: AccountHash, + entity_hash: AddressableEntityHash, + named_keys: NamedKeys, +) -> (Key, Key, AddressableEntity) { + new_addressable_entity_with_purse( + account_hash, + entity_hash, + PackageKind::Account(account_hash), + [0; 32], + named_keys, + ) } // create random account key. @@ -101,10 +113,10 @@ fn random_account_key(entropy_source: &mut G) -> Key { } // create random contract key. -fn random_contract_key(entropy_source: &mut G) -> ContractHash { - let mut key = [0u8; 32]; - entropy_source.fill_bytes(&mut key); - ContractHash::new(key) +fn random_contract_key(entropy_source: &mut G) -> Key { + let mut key_hash = [0u8; 32]; + entropy_source.fill_bytes(&mut key_hash); + Key::AddressableEntity((PackageKindTag::SmartContract, key_hash)) } // Create URef Key. @@ -122,7 +134,7 @@ fn random_hash(entropy_source: &mut G) -> Key { fn new_runtime_context<'a>( addressable_entity: &'a AddressableEntity, account_hash: AccountHash, - entity_address: ContractHash, + entity_address: Key, named_keys: &'a mut NamedKeys, access_rights: ContextAccessRights, address_generator: AddressGenerator, @@ -132,10 +144,13 @@ fn new_runtime_context<'a>( let default_system_registry = { let mut registry = SystemContractRegistry::new(); - registry.insert(MINT.to_string(), ContractHash::default()); - registry.insert(HANDLE_PAYMENT.to_string(), ContractHash::default()); - registry.insert(STANDARD_PAYMENT.to_string(), ContractHash::default()); - registry.insert(AUCTION.to_string(), ContractHash::default()); + registry.insert(MINT.to_string(), AddressableEntityHash::default()); + registry.insert(HANDLE_PAYMENT.to_string(), AddressableEntityHash::default()); + registry.insert( + STANDARD_PAYMENT.to_string(), + AddressableEntityHash::default(), + ); + registry.insert(AUCTION.to_string(), AddressableEntityHash::default()); StoredValue::CLValue(CLValue::from_t(registry).unwrap()) }; @@ -147,7 +162,7 @@ fn new_runtime_context<'a>( entity_address, BTreeSet::from_iter(vec![account_hash]), access_rights, - ContractPackageKind::Account(account_hash), + PackageKind::Account(account_hash), account_hash, Rc::new(RefCell::new(address_generator)), Rc::new(RefCell::new(tracking_copy)), @@ -197,17 +212,20 @@ where .expect("should create secret key"); let public_key = PublicKey::from(&secret_key); let account_hash = public_key.to_account_hash(); - let contract_hash = ContractHash::new([10u8; 32]); + let entity_hash = AddressableEntityHash::new([10u8; 32]); let deploy_hash = [1u8; 32]; - let addressable_entity = - new_addressable_entity(public_key.to_account_hash(), named_keys.clone()); + let (_, entity_key, addressable_entity) = new_addressable_entity( + public_key.to_account_hash(), + entity_hash, + named_keys.clone(), + ); let address_generator = AddressGenerator::new(&deploy_hash, Phase::Session); - let access_rights = addressable_entity.extract_access_rights(contract_hash); + let access_rights = addressable_entity.extract_access_rights(entity_hash); let (runtime_context, _tempdir) = new_runtime_context( &addressable_entity, account_hash, - contract_hash, + entity_key, &mut named_keys, access_rights, address_generator, @@ -220,15 +238,13 @@ where fn last_transform_kind_on_addressable_entity( runtime_context: &RuntimeContext, ) -> TransformKind { - let key = runtime_context.entity_address; + let key = runtime_context.entity_key; runtime_context .effects() .transforms() .iter() .rev() - .find_map(|transform| { - (transform.key() == &Key::from(key)).then(|| transform.kind().clone()) - }) + .find_map(|transform| (transform.key() == &key).then(|| transform.kind().clone())) .unwrap() } @@ -280,11 +296,11 @@ 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 base_key = rc.get_entity_address(); + let base_key = rc.get_entity_key(); let entity = rc.get_entity(); let result = rc - .read_gs(&Key::from(base_key)) + .read_gs(&base_key) .expect("Account key is readable.") .expect("Account is found in GS."); @@ -337,9 +353,8 @@ fn contract_key_readable_valid() { // 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| { - rc.read_gs(&Key::from(contract_key)) - }); + let query_result = + build_runtime_context_and_execute(NamedKeys::new(), |mut rc| rc.read_gs(&contract_key)); assert!(query_result.is_ok()); } @@ -352,7 +367,7 @@ fn contract_key_not_writeable() { let contract_key = random_contract_key(&mut rng); let query_result = build_runtime_context_and_execute(NamedKeys::new(), |mut rc| { rc.metered_write_gs( - Key::from(contract_key), + contract_key, StoredValue::CLValue(CLValue::from_t(1_i32).unwrap()), ) }); @@ -364,8 +379,9 @@ fn contract_key_not_writeable() { fn contract_key_addable_valid() { // Contract key is addable if it is a "base" key - current context of the execution. let account_hash = AccountHash::new([0u8; 32]); - let entity_hash = ContractHash::new([1u8; 32]); - let entity = new_addressable_entity(account_hash, NamedKeys::new()); + let entity_hash = AddressableEntityHash::new([1u8; 32]); + let (_account_key, entity_key, entity) = + new_addressable_entity(account_hash, entity_hash, NamedKeys::new()); let authorization_keys = BTreeSet::from_iter(vec![account_hash]); let mut address_generator = AddressGenerator::new(&DEPLOY_HASH, PHASE); @@ -375,20 +391,23 @@ fn contract_key_addable_valid() { let mut access_rights = entity_as_stored_value .as_addressable_entity() .unwrap() - .extract_access_rights(ContractHash::default()); + .extract_access_rights(AddressableEntityHash::default()); - let (tracking_copy, _tempdir) = new_tracking_copy(account_hash, entity_hash, entity); + let (tracking_copy, _tempdir) = new_tracking_copy(account_hash, entity_key, entity); let tracking_copy = Rc::new(RefCell::new(tracking_copy)); tracking_copy .borrow_mut() - .write(Key::from(contract_key), entity_as_stored_value.clone()); + .write(contract_key, entity_as_stored_value.clone()); let default_system_registry = { let mut registry = SystemContractRegistry::new(); - registry.insert(MINT.to_string(), ContractHash::default()); - registry.insert(HANDLE_PAYMENT.to_string(), ContractHash::default()); - registry.insert(STANDARD_PAYMENT.to_string(), ContractHash::default()); - registry.insert(AUCTION.to_string(), ContractHash::default()); + registry.insert(MINT.to_string(), AddressableEntityHash::default()); + registry.insert(HANDLE_PAYMENT.to_string(), AddressableEntityHash::default()); + registry.insert( + STANDARD_PAYMENT.to_string(), + AddressableEntityHash::default(), + ); + registry.insert(AUCTION.to_string(), AddressableEntityHash::default()); StoredValue::CLValue(CLValue::from_t(registry).unwrap()) }; @@ -411,7 +430,7 @@ fn contract_key_addable_valid() { contract_key, authorization_keys, access_rights, - ContractPackageKind::Wasm, + PackageKind::SmartContract, account_hash, Rc::new(RefCell::new(address_generator)), Rc::clone(&tracking_copy), @@ -443,15 +462,16 @@ fn contract_key_addable_valid() { ActionThresholds::default(), )); - let read_contract = runtime_context.read_gs(&Key::from(contract_key)).unwrap(); + let read_contract = runtime_context.read_gs(&contract_key).unwrap(); assert_eq!(read_contract, Some(updated_contract)); } #[test] fn contract_key_addable_invalid() { let account_hash = AccountHash::new([0u8; 32]); - let contract_hash = ContractHash::new([1u8; 32]); - let entity = new_addressable_entity(account_hash, NamedKeys::new()); + let entity_hash = AddressableEntityHash::new([1u8; 32]); + let (_, entity_key, entity) = + new_addressable_entity(account_hash, entity_hash, NamedKeys::new()); let authorization_keys = BTreeSet::from_iter(vec![account_hash]); let mut address_generator = AddressGenerator::new(&DEPLOY_HASH, PHASE); let mut rng = rand::thread_rng(); @@ -462,13 +482,11 @@ fn contract_key_addable_invalid() { let mut access_rights = contract .as_addressable_entity() .unwrap() - .extract_access_rights(ContractHash::default()); - let (tracking_copy, _tempdir) = new_tracking_copy(account_hash, contract_hash, entity.clone()); + .extract_access_rights(AddressableEntityHash::default()); + let (tracking_copy, _tempdir) = new_tracking_copy(account_hash, entity_key, entity.clone()); let tracking_copy = Rc::new(RefCell::new(tracking_copy)); - tracking_copy - .borrow_mut() - .write(Key::from(contract_key), contract); + tracking_copy.borrow_mut().write(contract_key, contract); let uref_as_key = create_uref_as_key(&mut address_generator, AccessRights::WRITE); let uref_name = "NewURef".to_owned(); @@ -485,7 +503,7 @@ fn contract_key_addable_invalid() { other_contract_key, authorization_keys, access_rights, - ContractPackageKind::Account(account_hash), + PackageKind::Account(account_hash), account_hash, Rc::new(RefCell::new(address_generator)), Rc::clone(&tracking_copy), @@ -710,6 +728,16 @@ fn action_thresholds_management() { // making sure `account_dirty` mutated let named_keys = NamedKeys::new(); let query = |mut runtime_context: RuntimeContext| { + let entity_hash_by_account_hash = + CLValue::from_t(Key::Hash([2; 32])).expect("must convert to cl_value"); + + runtime_context + .metered_write_gs_unsafe( + Key::Account(AccountHash::new([42; 32])), + entity_hash_by_account_hash, + ) + .expect("must write key to gs"); + runtime_context .add_associated_key(AccountHash::new([42; 32]), Weight::new(254)) .expect("Unable to add associated key with maximum weight"); @@ -752,7 +780,21 @@ fn should_verify_ownership_before_adding_key() { let query = |mut runtime_context: RuntimeContext| { // Overwrites a `base_key` to a different one before doing any operation as // account `[0; 32]` - runtime_context.entity_address = ContractHash::new([1; 32]); + let entity_hash_by_account_hash = + CLValue::from_t(Key::Hash([2; 32])).expect("must convert to cl_value"); + + runtime_context + .metered_write_gs_unsafe( + Key::Account(AccountHash::new([84; 32])), + entity_hash_by_account_hash, + ) + .expect("must write key to gs"); + + runtime_context + .metered_write_gs_unsafe(Key::Hash([1; 32]), AddressableEntity::default()) + .expect("must write key to gs"); + + runtime_context.entity_key = Key::Hash([1; 32]); let err = runtime_context .add_associated_key(AccountHash::new([84; 32]), Weight::new(123)) @@ -776,7 +818,7 @@ fn should_verify_ownership_before_removing_a_key() { let query = |mut runtime_context: RuntimeContext| { // Overwrites a `base_key` to a different one before doing any operation as // account `[0; 32]` - runtime_context.entity_address = ContractHash::new([1; 32]); + runtime_context.entity_key = Key::Hash([1; 32]); let err = runtime_context .remove_associated_key(AccountHash::new([84; 32])) @@ -800,7 +842,7 @@ fn should_verify_ownership_before_setting_action_threshold() { let query = |mut runtime_context: RuntimeContext| { // Overwrites a `base_key` to a different one before doing any operation as // account `[0; 32]` - runtime_context.entity_address = ContractHash::new([1; 32]); + runtime_context.entity_key = Key::Hash([1; 32]); let err = runtime_context .set_action_threshold(ActionType::Deployment, Weight::new(123)) @@ -852,17 +894,18 @@ fn remove_uref_works() { let uref_name = "Foo".to_owned(); let uref_key = create_uref_as_key(&mut address_generator, AccessRights::READ); let account_hash = AccountHash::new([0u8; 32]); - let contract_hash = ContractHash::new([1u8; 32]); + let entity_hash = AddressableEntityHash::new([1u8; 32]); let mut named_keys = NamedKeys::new(); named_keys.insert(uref_name.clone(), uref_key); - let addressable_entity = new_addressable_entity(account_hash, named_keys.clone()); + let (_, entity_key, addressable_entity) = + new_addressable_entity(account_hash, entity_hash, named_keys.clone()); - let access_rights = addressable_entity.extract_access_rights(contract_hash); + let access_rights = addressable_entity.extract_access_rights(entity_hash); let (mut runtime_context, _tempdir) = new_runtime_context( &addressable_entity, account_hash, - contract_hash, + entity_key, &mut named_keys, access_rights, address_generator, @@ -882,12 +925,12 @@ fn remove_uref_works() { assert!(!entity.named_keys().contains(&uref_name)); // The next time the account is used, the access right is gone for the removed // named key. - let next_session_access_rights = entity.extract_access_rights(contract_hash); + let next_session_access_rights = entity.extract_access_rights(entity_hash); let address_generator = AddressGenerator::new(&deploy_hash, Phase::Session); let (runtime_context, _tempdir) = new_runtime_context( &entity, account_hash, - contract_hash, + entity_key, &mut named_keys, next_session_access_rights, address_generator, @@ -900,15 +943,20 @@ fn an_accounts_access_rights_should_include_main_purse() { let test_main_purse = URef::new([42u8; 32], AccessRights::READ_ADD_WRITE); // All other access rights except for main purse are extracted from named keys. let account_hash = AccountHash::new([0u8; 32]); - let contract_hash = ContractHash::new([1u8; 32]); + let entity_hash = AddressableEntityHash::new([1u8; 32]); let named_keys = NamedKeys::new(); - let entity = - new_addressable_entity_with_purse(account_hash, test_main_purse.addr(), named_keys); + let (_base_key, _, entity) = new_addressable_entity_with_purse( + account_hash, + entity_hash, + PackageKind::Account(account_hash), + test_main_purse.addr(), + named_keys, + ); assert!( entity.named_keys().is_empty(), "Named keys does not contain main purse" ); - let access_rights = entity.extract_access_rights(contract_hash); + let access_rights = entity.extract_access_rights(entity_hash); assert!( access_rights.has_access_rights_to_uref(&test_main_purse), "Main purse should be included in access rights" @@ -925,18 +973,23 @@ fn validate_valid_purse_of_an_account() { let deploy_hash = [1u8; 32]; let account_hash = AccountHash::new([0u8; 32]); - let contract_hash = ContractHash::new([1u8; 32]); - let entity = - new_addressable_entity_with_purse(account_hash, test_main_purse.addr(), named_keys.clone()); + let entity_hash = AddressableEntityHash::new([1u8; 32]); + let (base_key, _, entity) = new_addressable_entity_with_purse( + account_hash, + entity_hash, + PackageKind::Account(account_hash), + test_main_purse.addr(), + named_keys.clone(), + ); - let mut access_rights = entity.extract_access_rights(contract_hash); + let mut access_rights = entity.extract_access_rights(entity_hash); access_rights.extend(&[test_main_purse]); let address_generator = AddressGenerator::new(&deploy_hash, Phase::Session); let (runtime_context, _tempdir) = new_runtime_context( &entity, account_hash, - contract_hash, + base_key, &mut named_keys, access_rights, address_generator, diff --git a/execution_engine/src/system.rs b/execution_engine/src/system.rs index 9c6a40f3ba..62b7613d9c 100644 --- a/execution_engine/src/system.rs +++ b/execution_engine/src/system.rs @@ -1,4 +1,3 @@ pub(crate) mod auction; pub(crate) mod handle_payment; pub(crate) mod mint; -pub(crate) mod standard_payment; diff --git a/execution_engine/src/system/mint.rs b/execution_engine/src/system/mint.rs index 1d18baecf5..31cffe0e34 100644 --- a/execution_engine/src/system/mint.rs +++ b/execution_engine/src/system/mint.rs @@ -12,7 +12,7 @@ use casper_types::{ mint::{Error, ROUND_SEIGNIORAGE_RATE_KEY, TOTAL_SUPPLY_KEY}, CallStackElement, }, - Key, Phase, PublicKey, URef, U512, + Key, PublicKey, URef, U512, }; use crate::{ @@ -105,13 +105,6 @@ pub trait Mint: RuntimeProvider + StorageProvider + SystemProvider { amount: U512, id: Option, ) -> Result<(), Error> { - if let (Phase::Session, Some(CallStackElement::StoredSession { .. })) = - (self.get_phase(), self.get_immediate_caller()) - { - // stored session code is not allowed to call this method in the session phase - return Err(Error::InvalidContext); - } - if !self.allow_unrestricted_transfers() { let registry = match self.get_system_contract_registry() { Ok(registry) => registry, @@ -122,26 +115,14 @@ pub trait Mint: RuntimeProvider + StorageProvider + SystemProvider { }; let immediate_caller = self.get_immediate_caller().cloned(); match immediate_caller { - Some(CallStackElement::StoredSession { contract_hash, .. }) - | Some(CallStackElement::StoredContract { contract_hash, .. }) - if registry.has_contract_hash(&contract_hash) => - { + Some(CallStackElement::AddressableEntity { + entity_hash: contract_hash, + .. + }) if registry.has_contract_hash(&contract_hash) => { // System contract calling a mint is fine (i.e. standard payment calling mint's // transfer) } - Some(CallStackElement::StoredSession { - account_hash, - contract_package_hash: _, - contract_hash: _, - }) => { - if account_hash != PublicKey::System.to_account_hash() - && !self.is_administrator(&account_hash) - { - return Err(Error::DisabledUnrestrictedTransfers); - } - } - Some(CallStackElement::Session { account_hash: _ }) if self.is_called_from_standard_payment() => { @@ -206,9 +187,9 @@ pub trait Mint: RuntimeProvider + StorageProvider + SystemProvider { } } - Some(CallStackElement::StoredContract { - contract_package_hash: _, - contract_hash: _, + Some(CallStackElement::AddressableEntity { + package_hash: _, + entity_hash: _, }) => { if self.get_caller() != PublicKey::System.to_account_hash() && !self.is_administrator(&self.get_caller()) diff --git a/execution_engine/src/system/standard_payment.rs b/execution_engine/src/system/standard_payment.rs deleted file mode 100644 index b2e1b21cbe..0000000000 --- a/execution_engine/src/system/standard_payment.rs +++ /dev/null @@ -1,32 +0,0 @@ -pub(crate) mod account_provider; -pub(crate) mod handle_payment_provider; -pub(crate) mod mint_provider; - -use casper_types::{account::Account, ApiError, PublicKey, U512}; - -use self::{ - account_provider::AccountProvider, handle_payment_provider::HandlePaymentProvider, - mint_provider::MintProvider, -}; - -/// Implementation of a standard payment contract. -pub trait StandardPayment: AccountProvider + MintProvider + HandlePaymentProvider + Sized { - /// Pay `amount` to a payment purse. - fn pay(&mut self, amount: U512) -> Result<(), ApiError> { - let main_purse = self.get_main_purse()?; - let payment_purse = self.get_payment_purse()?; - - // NOTE: We can't simply pass a virtual system account with main purse assumed to be a - // payment purse - as some chains may have started with a system account with a main purse - // of different purpose. - let virtual_system_account = Account::new( - PublicKey::System.to_account_hash(), - Default::default(), - payment_purse, - Default::default(), - Default::default(), - ); - - self.transfer_purse_to_account(main_purse, &virtual_system_account, amount) - } -} diff --git a/execution_engine/src/system/standard_payment/account_provider.rs b/execution_engine/src/system/standard_payment/account_provider.rs deleted file mode 100644 index b83c3a4060..0000000000 --- a/execution_engine/src/system/standard_payment/account_provider.rs +++ /dev/null @@ -1,7 +0,0 @@ -use casper_types::{ApiError, URef}; - -/// Provider of an account related functionality. -pub trait AccountProvider { - /// Get currently executing account's purse. - fn get_main_purse(&mut self) -> Result; -} diff --git a/execution_engine/src/system/standard_payment/handle_payment_provider.rs b/execution_engine/src/system/standard_payment/handle_payment_provider.rs deleted file mode 100644 index 47f72fb967..0000000000 --- a/execution_engine/src/system/standard_payment/handle_payment_provider.rs +++ /dev/null @@ -1,7 +0,0 @@ -use casper_types::{ApiError, URef}; - -/// Provider of handle payment functionality. -pub trait HandlePaymentProvider { - /// Get payment purse for given deploy. - fn get_payment_purse(&mut self) -> Result; -} diff --git a/execution_engine/src/system/standard_payment/mint_provider.rs b/execution_engine/src/system/standard_payment/mint_provider.rs deleted file mode 100644 index a7a25e200c..0000000000 --- a/execution_engine/src/system/standard_payment/mint_provider.rs +++ /dev/null @@ -1,12 +0,0 @@ -use casper_types::{account::Account, ApiError, URef, U512}; - -/// Provides an access to mint. -pub trait MintProvider { - /// Transfer `amount` of tokens from `source` purse to a `target` purse. - fn transfer_purse_to_account( - &mut self, - source: URef, - target_account: &Account, - amount: U512, - ) -> Result<(), ApiError>; -} diff --git a/execution_engine/src/tracking_copy/byte_size.rs b/execution_engine/src/tracking_copy/byte_size.rs index 9cabd62aac..39890843af 100644 --- a/execution_engine/src/tracking_copy/byte_size.rs +++ b/execution_engine/src/tracking_copy/byte_size.rs @@ -1,6 +1,6 @@ use std::mem; -use casper_types::{account::Account, bytesrepr::ToBytes, ContractWasm, Key, StoredValue}; +use casper_types::{account::Account, bytesrepr::ToBytes, ByteCode, Key, StoredValue}; /// Returns byte size of the element - both heap size and stack size. pub trait ByteSize { @@ -26,13 +26,14 @@ impl ByteSize for StoredValue { StoredValue::CLValue(cl_value) => cl_value.serialized_length(), StoredValue::Account(account) => account.serialized_length(), StoredValue::ContractWasm(contract_wasm) => contract_wasm.serialized_length(), + StoredValue::ContractPackage(contract_package) => { + contract_package.serialized_length() + } StoredValue::Contract(contract) => contract.serialized_length(), StoredValue::AddressableEntity(contract_header) => { contract_header.serialized_length() } - StoredValue::ContractPackage(contract_package) => { - contract_package.serialized_length() - } + StoredValue::Package(package) => package.serialized_length(), StoredValue::DeployInfo(deploy_info) => deploy_info.serialized_length(), StoredValue::Transfer(transfer) => transfer.serialized_length(), StoredValue::EraInfo(era_info) => era_info.serialized_length(), @@ -40,6 +41,7 @@ impl ByteSize for StoredValue { StoredValue::BidKind(bid_kind) => bid_kind.serialized_length(), StoredValue::Withdraw(withdraw_purses) => withdraw_purses.serialized_length(), StoredValue::Unbonding(unbonding_purses) => unbonding_purses.serialized_length(), + StoredValue::ByteCode(byte_code) => byte_code.serialized_length(), } } } @@ -67,7 +69,7 @@ impl HeapSizeOf for Account { } // TODO: contract has other fields (re protocol version) that are not repr here...on purpose? -impl HeapSizeOf for ContractWasm { +impl HeapSizeOf for ByteCode { fn heap_size(&self) -> usize { self.bytes().len() } diff --git a/execution_engine/src/tracking_copy/ext.rs b/execution_engine/src/tracking_copy/ext.rs index 963498c50d..cd4a468719 100644 --- a/execution_engine/src/tracking_copy/ext.rs +++ b/execution_engine/src/tracking_copy/ext.rs @@ -1,16 +1,19 @@ -use std::{collections::BTreeSet, convert::TryInto}; +use std::{ + collections::BTreeSet, + convert::{TryFrom, TryInto}, +}; use casper_storage::global_state::{state::StateReader, trie::merkle_proof::TrieMerkleProof}; use casper_types::{ account::AccountHash, - package::{ContractPackageKind, ContractPackageStatus, ContractVersions, Groups}, - AccessRights, AddressableEntity, CLValue, ContractHash, ContractPackageHash, ContractWasm, - ContractWasmHash, EntryPoints, Key, Motes, Package, Phase, ProtocolVersion, StoredValue, - StoredValueTypeMismatch, URef, + bytesrepr, + package::{EntityVersions, Groups, PackageKind, PackageKindTag, PackageStatus}, + AccessRights, AddressableEntity, AddressableEntityHash, CLValue, EntryPoints, Key, Motes, + Package, PackageHash, Phase, ProtocolVersion, StoredValue, StoredValueTypeMismatch, URef, }; use crate::{ - engine_state::{ChecksumRegistry, SystemContractRegistry, ACCOUNT_WASM_HASH}, + engine_state::{ChecksumRegistry, SystemContractRegistry, ACCOUNT_BYTE_CODE_HASH}, execution, execution::AddressGenerator, tracking_copy::TrackingCopy, @@ -25,7 +28,7 @@ pub trait TrackingCopyExt { fn get_entity_hash_by_account_hash( &mut self, account_hash: AccountHash, - ) -> Result; + ) -> Result; /// Gets the entity for a given account by its account address fn get_addressable_entity_by_account_hash( @@ -62,23 +65,24 @@ pub trait TrackingCopyExt { balance_key: Key, ) -> Result<(Motes, TrieMerkleProof), Self::Error>; - /// Gets a contract by Key. - fn get_contract_wasm( - &mut self, - contract_wasm_hash: ContractWasmHash, - ) -> Result; + // /// Gets a contract by Key. + // fn get_byte_code(&mut self, contract_wasm_hash: ByteCodeHash) -> Result; /// Gets an addressable entity by Key. fn get_contract( &mut self, - contract_hash: ContractHash, + contract_hash: AddressableEntityHash, ) -> Result; - /// Gets a contract package by Key. - fn get_contract_package( + /// Gets a package by Key. + fn get_package(&mut self, contract_package_hash: PackageHash) -> Result; + + /// Gets an entity by Key. + fn get_contract_entity( &mut self, - contract_package_hash: ContractPackageHash, - ) -> Result; + entity_hash: AddressableEntityHash, + ) -> Result<(AddressableEntity, bool), Self::Error>; /// Gets the system contract registry. fn get_system_contracts(&mut self) -> Result; @@ -97,17 +101,15 @@ where fn get_entity_hash_by_account_hash( &mut self, account_hash: AccountHash, - ) -> Result { + ) -> Result { let account_key = Key::Account(account_hash); match self.get(&account_key).map_err(Into::into)? { Some(StoredValue::CLValue(cl_value)) => { - let contract_hash = CLValue::into_t::(cl_value)?; - let contract_hash = contract_hash - .into_hash() - .map(ContractHash::new) - .expect("must convert to contract hash"); + let entity_key = CLValue::into_t::(cl_value)?; + let entity_hash = AddressableEntityHash::try_from(entity_key) + .map_err(|_| execution::Error::BytesRepr(bytesrepr::Error::Formatting))?; - Ok(contract_hash) + Ok(entity_hash) } Some(other) => Err(execution::Error::TypeMismatch( StoredValueTypeMismatch::new("CLValue".to_string(), other.type_name()), @@ -131,14 +133,14 @@ where let mut generator = AddressGenerator::new(account.main_purse().addr().as_ref(), Phase::System); - let contract_wasm_hash = *ACCOUNT_WASM_HASH; - let contract_hash = ContractHash::new(generator.new_hash_address()); - let contract_package_hash = ContractPackageHash::new(generator.new_hash_address()); + let contract_wasm_hash = *ACCOUNT_BYTE_CODE_HASH; + let entity_hash = AddressableEntityHash::new(generator.new_hash_address()); + let package_hash = PackageHash::new(generator.new_hash_address()); let entry_points = EntryPoints::new(); let entity = AddressableEntity::new( - contract_package_hash, + package_hash, contract_wasm_hash, account.named_keys().clone(), entry_points, @@ -153,23 +155,23 @@ where let contract_package = { let mut contract_package = Package::new( access_key, - ContractVersions::default(), + EntityVersions::default(), BTreeSet::default(), Groups::default(), - ContractPackageStatus::Locked, - ContractPackageKind::Account(account_hash), + PackageStatus::Locked, + PackageKind::Account(account_hash), ); contract_package - .insert_contract_version(protocol_version.value().major, contract_hash); + .insert_entity_version(protocol_version.value().major, entity_hash); contract_package }; - let contract_key: Key = contract_hash.into(); + let entity_key = Key::addressable_entity_key(PackageKindTag::Account, entity_hash); - self.write(contract_key, StoredValue::AddressableEntity(entity.clone())); - self.write(contract_package_hash.into(), contract_package.into()); + self.write(entity_key, StoredValue::AddressableEntity(entity.clone())); + self.write(package_hash.into(), contract_package.into()); - let contract_by_account = match CLValue::from_t(contract_key) { + let contract_by_account = match CLValue::from_t(entity_key) { Ok(cl_value) => cl_value, Err(error) => return Err(execution::Error::CLValue(error)), }; @@ -186,6 +188,7 @@ where } None => return Err(execution::Error::KeyNotFound(account_key)), }; + match self.get(&contract_key).map_err(Into::into)? { Some(StoredValue::AddressableEntity(contract)) => Ok(contract), Some(other) => Err(execution::Error::TypeMismatch( @@ -270,36 +273,21 @@ where Ok((balance, proof)) } - /// Gets a contract wasm by Key - fn get_contract_wasm( - &mut self, - contract_wasm_hash: ContractWasmHash, - ) -> Result { - let key = contract_wasm_hash.into(); - match self.get(&key).map_err(Into::into)? { - Some(StoredValue::ContractWasm(contract_wasm)) => Ok(contract_wasm), - Some(other) => Err(execution::Error::TypeMismatch( - StoredValueTypeMismatch::new("ContractWasm".to_string(), other.type_name()), - )), - None => Err(execution::Error::KeyNotFound(key)), - } - } - /// Gets a contract header by Key fn get_contract( &mut self, - contract_hash: ContractHash, + entity_hash: AddressableEntityHash, ) -> Result { - let key = contract_hash.into(); + let package_kind_tag = if self.get_system_contracts()?.has_contract_hash(&entity_hash) { + PackageKindTag::System + } else { + PackageKindTag::SmartContract + }; + + let key = Key::addressable_entity_key(package_kind_tag, entity_hash); match self.read(&key).map_err(Into::into)? { Some(StoredValue::AddressableEntity(entity)) => Ok(entity), - Some(StoredValue::Contract(contract)) => { - let contract_key: Key = contract_hash.into(); - let entity: AddressableEntity = contract.into(); - self.write(contract_key, StoredValue::AddressableEntity(entity.clone())); - Ok(entity) - } Some(other) => Err(execution::Error::TypeMismatch( StoredValueTypeMismatch::new( "AddressableEntity or Contract".to_string(), @@ -310,17 +298,53 @@ where } } - fn get_contract_package( + fn get_package(&mut self, package_hash: PackageHash) -> Result { + let key = package_hash.into(); + match self.read(&key).map_err(Into::into)? { + Some(StoredValue::Package(contract_package)) => Ok(contract_package), + Some(other) => Err(execution::Error::TypeMismatch( + StoredValueTypeMismatch::new("Package".to_string(), other.type_name()), + )), + None => match self + .read(&Key::Hash(package_hash.value())) + .map_err(Into::into)? + { + Some(StoredValue::ContractPackage(contract_package)) => { + let package: Package = contract_package.into(); + self.write( + Key::Package(package_hash.value()), + StoredValue::Package(package.clone()), + ); + Ok(package) + } + Some(other) => Err(execution::Error::TypeMismatch( + StoredValueTypeMismatch::new("ContractPackage".to_string(), other.type_name()), + )), + None => Err(execution::Error::KeyNotFound(key)), + }, + } + } + + fn get_contract_entity( &mut self, - contract_package_hash: ContractPackageHash, - ) -> Result { - let key = contract_package_hash.into(); + entity_hash: AddressableEntityHash, + ) -> Result<(AddressableEntity, bool), Self::Error> { + let key = Key::contract_entity_key(entity_hash); match self.read(&key).map_err(Into::into)? { - Some(StoredValue::ContractPackage(contract_package)) => Ok(contract_package), + Some(StoredValue::AddressableEntity(entity)) => Ok((entity, false)), Some(other) => Err(execution::Error::TypeMismatch( - StoredValueTypeMismatch::new("ContractPackage".to_string(), other.type_name()), + StoredValueTypeMismatch::new("AddressableEntity".to_string(), other.type_name()), )), - None => Err(execution::Error::KeyNotFound(key)), + None => match self + .read(&Key::Hash(entity_hash.value())) + .map_err(Into::into)? + { + Some(StoredValue::Contract(contract)) => Ok((contract.into(), true)), + Some(other) => Err(execution::Error::TypeMismatch( + StoredValueTypeMismatch::new("Contract".to_string(), other.type_name()), + )), + None => Err(execution::Error::KeyNotFound(key)), + }, } } diff --git a/execution_engine/src/tracking_copy/mod.rs b/execution_engine/src/tracking_copy/mod.rs index e15beb8eb7..8d027bf26b 100644 --- a/execution_engine/src/tracking_copy/mod.rs +++ b/execution_engine/src/tracking_copy/mod.rs @@ -536,11 +536,17 @@ impl> TrackingCopy { return Ok(query.into_not_found_result(&msg_prefix)); } } + StoredValue::ContractWasm(_) => { + return Ok(query.into_not_found_result("ContractWasm value found.")); + } StoredValue::ContractPackage(_) => { return Ok(query.into_not_found_result("ContractPackage value found.")); } - StoredValue::ContractWasm(_) => { - return Ok(query.into_not_found_result("ContractWasm value found.")); + StoredValue::Package(_) => { + return Ok(query.into_not_found_result("Package value found.")); + } + StoredValue::ByteCode(_) => { + return Ok(query.into_not_found_result("ByteCode value found.")); } StoredValue::Transfer(_) => { return Ok(query.into_not_found_result("Transfer value found.")); diff --git a/execution_engine/src/tracking_copy/tests.rs b/execution_engine/src/tracking_copy/tests.rs index e249f632d0..408312fb12 100644 --- a/execution_engine/src/tracking_copy/tests.rs +++ b/execution_engine/src/tracking_copy/tests.rs @@ -9,10 +9,12 @@ use casper_storage::global_state::{ }; use casper_types::{ account::{AccountHash, ACCOUNT_HASH_LENGTH}, - addressable_entity::{ActionThresholds, AssociatedKeys, ContractHash, NamedKeys, Weight}, + addressable_entity::{ + ActionThresholds, AddressableEntityHash, AssociatedKeys, NamedKeys, Weight, + }, execution::{Effects, Transform, TransformKind}, gens::*, - package::ContractPackageHash, + package::{PackageHash, PackageKindTag}, AccessRights, AddressableEntity, CLValue, Digest, EntryPoints, HashAddr, Key, KeyTag, ProtocolVersion, StoredValue, URef, U256, U512, }; @@ -21,7 +23,7 @@ use super::{ meter::count_meter::Count, AddResult, TrackingCopy, TrackingCopyCache, TrackingCopyQueryResult, }; use crate::{ - engine_state::{EngineConfig, ACCOUNT_WASM_HASH}, + engine_state::{EngineConfig, ACCOUNT_BYTE_CODE_HASH}, runtime_context::dictionary, tracking_copy::{self, ValidationError}, }; @@ -188,8 +190,8 @@ fn tracking_copy_add_named_key() { // DB now holds an `Account` so that we can test adding a `NamedKey` let associated_keys = AssociatedKeys::new(zero_account_hash, Weight::new(1)); let contract = AddressableEntity::new( - ContractPackageHash::new([3u8; 32]), - *ACCOUNT_WASM_HASH, + PackageHash::new([3u8; 32]), + *ACCOUNT_BYTE_CODE_HASH, NamedKeys::new(), EntryPoints::new_with_default_entry_point(), ProtocolVersion::V1_0_0, @@ -391,8 +393,8 @@ proptest! { let purse = URef::new([0u8; 32], AccessRights::READ_ADD_WRITE); let associated_keys = AssociatedKeys::new(pk, Weight::new(1)); let account = AddressableEntity::new( - ContractPackageHash::new([1u8;32]), - *ACCOUNT_WASM_HASH, + PackageHash::new([1u8;32]), + *ACCOUNT_BYTE_CODE_HASH, named_keys, EntryPoints::new_with_default_entry_point(), ProtocolVersion::V1_0_0, @@ -449,16 +451,16 @@ proptest! { AssociatedKeys::default(), ActionThresholds::default(), )); - let contract_key = Key::Hash(hash); + let contract_key = Key::AddressableEntity((PackageKindTag::SmartContract,hash)); // create account which knows about contract let mut account_named_keys = NamedKeys::new(); account_named_keys.insert(contract_name, contract_key); - let contract_hash = ContractHash::new([10;32]); - let new_contract_key: Key = contract_hash.into(); - let account_value = CLValue::from_t(new_contract_key).unwrap(); + let entity_hash = AddressableEntityHash::new([10;32]); + let new_entity_key: Key = Key::addressable_entity_key(PackageKindTag::Account, entity_hash); + let account_value = CLValue::from_t(new_entity_key).unwrap(); let account_key = Key::Account(address); let value = dictionary::handle_stored_value_into(k, v.clone()).unwrap(); @@ -589,15 +591,16 @@ fn validate_query_proof_should_work() { // create account let account_hash = AccountHash::new([3; 32]); let fake_purse = URef::new([4; 32], AccessRights::READ_ADD_WRITE); - let account_contract_hash = ContractHash::new([30; 32]); - let account_contract_key: Key = account_contract_hash.into(); - let cl_value = CLValue::from_t(account_contract_key).unwrap(); + let account_entity_hash = AddressableEntityHash::new([30; 32]); + let account_entity_key: Key = + Key::addressable_entity_key(PackageKindTag::Account, account_entity_hash); + let cl_value = CLValue::from_t(account_entity_key).unwrap(); let account_value = StoredValue::CLValue(cl_value); let account_key = Key::Account(account_hash); let account_contract = StoredValue::AddressableEntity(AddressableEntity::new( - ContractPackageHash::new([20; 32]), - *ACCOUNT_WASM_HASH, + PackageHash::new([20; 32]), + *ACCOUNT_BYTE_CODE_HASH, NamedKeys::new(), EntryPoints::new_with_default_entry_point(), ProtocolVersion::V1_0_0, @@ -636,13 +639,14 @@ fn validate_query_proof_should_work() { tmp }; - let main_contract_hash = ContractHash::new([81; 32]); - let main_contract_key: Key = main_contract_hash.into(); + let main_entity_hash = AddressableEntityHash::new([81; 32]); + let main_entity_key: Key = + Key::addressable_entity_key(PackageKindTag::Account, main_entity_hash); - let cl_value_2 = CLValue::from_t(main_contract_key).unwrap(); - let main_contract = StoredValue::AddressableEntity(AddressableEntity::new( - ContractPackageHash::new([21; 32]), - *ACCOUNT_WASM_HASH, + let cl_value_2 = CLValue::from_t(main_entity_key).unwrap(); + let main_entity = StoredValue::AddressableEntity(AddressableEntity::new( + PackageHash::new([21; 32]), + *ACCOUNT_BYTE_CODE_HASH, named_keys, EntryPoints::new_with_default_entry_point(), ProtocolVersion::V1_0_0, @@ -662,9 +666,9 @@ fn validate_query_proof_should_work() { // persist them let (global_state, root_hash, _tempdir) = state::lmdb::make_temporary_global_state([ (contract_key, contract_value.to_owned()), - (account_contract_key, account_contract.to_owned()), + (account_entity_key, account_contract.to_owned()), (account_key, account_value.to_owned()), - (main_contract_key, main_contract.to_owned()), + (main_entity_key, main_entity.to_owned()), (main_account_key, main_account_value.to_owned()), (uref_key, uref_value), ]); @@ -679,7 +683,7 @@ fn validate_query_proof_should_work() { let path = &[contract_name, account_name]; let result = tracking_copy - .query(&EngineConfig::default(), main_contract_key, path) + .query(&EngineConfig::default(), main_entity_key, path) .expect("should query"); let proofs = if let TrackingCopyQueryResult::Success { proofs, .. } = result { @@ -692,7 +696,7 @@ fn validate_query_proof_should_work() { tracking_copy::validate_query_proof( &root_hash, &proofs, - &main_contract_key, + &main_entity_key, path, &account_value, ) @@ -704,7 +708,7 @@ fn validate_query_proof_should_work() { tracking_copy::validate_query_proof( &root_hash, &proofs, - &main_contract_key, + &main_entity_key, &[], &account_value ), @@ -716,7 +720,7 @@ fn validate_query_proof_should_work() { tracking_copy::validate_query_proof( &root_hash, &proofs, - &main_contract_key, + &main_entity_key, path, &main_account_value ), @@ -740,7 +744,7 @@ fn validate_query_proof_should_work() { tracking_copy::validate_query_proof( &Digest::hash([]), &proofs, - &main_contract_key, + &main_entity_key, path, &account_value ), @@ -752,7 +756,7 @@ fn validate_query_proof_should_work() { tracking_copy::validate_query_proof( &root_hash, &proofs, - &main_contract_key, + &main_entity_key, &[ "a non-existent path key 1".to_string(), "a non-existent path key 2".to_string() @@ -783,7 +787,7 @@ fn validate_query_proof_should_work() { misfit_proof.to_owned(), proofs[2].to_owned() ], - &main_contract_key, + &main_entity_key, path, &account_contract ), @@ -822,7 +826,7 @@ fn validate_query_proof_should_work() { state::lmdb::make_temporary_global_state([ (account_key, account_value.to_owned()), (contract_key, contract_value), - (main_contract_key, main_contract), + (main_entity_key, main_entity), (main_account_key, main_account_value), ]); @@ -834,7 +838,7 @@ fn validate_query_proof_should_work() { let misfit_tracking_copy = TrackingCopy::new(misfit_view); let misfit_result = misfit_tracking_copy - .query(&EngineConfig::default(), main_contract_key, path) + .query(&EngineConfig::default(), main_entity_key, path) .expect("should query"); let misfit_proof = if let TrackingCopyQueryResult::Success { proofs, .. } = misfit_result { @@ -848,7 +852,7 @@ fn validate_query_proof_should_work() { tracking_copy::validate_query_proof( &root_hash, &[proofs[0].to_owned(), misfit_proof, proofs[2].to_owned()], - &main_contract_key, + &main_entity_key, path, &account_value ), @@ -874,14 +878,14 @@ fn get_keys_should_return_keys_in_the_account_keyspace() { // account 1 let account_1_hash = AccountHash::new([1; 32]); - let account_cl_value = CLValue::from_t(ContractHash::new([20; 32])).unwrap(); + let account_cl_value = CLValue::from_t(AddressableEntityHash::new([20; 32])).unwrap(); let account_1_value = StoredValue::CLValue(account_cl_value); let account_1_key = Key::Account(account_1_hash); // account 2 let account_2_hash = AccountHash::new([2; 32]); - let fake_account_cl_value = CLValue::from_t(ContractHash::new([21; 32])).unwrap(); + let fake_account_cl_value = CLValue::from_t(AddressableEntityHash::new([21; 32])).unwrap(); let account_2_value = StoredValue::CLValue(fake_account_cl_value); let account_2_key = Key::Account(account_2_hash); @@ -917,7 +921,7 @@ fn get_keys_should_return_keys_in_the_uref_keyspace() { // account let account_hash = AccountHash::new([1; 32]); - let account_cl_value = CLValue::from_t(ContractHash::new([20; 32])).unwrap(); + let account_cl_value = CLValue::from_t(AddressableEntityHash::new([20; 32])).unwrap(); let account_value = StoredValue::CLValue(account_cl_value); let account_key = Key::Account(account_hash); @@ -1009,7 +1013,7 @@ fn get_keys_should_handle_reads_from_empty_trie() { // persist account let account_hash = AccountHash::new([1; 32]); - let account_value = CLValue::from_t(ContractHash::new([10; 32])).unwrap(); + let account_value = CLValue::from_t(AddressableEntityHash::new([10; 32])).unwrap(); let account_value = StoredValue::CLValue(account_value); let account_key = Key::Account(account_hash); tracking_copy.write(account_key, account_value); diff --git a/execution_engine_testing/test_support/src/auction.rs b/execution_engine_testing/test_support/src/auction.rs index bda6f93552..0b3f42853a 100644 --- a/execution_engine_testing/test_support/src/auction.rs +++ b/execution_engine_testing/test_support/src/auction.rs @@ -348,7 +348,7 @@ pub fn create_delegate_request( next_validator_key: PublicKey, delegation_amount: U512, delegator_account_hash: AccountHash, - contract_hash: casper_types::ContractHash, + contract_hash: casper_types::AddressableEntityHash, ) -> ExecuteRequest { let entry_point = auction::METHOD_DELEGATE; let args = runtime_args! { 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 e09e6b0a51..258094afd2 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, ContractHash, ContractPackageHash, ContractVersion, DeployHash, - ExecutableDeployItem, HashAddr, RuntimeArgs, + account::AccountHash, AddressableEntityHash, DeployHash, EntityVersion, ExecutableDeployItem, + HashAddr, PackageHash, RuntimeArgs, }; use crate::{utils, DEFAULT_GAS_PRICE}; @@ -60,7 +60,7 @@ impl DeployItemBuilder { /// Sets payment code of the deploy with contract hash. pub fn with_stored_payment_hash( mut self, - hash: ContractHash, + hash: AddressableEntityHash, entry_point: &str, args: RuntimeArgs, ) -> Self { @@ -90,7 +90,7 @@ impl DeployItemBuilder { /// Sets the payment code of the deploy with a contract package hash. pub fn with_stored_versioned_payment_hash( mut self, - package_hash: ContractPackageHash, + package_hash: PackageHash, entry_point: &str, args: RuntimeArgs, ) -> Self { @@ -144,7 +144,7 @@ impl DeployItemBuilder { /// arguments. pub fn with_stored_session_hash( mut self, - hash: ContractHash, + hash: AddressableEntityHash, entry_point: &str, args: RuntimeArgs, ) -> Self { @@ -175,7 +175,7 @@ impl DeployItemBuilder { pub fn with_stored_versioned_contract_by_name( mut self, name: &str, - version: Option, + version: Option, entry_point: &str, args: RuntimeArgs, ) -> Self { @@ -192,7 +192,7 @@ impl DeployItemBuilder { pub fn with_stored_versioned_contract_by_hash( mut self, hash: HashAddr, - version: Option, + version: Option, entry_point: &str, args: RuntimeArgs, ) -> Self { @@ -209,7 +209,7 @@ impl DeployItemBuilder { pub fn with_stored_versioned_payment_contract_by_name( mut self, key_name: &str, - version: Option, + version: Option, entry_point: &str, args: RuntimeArgs, ) -> Self { @@ -225,8 +225,9 @@ impl DeployItemBuilder { /// Sets the payment code of the deploy using a stored versioned contract by contract hash. pub fn with_stored_versioned_payment_contract_by_hash( mut self, + // TODO: Make this PackageHash hash: HashAddr, - version: Option, + version: Option, entry_point: &str, args: RuntimeArgs, ) -> Self { 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 f5ddd53267..3dfd210c5a 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::{ deploy_item::DeployItem, execute_request::ExecuteRequest, }; use casper_types::{ - account::AccountHash, runtime_args, ContractHash, ContractPackageHash, ContractVersion, + account::AccountHash, runtime_args, AddressableEntityHash, EntityVersion, PackageHash, ProtocolVersion, RuntimeArgs, }; @@ -113,7 +113,7 @@ impl ExecuteRequestBuilder { /// Returns an [`ExecuteRequest`] that will call a stored contract by hash. pub fn contract_call_by_hash( sender: AccountHash, - contract_hash: ContractHash, + contract_hash: AddressableEntityHash, entry_point: &str, args: RuntimeArgs, ) -> Self { @@ -155,8 +155,8 @@ impl ExecuteRequestBuilder { /// Returns an [`ExecuteRequest`] that will call a versioned stored contract by hash. pub fn versioned_contract_call_by_hash( sender: AccountHash, - contract_package_hash: ContractPackageHash, - version: Option, + contract_package_hash: PackageHash, + version: Option, entry_point_name: &str, args: RuntimeArgs, ) -> Self { @@ -183,7 +183,7 @@ impl ExecuteRequestBuilder { pub fn versioned_contract_call_by_name( sender: AccountHash, contract_name: &str, - version: Option, + version: Option, entry_point_name: &str, args: RuntimeArgs, ) -> Self { @@ -216,6 +216,30 @@ impl ExecuteRequestBuilder { ExecuteRequestBuilder::from_deploy_item(deploy_item) } + + /// 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(); + + 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(); + + ExecuteRequestBuilder::new().push_deploy(deploy) + } } impl Default for ExecuteRequestBuilder { 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 6bc1a98e42..fa5e36372e 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -43,7 +43,9 @@ use casper_storage::{ use casper_types::{ account::AccountHash, bytesrepr::{self, FromBytes}, + contracts::ContractHash, execution::Effects, + package::PackageKindTag, runtime_args, system::{ auction::{ @@ -54,10 +56,10 @@ use casper_types::{ mint::{ROUND_SEIGNIORAGE_RATE_KEY, TOTAL_SUPPLY_KEY}, AUCTION, HANDLE_PAYMENT, MINT, STANDARD_PAYMENT, }, - AddressableEntity, AuctionCosts, CLTyped, CLValue, Contract, ContractHash, ContractPackageHash, - ContractWasm, DeployHash, DeployInfo, Digest, EraId, Gas, HandlePaymentCosts, Key, KeyTag, - MintCosts, Motes, Package, ProtocolVersion, PublicKey, RefundHandling, StoredValue, Transfer, - TransferAddr, URef, UpgradeConfig, OS_PAGE_SIZE, U512, + AddressableEntity, AddressableEntityHash, AuctionCosts, ByteCode, ByteCodeHash, ByteCodeKind, + CLTyped, CLValue, Contract, DeployHash, DeployInfo, Digest, EraId, Gas, HandlePaymentCosts, + Key, KeyTag, MintCosts, Motes, Package, PackageHash, ProtocolVersion, PublicKey, + RefundHandling, StoredValue, Transfer, TransferAddr, URef, UpgradeConfig, OS_PAGE_SIZE, U512, }; use tempfile::TempDir; @@ -671,11 +673,12 @@ where /// # Panics /// Panics if the total supply can't be found. pub fn total_supply(&self, maybe_post_state: Option) -> U512 { - let mint_key: Key = self - .get_system_contract_hash(MINT) + let mint_entity_hash = self + .get_system_entity_hash(MINT) .cloned() - .expect("should have mint_contract_hash") - .into(); + .expect("should have mint_contract_hash"); + + let mint_key = Key::addressable_entity_key(PackageKindTag::System, mint_entity_hash); let result = self.query(maybe_post_state, mint_key, &[TOTAL_SUPPLY_KEY.to_string()]); @@ -692,7 +695,8 @@ where /// # 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_key: Key = self.get_mint_contract_hash().into(); + let mint_key: Key = + Key::addressable_entity_key(PackageKindTag::System, self.get_mint_contract_hash()); let mint_contract = self .query(maybe_post_state, mint_key, &[]) @@ -884,7 +888,7 @@ where 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 - .get_last_exec_results() + .get_last_exec_result() .expect("Expected to be called after run()"); let exec_result = exec_results .get(0) @@ -903,7 +907,7 @@ where 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 - .get_last_exec_results() + .get_last_exec_result() .expect("Expected to be called after run()"); let exec_result = exec_results .get(0) @@ -921,7 +925,7 @@ where /// Returns `true` if the las exec had an error, otherwise returns false. pub fn is_error(&self) -> bool { - self.get_last_exec_results() + self.get_last_exec_result() .expect("Expected to be called after run()") .get(0) .expect("Unable to get first execution result") @@ -930,7 +934,7 @@ where /// Returns an `Option` if the last exec had an error. pub fn get_error(&self) -> Option { - self.get_last_exec_results() + self.get_last_exec_result() .expect("Expected to be called after run()") .get(0) .expect("Unable to get first deploy result") @@ -950,37 +954,39 @@ where .expect("Unable to obtain genesis account. Please run genesis first.") } - /// Returns the [`ContractHash`] of the mint, panics if it can't be found. - pub fn get_mint_contract_hash(&self) -> ContractHash { - self.get_system_contract_hash(MINT) + /// Returns the [`AddressableEntityHash`] of the mint, panics if it can't be found. + pub fn get_mint_contract_hash(&self) -> AddressableEntityHash { + self.get_system_entity_hash(MINT) .cloned() .expect("Unable to obtain mint contract. Please run genesis first.") } - /// Returns the [`ContractHash`] of the "handle payment" contract, panics if it can't be found. - pub fn get_handle_payment_contract_hash(&self) -> ContractHash { - self.get_system_contract_hash(HANDLE_PAYMENT) + /// Returns the [`AddressableEntityHash`] of the "handle payment" contract, panics if it can't + /// be found. + pub fn get_handle_payment_contract_hash(&self) -> AddressableEntityHash { + self.get_system_entity_hash(HANDLE_PAYMENT) .cloned() .expect("Unable to obtain handle payment contract. Please run genesis first.") } - /// Returns the [`ContractHash`] of the "standard payment" contract, panics if it can't be - /// found. - pub fn get_standard_payment_contract_hash(&self) -> ContractHash { - self.get_system_contract_hash(STANDARD_PAYMENT) + /// Returns the [`AddressableEntityHash`] of the "standard payment" contract, panics if it can't + /// be found. + pub fn get_standard_payment_contract_hash(&self) -> AddressableEntityHash { + self.get_system_entity_hash(STANDARD_PAYMENT) .cloned() .expect("Unable to obtain standard payment contract. Please run genesis first.") } - fn get_system_contract_hash(&self, contract_name: &str) -> Option<&ContractHash> { + fn get_system_entity_hash(&self, contract_name: &str) -> Option<&AddressableEntityHash> { self.system_contract_registry .as_ref() .and_then(|registry| registry.get(contract_name)) } - /// Returns the [`ContractHash`] of the "auction" contract, panics if it can't be found. - pub fn get_auction_contract_hash(&self) -> ContractHash { - self.get_system_contract_hash(AUCTION) + /// Returns the [`AddressableEntityHash`] of the "auction" contract, panics if it can't be + /// found. + pub fn get_auction_contract_hash(&self) -> AddressableEntityHash { + self.get_system_entity_hash(AUCTION) .cloned() .expect("Unable to obtain auction contract. Please run genesis first.") } @@ -1009,7 +1015,7 @@ where } /// Returns the last results execs. - pub fn get_last_exec_results(&self) -> Option>> { + pub fn get_last_exec_result(&self) -> Option>> { let exec_results = self.exec_results.last()?; Some(exec_results.iter().map(Rc::clone).collect()) @@ -1051,11 +1057,12 @@ where /// Returns the "handle payment" contract, panics if it can't be found. pub fn get_handle_payment_contract(&self) -> AddressableEntity { - let handle_payment_contract: Key = self - .get_system_contract_hash(HANDLE_PAYMENT) - .cloned() - .expect("should have handle payment contract uref") - .into(); + let handle_payment_contract = Key::addressable_entity_key( + PackageKindTag::System, + self.get_system_entity_hash(HANDLE_PAYMENT) + .cloned() + .expect("should have handle payment contract uref"), + ); self.query(None, handle_payment_contract, &[]) .and_then(|v| v.try_into().map_err(|error| format!("{:?}", error))) .expect("should find handle payment URef") @@ -1095,17 +1102,14 @@ where } /// Gets the contract hash associated with a given account hash. - pub fn get_contract_hash_by_account_hash( + pub fn get_entity_hash_by_account_hash( &self, account_hash: AccountHash, - ) -> Option { + ) -> Option { match self.query(None, Key::Account(account_hash), &[]).ok() { Some(StoredValue::CLValue(cl_value)) => { - let contract_key = - CLValue::into_t::(cl_value).expect("must have contract hash"); - Some(ContractHash::new( - contract_key.into_hash().expect("must have hash addr"), - )) + let entity_key = CLValue::into_t::(cl_value).expect("must have contract hash"); + entity_key.into_entity_hash() } Some(_) | None => None, } @@ -1139,11 +1143,23 @@ where .expect("account to exist") } - /// Queries for an addressable entity by `ContractHash`. - pub fn get_addressable_entity(&self, contract_hash: ContractHash) -> Option { - let contract_value: StoredValue = self - .query(None, contract_hash.into(), &[]) - .expect("should have contract value"); + /// Queries for an addressable entity by `AddressableEntityHash`. + pub fn get_addressable_entity( + &self, + entity_hash: AddressableEntityHash, + ) -> Option { + let entity_key = Key::addressable_entity_key(PackageKindTag::SmartContract, entity_hash); + + let contract_value: StoredValue = match self.query(None, entity_key, &[]) { + Ok(stored_value) => stored_value, + Err(_) => self + .query( + None, + Key::addressable_entity_key(PackageKindTag::System, entity_hash), + &[], + ) + .expect("must have value"), + }; if let StoredValue::AddressableEntity(contract) = contract_value { Some(contract) @@ -1165,29 +1181,28 @@ where } } - /// Queries for a contract by `ContractHash` and returns an `Option`. - pub fn get_contract_wasm(&self, contract_hash: ContractHash) -> Option { - let contract_value: StoredValue = self - .query(None, contract_hash.into(), &[]) + /// Queries for byte code by `ByteCodeAddr` and returns an `Option`. + pub fn get_byte_code(&self, byte_code_hash: ByteCodeHash) -> Option { + let byte_code_key = Key::byte_code_key(ByteCodeKind::V1CasperWasm, byte_code_hash.value()); + + let byte_code_value: StoredValue = self + .query(None, byte_code_key, &[]) .expect("should have contract value"); - if let StoredValue::ContractWasm(contract_wasm) = contract_value { - Some(contract_wasm) + if let StoredValue::ByteCode(byte_code) = byte_code_value { + Some(byte_code) } else { None } } - /// Queries for a contract package by `ContractPackageHash`. - pub fn get_contract_package( - &self, - contract_package_hash: ContractPackageHash, - ) -> Option { + /// Queries for a contract package by `PackageHash`. + pub fn get_package(&self, package_hash: PackageHash) -> Option { let contract_value: StoredValue = self - .query(None, contract_package_hash.into(), &[]) + .query(None, package_hash.into(), &[]) .expect("should have package value"); - if let StoredValue::ContractPackage(package) = contract_value { + if let StoredValue::Package(package) = contract_value { Some(package) } else { None @@ -1231,7 +1246,7 @@ where /// Returns the `Gas` cost of the last exec. pub fn last_exec_gas_cost(&self) -> Gas { let exec_results = self - .get_last_exec_results() + .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() @@ -1372,12 +1387,12 @@ where } /// Gets a stored value from a contract's named keys. - pub fn get_value(&mut self, contract_hash: ContractHash, name: &str) -> T + pub fn get_value(&mut self, entity_hash: AddressableEntityHash, name: &str) -> T where T: FromBytes + CLTyped, { let contract = self - .get_addressable_entity(contract_hash) + .get_addressable_entity(entity_hash) .expect("should have contract"); let key = contract .named_keys() @@ -1407,40 +1422,32 @@ where self.get_value(auction_contract, UNBONDING_DELAY_KEY) } - /// Gets the [`ContractHash`] of the system auction contract, panics if it can't be found. - pub fn get_system_auction_hash(&self) -> ContractHash { + /// Gets the [`AddressableEntityHash`] of the system auction contract, panics if it can't be + /// found. + pub fn get_system_auction_hash(&self) -> AddressableEntityHash { let state_root_hash = self.get_post_state_hash(); self.engine_state .get_system_auction_hash(state_root_hash) .expect("should have auction hash") } - /// Gets the [`ContractHash`] of the system mint contract, panics if it can't be found. - pub fn get_system_mint_hash(&self) -> ContractHash { + /// Gets the [`AddressableEntityHash`] of the system mint contract, panics if it can't be found. + pub fn get_system_mint_hash(&self) -> AddressableEntityHash { let state_root_hash = self.get_post_state_hash(); self.engine_state .get_system_mint_hash(state_root_hash) .expect("should have mint hash") } - /// Gets the [`ContractHash`] of the system handle payment contract, panics if it can't be - /// found. - pub fn get_system_handle_payment_hash(&self) -> ContractHash { + /// Gets the [`AddressableEntityHash`] of the system handle payment contract, panics if it can't + /// be found. + pub fn get_system_handle_payment_hash(&self) -> AddressableEntityHash { let state_root_hash = self.get_post_state_hash(); self.engine_state .get_handle_payment_hash(state_root_hash) .expect("should have handle payment hash") } - /// Returns the [`ContractHash`] of the system standard payment contract, panics if it can't be - /// found. - pub fn get_system_standard_payment_hash(&self) -> ContractHash { - let state_root_hash = self.get_post_state_hash(); - self.engine_state - .get_standard_payment_hash(state_root_hash) - .expect("should have standard payment hash") - } - /// Resets the `exec_results`, `upgrade_results` and `transform` fields. pub fn clear_results(&mut self) -> &mut Self { self.exec_results = Vec::new(); diff --git a/execution_engine_testing/tests/benches/auction_bench.rs b/execution_engine_testing/tests/benches/auction_bench.rs index 2de9287cf4..e558e388a8 100644 --- a/execution_engine_testing/tests/benches/auction_bench.rs +++ b/execution_engine_testing/tests/benches/auction_bench.rs @@ -196,7 +196,7 @@ fn create_delegate_request( next_validator_key: PublicKey, delegation_amount: U512, delegator_account_hash: AccountHash, - contract_hash: casper_types::ContractHash, + contract_hash: casper_types::AddressableEntityHash, ) -> ExecuteRequest { let entry_point = auction::METHOD_DELEGATE; let args = runtime_args! { diff --git a/execution_engine_testing/tests/fixtures/call_stack_fixture/global_state/data.lmdb b/execution_engine_testing/tests/fixtures/call_stack_fixture/global_state/data.lmdb new file mode 100644 index 0000000000..bf1a45fa0e Binary files /dev/null and b/execution_engine_testing/tests/fixtures/call_stack_fixture/global_state/data.lmdb differ diff --git a/execution_engine_testing/tests/fixtures/call_stack_fixture/global_state/data.lmdb-lock b/execution_engine_testing/tests/fixtures/call_stack_fixture/global_state/data.lmdb-lock new file mode 100644 index 0000000000..25594bc32f Binary files /dev/null and b/execution_engine_testing/tests/fixtures/call_stack_fixture/global_state/data.lmdb-lock differ diff --git a/execution_engine_testing/tests/fixtures/call_stack_fixture/state.json b/execution_engine_testing/tests/fixtures/call_stack_fixture/state.json new file mode 100644 index 0000000000..deb85db9cd --- /dev/null +++ b/execution_engine_testing/tests/fixtures/call_stack_fixture/state.json @@ -0,0 +1,6 @@ +{ + "genesis_request": { + "protocol_version": "1.0.0" + }, + "post_state_hash": "6d2d9f1fadfbdc9396251fc2c9325ff7e08c70040a51bc6519d70a0dd86b7575" +} \ No newline at end of file diff --git a/execution_engine_testing/tests/fixtures/groups/global_state/data.lmdb b/execution_engine_testing/tests/fixtures/groups/global_state/data.lmdb new file mode 100644 index 0000000000..ca43002242 Binary files /dev/null and b/execution_engine_testing/tests/fixtures/groups/global_state/data.lmdb differ diff --git a/execution_engine_testing/tests/fixtures/groups/global_state/data.lmdb-lock b/execution_engine_testing/tests/fixtures/groups/global_state/data.lmdb-lock new file mode 100644 index 0000000000..08525ff39c Binary files /dev/null and b/execution_engine_testing/tests/fixtures/groups/global_state/data.lmdb-lock differ diff --git a/execution_engine_testing/tests/fixtures/groups/state.json b/execution_engine_testing/tests/fixtures/groups/state.json new file mode 100644 index 0000000000..4e201414b8 --- /dev/null +++ b/execution_engine_testing/tests/fixtures/groups/state.json @@ -0,0 +1,6 @@ +{ + "genesis_request": { + "protocol_version": "1.0.0" + }, + "post_state_hash": "f009952b02f61ba14c6ead8deade5f5ab1110a9442ddc7146677f1c0fadd76d4" +} \ No newline at end of file diff --git a/execution_engine_testing/tests/fixtures/upgrade_thresholds/global_state/data.lmdb b/execution_engine_testing/tests/fixtures/upgrade_thresholds/global_state/data.lmdb new file mode 100644 index 0000000000..2b508cbc02 Binary files /dev/null and b/execution_engine_testing/tests/fixtures/upgrade_thresholds/global_state/data.lmdb differ diff --git a/execution_engine_testing/tests/fixtures/upgrade_thresholds/global_state/data.lmdb-lock b/execution_engine_testing/tests/fixtures/upgrade_thresholds/global_state/data.lmdb-lock new file mode 100644 index 0000000000..35e8d70a41 Binary files /dev/null and b/execution_engine_testing/tests/fixtures/upgrade_thresholds/global_state/data.lmdb-lock differ diff --git a/execution_engine_testing/tests/fixtures/upgrade_thresholds/state.json b/execution_engine_testing/tests/fixtures/upgrade_thresholds/state.json new file mode 100644 index 0000000000..81c929d4ef --- /dev/null +++ b/execution_engine_testing/tests/fixtures/upgrade_thresholds/state.json @@ -0,0 +1,495 @@ +{ + "genesis_request": { + "genesis_config_hash": "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a", + "protocol_version": "1.0.0", + "ee_config": { + "accounts": [ + { + "Account": { + "public_key": "01d5af25e204ad03d0a26e236996404f1be51a60948bcc026cd084a83690b756d3", + "balance": "100000000000000000", + "validator": null + } + }, + { + "Account": { + "public_key": "01bb47d33d777b4559bb917d1825827421c4a6b1b9737f12e1c58ea4305af88b74", + "balance": "100000000000000000", + "validator": null + } + } + ], + "wasm_config": { + "max_memory": 64, + "max_stack_height": 500, + "opcode_costs": { + "bit": 300, + "add": 210, + "mul": 240, + "div": 320, + "load": 2500, + "store": 4700, + "const": 110, + "local": 390, + "global": 390, + "integer_comparison": 250, + "conversion": 420, + "unreachable": 270, + "nop": 200, + "current_memory": 290, + "grow_memory": 240000, + "control_flow": { + "block": 440, + "loop": 440, + "if": 440, + "else": 440, + "end": 440, + "br": 440000, + "br_if": 440000, + "return": 440, + "call": 140000, + "call_indirect": 140000, + "drop": 440, + "select": 440, + "br_table": { + "cost": 440000, + "size_multiplier": 100 + } + } + }, + "storage_costs": { + "gas_per_byte": 630000 + }, + "host_function_costs": { + "read_value": { + "cost": 6000, + "arguments": [ + 0, + 0, + 0 + ] + }, + "dictionary_get": { + "cost": 5500, + "arguments": [ + 0, + 590, + 0 + ] + }, + "write": { + "cost": 14000, + "arguments": [ + 0, + 0, + 0, + 980 + ] + }, + "dictionary_put": { + "cost": 9500, + "arguments": [ + 0, + 1800, + 0, + 520 + ] + }, + "add": { + "cost": 5800, + "arguments": [ + 0, + 0, + 0, + 0 + ] + }, + "new_uref": { + "cost": 17000, + "arguments": [ + 0, + 0, + 590 + ] + }, + "load_named_keys": { + "cost": 42000, + "arguments": [ + 0, + 0 + ] + }, + "ret": { + "cost": 23000, + "arguments": [ + 0, + 420000 + ] + }, + "get_key": { + "cost": 2000, + "arguments": [ + 0, + 440, + 0, + 0, + 0 + ] + }, + "has_key": { + "cost": 1500, + "arguments": [ + 0, + 840 + ] + }, + "put_key": { + "cost": 38000, + "arguments": [ + 0, + 1100, + 0, + 0 + ] + }, + "remove_key": { + "cost": 61000, + "arguments": [ + 0, + 3200 + ] + }, + "revert": { + "cost": 500, + "arguments": [ + 0 + ] + }, + "is_valid_uref": { + "cost": 760, + "arguments": [ + 0, + 0 + ] + }, + "add_associated_key": { + "cost": 9000, + "arguments": [ + 0, + 0, + 0 + ] + }, + "remove_associated_key": { + "cost": 4200, + "arguments": [ + 0, + 0 + ] + }, + "update_associated_key": { + "cost": 4200, + "arguments": [ + 0, + 0, + 0 + ] + }, + "set_action_threshold": { + "cost": 74000, + "arguments": [ + 0, + 0 + ] + }, + "get_caller": { + "cost": 380, + "arguments": [ + 0 + ] + }, + "get_blocktime": { + "cost": 330, + "arguments": [ + 0 + ] + }, + "create_purse": { + "cost": 2500000000, + "arguments": [ + 0, + 0 + ] + }, + "transfer_to_account": { + "cost": 2500000000, + "arguments": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "transfer_from_purse_to_account": { + "cost": 2500000000, + "arguments": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "transfer_from_purse_to_purse": { + "cost": 82000, + "arguments": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "get_balance": { + "cost": 3800, + "arguments": [ + 0, + 0, + 0 + ] + }, + "get_phase": { + "cost": 710, + "arguments": [ + 0 + ] + }, + "get_system_contract": { + "cost": 1100, + "arguments": [ + 0, + 0, + 0 + ] + }, + "get_main_purse": { + "cost": 1300, + "arguments": [ + 0 + ] + }, + "read_host_buffer": { + "cost": 3500, + "arguments": [ + 0, + 310, + 0 + ] + }, + "create_contract_package_at_hash": { + "cost": 200, + "arguments": [ + 0, + 0 + ] + }, + "create_contract_user_group": { + "cost": 200, + "arguments": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "add_contract_version": { + "cost": 200, + "arguments": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "disable_contract_version": { + "cost": 200, + "arguments": [ + 0, + 0, + 0, + 0 + ] + }, + "call_contract": { + "cost": 4500, + "arguments": [ + 0, + 0, + 0, + 0, + 0, + 420, + 0 + ] + }, + "call_versioned_contract": { + "cost": 4500, + "arguments": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 420, + 0 + ] + }, + "get_named_arg_size": { + "cost": 200, + "arguments": [ + 0, + 0, + 0 + ] + }, + "get_named_arg": { + "cost": 200, + "arguments": [ + 0, + 0, + 0, + 0 + ] + }, + "remove_contract_user_group": { + "cost": 200, + "arguments": [ + 0, + 0, + 0, + 0 + ] + }, + "provision_contract_user_group_uref": { + "cost": 200, + "arguments": [ + 0, + 0, + 0, + 0, + 0 + ] + }, + "remove_contract_user_group_urefs": { + "cost": 200, + "arguments": [ + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "print": { + "cost": 20000, + "arguments": [ + 0, + 4600 + ] + }, + "blake2b": { + "cost": 200, + "arguments": [ + 0, + 0, + 0, + 0 + ] + }, + "random_bytes": { + "cost": 200, + "arguments": [ + 0, + 0 + ] + } + } + }, + "system_config": { + "wasmless_transfer_cost": 100000000, + "auction_costs": { + "get_era_validators": 10000, + "read_seigniorage_recipients": 10000, + "add_bid": 2500000000, + "withdraw_bid": 2500000000, + "delegate": 2500000000, + "undelegate": 2500000000, + "run_auction": 10000, + "slash": 10000, + "distribute": 10000, + "withdraw_delegator_reward": 10000, + "withdraw_validator_reward": 10000, + "read_era_id": 10000, + "activate_bid": 10000, + "redelegate": 2500000000 + }, + "mint_costs": { + "mint": 2500000000, + "reduce_total_supply": 10000, + "create": 2500000000, + "balance": 10000, + "transfer": 10000, + "read_base_round_reward": 10000, + "mint_into_existing_purse": 2500000000 + }, + "handle_payment_costs": { + "get_payment_purse": 10000, + "set_refund_purse": 10000, + "get_refund_purse": 10000, + "finalize_payment": 10000 + }, + "standard_payment_costs": { + "pay": 10000 + } + }, + "validator_slots": 100, + "auction_delay": 1, + "locked_funds_period_millis": 7776000000, + "round_seigniorage_rate": [ + 7, + 87535408 + ], + "unbonding_delay": 7, + "genesis_timestamp_millis": 0 + }, + "chainspec_registry": { + "chainspec_raw_hash": "11c0e79b71c3976ccd0c02d1310e2516c08edc9d8b6f57ccd680d63a4d8e72da", + "genesis_accounts_raw_hash": "0afd4a04d7720da9922f2b40249989faf4ff8096e1ed49bee615bb6cb1ee4f7d", + "global_state_raw_hash": null + } + }, + "post_state_hash": "059d4fbbc1048314fd58111bbb6e733626de760b771793a181822e984fdd72a9" +} \ No newline at end of file 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 5a9a412181..c20ee8bca6 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 @@ -2,13 +2,12 @@ use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, PRODUCTION_RUN_GENESIS_REQUEST, }; -use casper_types::{runtime_args, RuntimeArgs}; +use casper_types::{runtime_args, ApiError, RuntimeArgs}; const CONTRACT_HASH_NAME: &str = "contract_stored"; const ENTRY_POINT_CONTRACT: &str = "named_keys_contract"; const ENTRY_POINT_SESSION: &str = "named_keys_session"; const ENTRY_POINT_CONTRACT_TO_CONTRACT: &str = "named_keys_contract_to_contract"; -const ENTRY_POINT_SESSION_TO_SESSION: &str = "named_keys_session_to_session"; #[ignore] #[test] @@ -38,7 +37,13 @@ fn should_run_stored_named_keys_session() { ) .build(); - builder.exec(exec_request_1).expect_success().commit(); + builder.exec(exec_request_1).expect_failure(); + + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::Revert(ApiError::User(0)), + ); + + builder.assert_error(expected_error) } #[ignore] @@ -56,22 +61,6 @@ fn should_run_stored_named_keys_contract_to_contract() { builder.exec(exec_request_1).expect_success().commit(); } -#[ignore] -#[test] -fn should_run_stored_named_keys_module_bytes_to_session() { - let mut builder = setup(); - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - "named_keys_stored_call.wasm", - runtime_args! { - "entry_point" => ENTRY_POINT_SESSION, - }, - ) - .build(); - - builder.exec(exec_request_1).expect_success().commit(); -} - #[ignore] #[test] fn should_run_stored_named_keys_module_bytes_to_contract() { @@ -104,22 +93,6 @@ fn should_run_stored_named_keys_module_bytes_to_contract_to_contract() { builder.exec(exec_request_1).expect_success().commit(); } -#[ignore] -#[test] -fn should_run_stored_named_keys_module_bytes_to_session_to_session() { - let mut builder = setup(); - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - "named_keys_stored_call.wasm", - runtime_args! { - "entry_point" => ENTRY_POINT_SESSION_TO_SESSION, - }, - ) - .build(); - - builder.exec(exec_request_1).expect_success().commit(); -} - fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(&PRODUCTION_RUN_GENESIS_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 6a297aea57..c35d8937b6 100644 --- a/execution_engine_testing/tests/src/test/contract_api/dictionary.rs +++ b/execution_engine_testing/tests/src/test/contract_api/dictionary.rs @@ -9,8 +9,9 @@ use casper_execution_engine::{ execution::Error, }; use casper_types::{ - account::AccountHash, runtime_args, system::mint, AccessRights, ApiError, CLType, CLValue, - ContractHash, GenesisAccount, Key, Motes, RuntimeArgs, StoredValue, U512, + account::AccountHash, package::PackageKindTag, runtime_args, system::mint, AccessRights, + AddressableEntityHash, ApiError, CLType, CLValue, GenesisAccount, Key, Motes, RuntimeArgs, + StoredValue, U512, }; use std::{convert::TryFrom, path::PathBuf}; @@ -23,7 +24,7 @@ const DICTIONARY_READ: &str = "dictionary_read.wasm"; const READ_FROM_KEY: &str = "read_from_key.wasm"; const ACCOUNT_1_ADDR: AccountHash = AccountHash::new([1u8; 32]); -fn setup() -> (LmdbWasmTestBuilder, ContractHash) { +fn setup() -> (LmdbWasmTestBuilder, AddressableEntityHash) { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); @@ -61,15 +62,14 @@ fn setup() -> (LmdbWasmTestBuilder, ContractHash) { .contains(dictionary::MALICIOUS_KEY_NAME)); assert!(contract.named_keys().contains(dictionary::DICTIONARY_REF)); - let contract_hash = contract + let entity_hash = contract .named_keys() .get(dictionary::CONTRACT_HASH_NAME) .cloned() - .and_then(Key::into_hash) - .map(ContractHash::new) + .and_then(Key::into_entity_hash) .expect("should have hash"); - (builder, contract_hash) + (builder, entity_hash) } fn query_dictionary_item( @@ -87,14 +87,16 @@ fn query_dictionary_item( } let stored_value = builder.query(None, key, &[])?; if let StoredValue::CLValue(cl_value) = stored_value { - let contract_hash: ContractHash = CLValue::into_t::(cl_value) + let entity_hash: AddressableEntityHash = CLValue::into_t::(cl_value) .expect("must convert to contract hash") - .into_hash() - .map(ContractHash::new) + .into_entity_hash() .expect("must convert to contract hash"); + + let entity_key = Key::addressable_entity_key(PackageKindTag::Account, entity_hash); + return query_dictionary_item( builder, - contract_hash.into(), + entity_key, dictionary_name, dictionary_item_key, ); @@ -102,7 +104,7 @@ fn query_dictionary_item( return Err("Provided base key is not an account".to_string()); } } - Key::Hash(_) => { + Key::AddressableEntity(_) => { if let Some(name) = dictionary_name { let stored_value = builder.query(None, key, &[])?; @@ -229,9 +231,7 @@ fn should_not_write_with_read_access_rights() { builder.exec(call_request).commit(); - let exec_results = builder - .get_last_exec_results() - .expect("should have results"); + 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"); assert!( @@ -283,9 +283,7 @@ fn should_not_read_with_write_access_rights() { builder.exec(call_request).commit(); - let exec_results = builder - .get_last_exec_results() - .expect("should have results"); + 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"); @@ -369,9 +367,7 @@ fn should_not_write_with_forged_uref() { builder.exec(call_request).commit(); - let exec_results = builder - .get_last_exec_results() - .expect("should have results"); + 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"); assert!( @@ -409,9 +405,7 @@ fn should_fail_put_with_invalid_dictionary_item_key() { .build(); builder.exec(call_request).commit(); - let exec_results = builder - .get_last_exec_results() - .expect("should have results"); + 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"); assert!( @@ -448,9 +442,7 @@ fn should_fail_get_with_invalid_dictionary_item_key() { .build(); builder.exec(call_request).commit(); - let exec_results = builder - .get_last_exec_results() - .expect("should have results"); + 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"); assert!( @@ -491,9 +483,7 @@ 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_results() - .expect("should have results"); + 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"); assert!( @@ -534,9 +524,7 @@ 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_results() - .expect("should have results"); + 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"); assert!( @@ -586,13 +574,14 @@ fn should_query_dictionary_items_with_test_builder() { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should have account"); - let contract_hash = default_account + + let entity_hash = default_account .named_keys() .get(dictionary::CONTRACT_HASH_NAME) .expect("should have contract") - .into_hash() - .map(ContractHash::new) + .into_entity_hash() .expect("should have hash"); + let dictionary_uref = default_account .named_keys() .get(dictionary::DICTIONARY_REF) @@ -632,7 +621,7 @@ fn should_query_dictionary_items_with_test_builder() { // Query through contract's named keys let queried_value = query_dictionary_item( &builder, - Key::from(contract_hash), + Key::addressable_entity_key(PackageKindTag::SmartContract, entity_hash), Some(dictionary::DICTIONARY_NAME.to_string()), dictionary::DEFAULT_DICTIONARY_NAME.to_string(), ) 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 8adb64671c..c8b4a7e92a 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,21 +1,19 @@ use num_traits::One; -use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, -}; +use casper_engine_test_support::{LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR}; use casper_execution_engine::engine_state::{Error as CoreError, ExecError, ExecuteRequest}; use casper_types::{ - runtime_args, system::CallStackElement, AddressableEntity, CLValue, ContractHash, - ContractPackageHash, EntryPointType, HashAddr, Key, StoredValue, U512, + system::CallStackElement, AddressableEntity, AddressableEntityHash, CLValue, EntityAddr, + EntryPointType, HashAddr, Key, PackageAddr, PackageHash, StoredValue, Tagged, U512, }; +use crate::lmdb_fixture; + use get_call_stack_recursive_subcall::{ Call, ContractAddress, ARG_CALLS, ARG_CURRENT_DEPTH, METHOD_FORWARDER_CONTRACT_NAME, METHOD_FORWARDER_SESSION_NAME, }; -const CONTRACT_RECURSIVE_SUBCALL: &str = "get_call_stack_recursive_subcall.wasm"; const CONTRACT_CALL_RECURSIVE_SUBCALL: &str = "get_call_stack_call_recursive_subcall.wasm"; const CONTRACT_PACKAGE_NAME: &str = "forwarder"; @@ -24,7 +22,12 @@ const CONTRACT_NAME: &str = "our_contract_name"; const CONTRACT_FORWARDER_ENTRYPOINT_CONTRACT: &str = METHOD_FORWARDER_CONTRACT_NAME; const CONTRACT_FORWARDER_ENTRYPOINT_SESSION: &str = METHOD_FORWARDER_SESSION_NAME; -fn stored_session(contract_hash: ContractHash) -> Call { +const IS_SESSION_ENTRY_POINT: bool = true; +const IS_NOT_SESSION_ENTRY_POINT: bool = false; + +const CALL_STACK_FIXTURE: &str = "call_stack_fixture"; + +fn stored_session(contract_hash: AddressableEntityHash) -> Call { Call { contract_address: ContractAddress::ContractHash(contract_hash), target_method: CONTRACT_FORWARDER_ENTRYPOINT_SESSION.to_string(), @@ -32,7 +35,7 @@ fn stored_session(contract_hash: ContractHash) -> Call { } } -fn stored_versioned_session(contract_package_hash: ContractPackageHash) -> Call { +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(), @@ -40,42 +43,34 @@ fn stored_versioned_session(contract_package_hash: ContractPackageHash) -> Call } } -fn stored_contract(contract_hash: ContractHash) -> Call { +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::Contract, + entry_point_type: EntryPointType::AddressableEntity, } } -fn stored_versioned_contract(contract_package_hash: ContractPackageHash) -> Call { +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::Contract, + entry_point_type: EntryPointType::AddressableEntity, } } -fn store_contract(builder: &mut LmdbWasmTestBuilder, session_filename: &str) { - let store_contract_request = - ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, session_filename, runtime_args! {}) - .build(); - builder - .exec(store_contract_request) - .commit() - .expect_success(); -} - fn execute_and_assert_result( call_depth: usize, builder: &mut LmdbWasmTestBuilder, execute_request: ExecuteRequest, + is_entry_point_type_session: bool, ) { - if call_depth == 0 { + if call_depth == 0 && !is_entry_point_type_session { builder.exec(execute_request).commit().expect_success(); } else { builder.exec(execute_request).commit().expect_failure(); let error = builder.get_error().expect("must have an error"); + assert!(matches!( error, // Call chains have stored contract trying to call stored session which we don't @@ -98,15 +93,25 @@ pub fn approved_amount(idx: usize) -> U512 { } trait AccountExt { - fn get_hash(&self, key: &str) -> HashAddr; + fn get_entity_hash(&self, key: &str) -> EntityAddr; + + fn get_package_hash(&self, key: &str) -> PackageAddr; } impl AccountExt for AddressableEntity { - fn get_hash(&self, key: &str) -> HashAddr { + fn get_entity_hash(&self, key: &str) -> EntityAddr { + self.named_keys() + .get(key) + .cloned() + .and_then(Key::into_entity_addr) + .unwrap() + } + + fn get_package_hash(&self, key: &str) -> PackageAddr { self.named_keys() .get(key) .cloned() - .and_then(Key::into_hash) + .and_then(Key::into_package_addr) .unwrap() } } @@ -150,20 +155,24 @@ impl BuilderExt for LmdbWasmTestBuilder { contract_package_hash: HashAddr, ) -> Vec { let value = self - .query(None, Key::Hash(contract_package_hash), &[]) + .query(None, Key::Package(contract_package_hash), &[]) .unwrap(); let contract_package = match value { - StoredValue::ContractPackage(package) => package, + StoredValue::Package(package) => package, _ => panic!("unreachable"), }; - let current_contract_hash = contract_package.current_contract_hash().unwrap(); + let current_contract_hash = contract_package.current_entity_hash().unwrap(); + let current_contract_entity_key = Key::addressable_entity_key( + contract_package.get_package_kind().tag(), + current_contract_hash, + ); let cl_value = self .query( None, - current_contract_hash.into(), + current_contract_entity_key, &[stored_call_stack_key.to_string()], ) .unwrap(); @@ -177,9 +186,7 @@ impl BuilderExt for LmdbWasmTestBuilder { } fn setup() -> LmdbWasmTestBuilder { - let mut builder = LmdbWasmTestBuilder::default(); - builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - store_contract(&mut builder, CONTRACT_RECURSIVE_SUBCALL); + let (builder, _, _) = lmdb_fixture::builder_from_global_state_fixture(CALL_STACK_FIXTURE); builder } @@ -198,7 +205,7 @@ 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::Contract | EntryPointType::Install => builder + EntryPointType::AddressableEntity | EntryPointType::Factory => builder .get_call_stack_from_contract_context( &stored_call_stack_key, current_contract_package_hash, @@ -244,7 +251,7 @@ fn assert_invalid_context(builder: &mut LmdbWasmTestBuilder, depth: usize) { fn assert_each_context_has_correct_call_stack_info_module_bytes( builder: &mut LmdbWasmTestBuilder, subcalls: Vec, - current_contract_package_hash: HashAddr, + current_contract_package_hash: PackageHash, ) { let stored_call_stack_key = format!("call_stack-{}", 0); let call_stack = builder.get_call_stack_from_session_context(&stored_call_stack_key); @@ -260,10 +267,10 @@ 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::Contract | EntryPointType::Install => builder + EntryPointType::AddressableEntity | EntryPointType::Factory => builder .get_call_stack_from_contract_context( &stored_call_stack_key, - current_contract_package_hash, + current_contract_package_hash.value(), ), EntryPointType::Session => { builder.get_call_stack_from_session_context(&stored_call_stack_key) @@ -292,11 +299,11 @@ fn assert_call_stack_matches_calls(call_stack: Vec, calls: &[C ContractAddress::ContractPackageHash(current_contract_package_hash), .. }), - CallStackElement::StoredContract { - contract_package_hash, + CallStackElement::AddressableEntity { + package_hash: contract_package_hash, .. }, - ) if *entry_point_type == EntryPointType::Contract + ) if *entry_point_type == EntryPointType::AddressableEntity && *contract_package_hash == *current_contract_package_hash => {} // Unversioned Call with EntryPointType::Contract @@ -306,41 +313,11 @@ fn assert_call_stack_matches_calls(call_stack: Vec, calls: &[C contract_address: ContractAddress::ContractHash(current_contract_hash), .. }), - CallStackElement::StoredContract { contract_hash, .. }, - ) if *entry_point_type == EntryPointType::Contract - && *contract_hash == *current_contract_hash => {} - - // Versioned Call with EntryPointType::Session - ( - Some(Call { - entry_point_type, - contract_address: - ContractAddress::ContractPackageHash(current_contract_package_hash), - .. - }), - CallStackElement::StoredSession { - account_hash, - contract_package_hash, - .. - }, - ) if *entry_point_type == EntryPointType::Session - && *account_hash == *DEFAULT_ACCOUNT_ADDR - && *contract_package_hash == *current_contract_package_hash => {} - - // Unversioned Call with EntryPointType::Session - ( - Some(Call { - entry_point_type, - contract_address: ContractAddress::ContractHash(current_contract_hash), - .. - }), - CallStackElement::StoredSession { - account_hash, - contract_hash, + CallStackElement::AddressableEntity { + entity_hash: contract_hash, .. }, - ) if *entry_point_type == EntryPointType::Session - && *account_hash == *DEFAULT_ACCOUNT_ADDR + ) if *entry_point_type == EntryPointType::AddressableEntity && *contract_hash == *current_contract_hash => {} _ => panic!( @@ -354,6 +331,7 @@ fn assert_call_stack_matches_calls(call_stack: Vec, calls: &[C mod session { use casper_engine_test_support::{ExecuteRequestBuilder, DEFAULT_ACCOUNT_ADDR}; use casper_types::{execution::TransformKind, runtime_args, system::mint, Key}; + use num_traits::Zero; use super::{ approved_amount, AccountExt, ARG_CALLS, ARG_CURRENT_DEPTH, CONTRACT_CALL_RECURSIVE_SUBCALL, @@ -375,7 +353,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![super::stored_versioned_contract(current_contract_package_hash.into()); *len]; @@ -396,7 +375,7 @@ mod session { super::assert_each_context_has_correct_call_stack_info_module_bytes( &mut builder, subcalls, - current_contract_package_hash, + current_contract_package_hash.into(), ); } } @@ -409,8 +388,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_contract(current_contract_hash.into()); *len]; @@ -430,7 +410,7 @@ mod session { super::assert_each_context_has_correct_call_stack_info_module_bytes( &mut builder, subcalls, - current_contract_package_hash, + current_contract_package_hash.into(), ); } } @@ -443,8 +423,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ @@ -471,7 +452,7 @@ mod session { super::assert_each_context_has_correct_call_stack_info_module_bytes( &mut builder, subcalls, - current_contract_package_hash, + current_contract_package_hash.into(), ); } } @@ -484,8 +465,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![super::stored_contract(current_contract_hash.into()); len.saturating_sub(1)]; @@ -511,7 +493,7 @@ mod session { super::assert_each_context_has_correct_call_stack_info_module_bytes( &mut builder, subcalls, - current_contract_package_hash, + current_contract_package_hash.into(), ); } } @@ -524,7 +506,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let mut subcalls = vec![ @@ -548,13 +531,20 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + // At current depth with len at 0, the invoked wasm will early exit and + // does not invoke the stored session. Therefore for the first iteration we + // expect successful execution of the module bytes. + if len.is_zero() { + builder.exec(execute_request).expect_success().commit(); + } else { + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info_module_bytes( - &mut builder, - subcalls, - current_contract_package_hash, - ); + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, + ); + + builder.assert_error(expected_error) + } } } @@ -566,8 +556,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ @@ -589,13 +580,20 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + // At current depth with len at 0, the invoked wasm will early exit and + // does not invoke the stored session. Therefore for the first iteration we + // expect successful execution of the module bytes. + if len.is_zero() { + builder.exec(execute_request).expect_success().commit(); + } else { + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info_module_bytes( - &mut builder, - subcalls, - current_contract_package_hash, - ); + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, + ); + + builder.assert_error(expected_error) + } } } @@ -607,8 +605,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![super::stored_session(current_contract_hash.into()); len.saturating_sub(1)]; @@ -629,13 +628,20 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + // At current depth with len at 0, the invoked wasm will early exit and + // does not invoke the stored session. Therefore for the first iteration we + // expect successful execution of the module bytes. + if len.is_zero() { + builder.exec(execute_request).expect_success().commit(); + } else { + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info_module_bytes( - &mut builder, - subcalls, - current_contract_package_hash, - ); + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, + ); + + builder.assert_error(expected_error) + } } } @@ -647,8 +653,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![super::stored_session(current_contract_hash.into()); len.saturating_sub(1)]; @@ -667,13 +673,20 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + // At current depth with len at 0, the invoked wasm will early exit and + // does not invoke the stored session. Therefore for the first iteration we + // expect successful execution of the module bytes. + if len.is_zero() { + builder.exec(execute_request).expect_success().commit(); + } else { + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info_module_bytes( - &mut builder, - subcalls, - current_contract_package_hash, - ); + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, + ); + + builder.assert_error(expected_error) + } } } @@ -685,7 +698,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![super::stored_versioned_session(current_contract_package_hash.into()); *len]; @@ -701,13 +715,20 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + // At current depth with len at 0, the invoked wasm will early exit and + // does not invoke the stored session. Therefore for the first iteration we + // expect successful execution of the module bytes. + if len.is_zero() { + builder.exec(execute_request).expect_success().commit(); + } else { + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info_module_bytes( - &mut builder, - subcalls, - current_contract_package_hash, - ); + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, + ); + + builder.assert_error(expected_error) + } } } @@ -719,8 +740,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ @@ -742,13 +764,20 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + // At current depth with len at 0, the invoked wasm will early exit and + // does not invoke the stored session. Therefore for the first iteration we + // expect successful execution of the module bytes. + if len.is_zero() { + builder.exec(execute_request).expect_success().commit(); + } else { + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info_module_bytes( - &mut builder, - subcalls, - current_contract_package_hash, - ); + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, + ); + + builder.assert_error(expected_error) + } } } @@ -760,8 +789,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![super::stored_session(current_contract_hash.into()); len.saturating_sub(1)]; @@ -782,13 +812,20 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + // At current depth with len at 0, the invoked wasm will early exit and + // does not invoke the stored session. Therefore for the first iteration we + // expect successful execution of the module bytes. + if len.is_zero() { + builder.exec(execute_request).expect_success().commit(); + } else { + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info_module_bytes( - &mut builder, - subcalls, - current_contract_package_hash, - ); + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, + ); + + builder.assert_error(expected_error) + } } } @@ -800,8 +837,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_session(current_contract_hash.into()); *len]; @@ -816,13 +853,20 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + // At current depth with len at 0, the invoked wasm will early exit and + // does not invoke the stored session. Therefore for the first iteration we + // expect successful execution of the module bytes. + if len.is_zero() { + builder.exec(execute_request).expect_success().commit(); + } else { + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info_module_bytes( - &mut builder, - subcalls, - current_contract_package_hash, - ); + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, + ); + + builder.assert_error(expected_error) + } } } @@ -836,7 +880,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let mut subcalls = vec![ @@ -874,8 +919,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ @@ -911,8 +957,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![super::stored_contract(current_contract_hash.into()); len.saturating_sub(1)]; @@ -947,7 +994,7 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![super::stored_contract(current_contract_hash.into()); len.saturating_sub(1)]; @@ -982,7 +1029,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![super::stored_versioned_contract(current_contract_package_hash.into()); *len]; @@ -1019,7 +1067,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![super::stored_versioned_contract(current_contract_package_hash.into()); *len]; @@ -1043,7 +1092,7 @@ mod session { assert!( effects.transforms().iter().any(|transform| transform.key() - == &Key::Hash(current_contract_package_hash) + == &Key::Package(current_contract_package_hash) && transform.kind() == &TransformKind::Identity), "Missing `Identity` transform for a contract package being called." ); @@ -1065,8 +1114,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_contract(current_contract_hash.into()); *len]; @@ -1102,8 +1152,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_contract(current_contract_hash.into()); *len]; @@ -1139,8 +1190,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_versioned_contract(current_contract_package_hash.into()); *len]; @@ -1176,8 +1228,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_versioned_contract(current_contract_package_hash.into()); *len]; @@ -1200,7 +1253,7 @@ mod session { assert!( effects.transforms().iter().any(|transform| transform.key() - == &Key::Hash(current_contract_hash) + == &Key::contract_entity_key(current_contract_hash.into()) && transform.kind() == &TransformKind::Identity), "Missing `Identity` transform for a contract being called." ); @@ -1222,8 +1275,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_contract(current_contract_hash.into()); *len]; @@ -1258,8 +1312,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_contract(current_contract_hash.into()); *len]; @@ -1296,7 +1351,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![super::stored_versioned_session(current_contract_package_hash.into()); *len]; @@ -1328,7 +1384,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![super::stored_versioned_session(current_contract_package_hash.into()); *len]; @@ -1360,7 +1417,7 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_session(current_contract_hash.into()); *len]; @@ -1391,8 +1448,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_session(current_contract_hash.into()); *len]; @@ -1423,7 +1481,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![super::stored_versioned_session(current_contract_package_hash.into()); *len]; @@ -1454,8 +1513,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_versioned_session(current_contract_package_hash.into()); *len]; @@ -1486,7 +1546,7 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_session(current_contract_hash.into()); *len]; @@ -1516,7 +1576,7 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_session(current_contract_hash.into()); *len]; @@ -1547,7 +1607,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let mut subcalls = vec![ @@ -1588,8 +1649,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ @@ -1628,8 +1690,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![super::stored_contract(current_contract_hash.into()); len.saturating_sub(1)]; @@ -1666,8 +1729,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![super::stored_contract(current_contract_hash.into()); len.saturating_sub(1)]; @@ -1703,7 +1767,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let mut subcalls = vec![ @@ -1742,8 +1807,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ @@ -1780,8 +1846,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![super::stored_contract(current_contract_hash.into()); len.saturating_sub(1)]; @@ -1817,7 +1884,7 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![super::stored_contract(current_contract_hash.into()); len.saturating_sub(1)]; @@ -1853,7 +1920,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![super::stored_versioned_session(current_contract_package_hash.into()); *len]; @@ -1871,14 +1939,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info( - &mut builder, - super::stored_versioned_session(current_contract_package_hash.into()), - subcalls, - current_contract_package_hash, + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, ); + + builder.assert_error(expected_error); } } @@ -1890,7 +1957,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![super::stored_versioned_session(current_contract_package_hash.into()); *len]; @@ -1908,14 +1976,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info( - &mut builder, - super::stored_versioned_session(current_contract_package_hash.into()), - subcalls, - current_contract_package_hash, + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, ); + + builder.assert_error(expected_error); } } @@ -1927,8 +1994,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_session(current_contract_hash.into()); *len]; @@ -1945,14 +2012,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info( - &mut builder, - super::stored_versioned_session(current_contract_package_hash.into()), - subcalls, - current_contract_package_hash, + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, ); + + builder.assert_error(expected_error); } } @@ -1964,8 +2030,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_session(current_contract_hash.into()); *len]; @@ -1982,14 +2049,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info( - &mut builder, - super::stored_versioned_session(current_contract_package_hash.into()), - subcalls, - current_contract_package_hash, + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, ); + + builder.assert_error(expected_error); } } @@ -2001,8 +2067,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![super::stored_versioned_session(current_contract_package_hash.into()); *len]; @@ -2019,14 +2085,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info( - &mut builder, - super::stored_session(current_contract_hash.into()), - subcalls, - current_contract_package_hash, + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, ); + + builder.assert_error(expected_error); } } @@ -2038,8 +2103,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_versioned_session(current_contract_package_hash.into()); *len]; @@ -2056,14 +2122,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info( - &mut builder, - super::stored_versioned_session(current_contract_package_hash.into()), - subcalls, - current_contract_package_hash, + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, ); + + builder.assert_error(expected_error); } } @@ -2075,8 +2140,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_session(current_contract_hash.into()); *len]; @@ -2092,14 +2157,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info( - &mut builder, - super::stored_session(current_contract_hash.into()), - subcalls, - current_contract_package_hash, + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, ); + + builder.assert_error(expected_error); } } @@ -2111,8 +2175,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_session(current_contract_hash.into()); *len]; @@ -2128,14 +2192,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info( - &mut builder, - super::stored_session(current_contract_hash.into()), - subcalls, - current_contract_package_hash, + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, ); + + builder.assert_error(expected_error); } } @@ -2147,7 +2210,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![super::stored_versioned_contract(current_contract_package_hash.into()); *len]; @@ -2165,14 +2229,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info( - &mut builder, - super::stored_versioned_session(current_contract_package_hash.into()), - subcalls, - current_contract_package_hash, + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, ); + + builder.assert_error(expected_error); } } @@ -2184,7 +2247,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![super::stored_versioned_contract(current_contract_package_hash.into()); *len]; @@ -2202,14 +2266,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info( - &mut builder, - super::stored_versioned_session(current_contract_package_hash.into()), - subcalls, - current_contract_package_hash, + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, ); + + builder.assert_error(expected_error); } } @@ -2221,8 +2284,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_contract(current_contract_hash.into()); *len]; @@ -2239,14 +2302,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info( - &mut builder, - super::stored_versioned_session(current_contract_package_hash.into()), - subcalls, - current_contract_package_hash, + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, ); + + builder.assert_error(expected_error); } } @@ -2258,8 +2320,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_contract(current_contract_hash.into()); *len]; @@ -2276,14 +2339,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info( - &mut builder, - super::stored_versioned_session(current_contract_package_hash.into()), - subcalls, - current_contract_package_hash, + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, ); + + builder.assert_error(expected_error); } } @@ -2295,8 +2357,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![super::stored_versioned_contract(current_contract_package_hash.into()); *len]; @@ -2313,14 +2375,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info( - &mut builder, - super::stored_session(current_contract_hash.into()), - subcalls, - current_contract_package_hash, + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, ); + + builder.assert_error(expected_error); } } @@ -2332,8 +2393,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_versioned_contract(current_contract_package_hash.into()); *len]; @@ -2350,14 +2412,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info( - &mut builder, - super::stored_session(current_contract_hash.into()), - subcalls, - current_contract_package_hash, + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, ); + + builder.assert_error(expected_error); } } @@ -2369,8 +2430,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_contract(current_contract_hash.into()); *len]; @@ -2386,14 +2447,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info( - &mut builder, - super::stored_session(current_contract_hash.into()), - subcalls, - current_contract_package_hash, + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, ); + + builder.assert_error(expected_error); } } @@ -2405,8 +2465,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_contract(current_contract_hash.into()); *len]; @@ -2422,14 +2482,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit().expect_success(); + builder.exec(execute_request).expect_failure(); - super::assert_each_context_has_correct_call_stack_info( - &mut builder, - super::stored_session(current_contract_hash.into()), - subcalls, - current_contract_package_hash, + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, ); + + builder.assert_error(expected_error); } } @@ -2444,7 +2503,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let mut subcalls = vec![ @@ -2470,9 +2530,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit(); + builder.exec(execute_request).expect_failure(); - super::assert_invalid_context(&mut builder, *len); + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, + ); + + builder.assert_error(expected_error); } } @@ -2485,8 +2549,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ @@ -2510,9 +2575,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit(); + builder.exec(execute_request).expect_failure(); - super::assert_invalid_context(&mut builder, *len); + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, + ); + + builder.assert_error(expected_error); } } @@ -2525,8 +2594,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![super::stored_contract(current_contract_hash.into()); len.saturating_sub(1)]; @@ -2549,9 +2619,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit(); + builder.exec(execute_request).expect_failure(); - super::assert_invalid_context(&mut builder, *len); + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, + ); + + builder.assert_error(expected_error); } } @@ -2563,8 +2637,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![super::stored_contract(current_contract_hash.into()); len.saturating_sub(1)]; @@ -2585,9 +2660,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit(); + builder.exec(execute_request).expect_failure(); - super::assert_invalid_context(&mut builder, *len); + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, + ); + + builder.assert_error(expected_error); } } @@ -2600,7 +2679,8 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let mut subcalls = vec![ @@ -2625,9 +2705,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit(); + builder.exec(execute_request).expect_failure(); - super::assert_invalid_context(&mut builder, *len); + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, + ); + + builder.assert_error(expected_error); } } @@ -2639,8 +2723,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ @@ -2663,9 +2748,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit(); + builder.exec(execute_request).expect_failure(); - super::assert_invalid_context(&mut builder, *len); + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, + ); + + builder.assert_error(expected_error); } } @@ -2677,8 +2766,9 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![super::stored_contract(current_contract_hash.into()); len.saturating_sub(1)]; @@ -2700,9 +2790,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit(); + builder.exec(execute_request).expect_failure(); - super::assert_invalid_context(&mut builder, *len); + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, + ); + + builder.assert_error(expected_error); } } @@ -2714,7 +2808,7 @@ mod session { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![super::stored_contract(current_contract_hash.into()); len.saturating_sub(1)]; @@ -2734,9 +2828,13 @@ mod session { ) .build(); - builder.exec(execute_request).commit(); + builder.exec(execute_request).expect_failure(); - super::assert_invalid_context(&mut builder, *len); + let expected_error = casper_execution_engine::engine_state::Error::Exec( + casper_execution_engine::execution::Error::InvalidContext, + ); + + builder.assert_error(expected_error); } } } @@ -2744,6 +2842,9 @@ mod session { mod payment { use rand::Rng; + use crate::test::contract_api::get_call_stack::{ + IS_NOT_SESSION_ENTRY_POINT, IS_SESSION_ENTRY_POINT, + }; use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, }; @@ -2781,7 +2882,12 @@ mod payment { ExecuteRequestBuilder::new().push_deploy(deploy).build() }; - super::execute_and_assert_result(call_depth, builder, execute_request); + super::execute_and_assert_result( + call_depth, + builder, + execute_request, + IS_NOT_SESSION_ENTRY_POINT, + ); } fn execute_stored_payment_by_package_name( @@ -2817,7 +2923,12 @@ mod payment { ExecuteRequestBuilder::new().push_deploy(deploy).build() }; - super::execute_and_assert_result(call_depth, builder, execute_request); + super::execute_and_assert_result( + call_depth, + builder, + execute_request, + IS_SESSION_ENTRY_POINT, + ); } fn execute_stored_payment_by_package_hash( @@ -2850,7 +2961,12 @@ mod payment { ExecuteRequestBuilder::new().push_deploy(deploy).build() }; - super::execute_and_assert_result(call_depth, builder, execute_request); + super::execute_and_assert_result( + call_depth, + builder, + execute_request, + IS_SESSION_ENTRY_POINT, + ); } fn execute_stored_payment_by_contract_name( @@ -2885,7 +3001,12 @@ mod payment { ExecuteRequestBuilder::new().push_deploy(deploy).build() }; - super::execute_and_assert_result(call_depth, builder, execute_request); + super::execute_and_assert_result( + call_depth, + builder, + execute_request, + IS_SESSION_ENTRY_POINT, + ); } fn execute_stored_payment_by_contract_hash( @@ -2917,7 +3038,14 @@ mod payment { ExecuteRequestBuilder::new().push_deploy(deploy).build() }; - super::execute_and_assert_result(call_depth, builder, execute_request); + let is_entry_point_type_session = true; + + super::execute_and_assert_result( + call_depth, + builder, + execute_request, + is_entry_point_type_session, + ); } // Session + recursive subcall @@ -2930,7 +3058,8 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let mut subcalls = vec![ @@ -2955,8 +3084,9 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ @@ -2979,8 +3109,9 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ super::stored_session(current_contract_hash.into()); @@ -3007,7 +3138,7 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![ super::stored_contract(current_contract_hash.into()), @@ -3024,7 +3155,7 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![ super::stored_session(current_contract_hash.into()), @@ -3043,7 +3174,8 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let mut subcalls = vec![ @@ -3068,8 +3200,9 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ @@ -3092,8 +3225,9 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ super::stored_contract(current_contract_hash.into()); @@ -3117,7 +3251,7 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ super::stored_contract(current_contract_hash.into()); @@ -3141,7 +3275,8 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![ @@ -3161,7 +3296,8 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![ @@ -3186,7 +3322,7 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_session(current_contract_hash.into()); *call_depth]; @@ -3202,8 +3338,9 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_session(current_contract_hash.into()); *call_depth]; @@ -3224,7 +3361,8 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![ @@ -3244,8 +3382,9 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![ @@ -3270,7 +3409,7 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_session(current_contract_hash.into()); *call_depth]; @@ -3286,7 +3425,7 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_session(current_contract_hash.into()); *call_depth]; @@ -3307,7 +3446,8 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![ @@ -3327,7 +3467,8 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![ @@ -3352,7 +3493,7 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_contract(current_contract_hash.into()); *call_depth]; @@ -3368,8 +3509,9 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_contract(current_contract_hash.into()); *call_depth]; @@ -3390,7 +3532,8 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let subcalls = vec![ @@ -3410,8 +3553,9 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![ @@ -3436,7 +3580,7 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_contract(current_contract_hash.into()); *call_depth]; @@ -3452,7 +3596,7 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let subcalls = vec![super::stored_contract(current_contract_hash.into()); *call_depth]; @@ -3476,7 +3620,8 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let mut subcalls = vec![ @@ -3502,8 +3647,9 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ @@ -3532,8 +3678,9 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ super::stored_contract(current_contract_hash.into()); @@ -3557,8 +3704,9 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ super::stored_contract(current_contract_hash.into()); @@ -3586,7 +3734,8 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); let mut subcalls = vec![ @@ -3611,8 +3760,9 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ @@ -3640,8 +3790,9 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_package_hash = default_account.get_hash(CONTRACT_PACKAGE_NAME); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_package_hash = + default_account.get_package_hash(CONTRACT_PACKAGE_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ super::stored_contract(current_contract_hash.into()); @@ -3665,7 +3816,7 @@ mod payment { let default_account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let current_contract_hash = default_account.get_hash(CONTRACT_NAME); + let current_contract_hash = default_account.get_entity_hash(CONTRACT_NAME); let mut subcalls = vec![ super::stored_contract(current_contract_hash.into()); 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 84390178d4..c3f4e980b8 100644 --- a/execution_engine_testing/tests/src/test/contract_api/subcall.rs +++ b/execution_engine_testing/tests/src/test/contract_api/subcall.rs @@ -5,7 +5,7 @@ use casper_engine_test_support::{ PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_types::{ - package::CONTRACT_INITIAL_VERSION, runtime_args, RuntimeArgs, StorageCosts, U512, + package::ENTITY_INITIAL_VERSION, runtime_args, RuntimeArgs, StorageCosts, U512, }; const ARG_TARGET: &str = "target_contract"; @@ -207,7 +207,7 @@ fn expensive_subcall_should_cost_more() { .named_keys() .get(EXPENSIVE_CALCULATION_KEY) .expect("should get expensive_calculation contract hash") - .into_hash() + .into_entity_hash() .expect("should get hash"); // execute the contracts via subcalls @@ -215,7 +215,7 @@ fn expensive_subcall_should_cost_more() { let call_do_nothing_request = ExecuteRequestBuilder::versioned_contract_call_by_name( *DEFAULT_ACCOUNT_ADDR, DO_NOTHING_PACKAGE_HASH_KEY_NAME, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), ENTRY_FUNCTION_NAME, RuntimeArgs::new(), ) @@ -223,7 +223,7 @@ fn expensive_subcall_should_cost_more() { let call_expensive_calculation_request = ExecuteRequestBuilder::contract_call_by_hash( *DEFAULT_ACCOUNT_ADDR, - expensive_calculation_contract_hash.into(), + expensive_calculation_contract_hash, "calculate", RuntimeArgs::default(), ) diff --git a/execution_engine_testing/tests/src/test/contract_context.rs b/execution_engine_testing/tests/src/test/contract_context.rs index 2e74ffa9ce..a03cee9454 100644 --- a/execution_engine_testing/tests/src/test/contract_context.rs +++ b/execution_engine_testing/tests/src/test/contract_context.rs @@ -1,21 +1,19 @@ -use assert_matches::assert_matches; use casper_engine_test_support::{ - DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, + PRODUCTION_RUN_GENESIS_REQUEST, }; -use casper_execution_engine::{engine_state::Error, execution}; -use casper_types::{package::CONTRACT_INITIAL_VERSION, runtime_args, Key, RuntimeArgs}; + +use casper_types::{package::ENTITY_INITIAL_VERSION, runtime_args, Key, RuntimeArgs}; const CONTRACT_HEADERS: &str = "contract_context.wasm"; const PACKAGE_HASH_KEY: &str = "package_hash_key"; const PACKAGE_ACCESS_KEY: &str = "package_access_key"; const CONTRACT_HASH_KEY: &str = "contract_hash_key"; -const SESSION_CODE_TEST: &str = "session_code_test"; + const CONTRACT_CODE_TEST: &str = "contract_code_test"; -const ADD_NEW_KEY_AS_SESSION: &str = "add_new_key_as_session"; + const NEW_KEY: &str = "new_key"; -const SESSION_CODE_CALLER_AS_CONTRACT: &str = "session_code_caller_as_contract"; -const ARG_AMOUNT: &str = "amount"; + const CONTRACT_VERSION: &str = "contract_version"; #[ignore] @@ -29,71 +27,23 @@ fn should_enforce_intended_execution_contexts() { ) .build(); - let exec_request_2 = { - let args = runtime_args! {}; - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_contract_by_name( - PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), - SESSION_CODE_TEST, - args, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::new().push_deploy(deploy).build() - }; - - let exec_request_3 = { - let args = runtime_args! {}; - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_contract_by_name( - PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), - CONTRACT_CODE_TEST, - args, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::new().push_deploy(deploy).build() - }; - - let exec_request_4 = { - let args = runtime_args! {}; - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_contract_by_name( - PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), - ADD_NEW_KEY_AS_SESSION, - args, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([4; 32]) - .build(); - - ExecuteRequestBuilder::new().push_deploy(deploy).build() - }; + let exec_request_3 = ExecuteRequestBuilder::versioned_contract_call_by_name( + *DEFAULT_ACCOUNT_ADDR, + PACKAGE_HASH_KEY, + Some(ENTITY_INITIAL_VERSION), + CONTRACT_CODE_TEST, + runtime_args! {}, + ) + .build(); + let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); builder.exec(exec_request_1).expect_success().commit(); - builder.exec(exec_request_2).expect_success().commit(); - builder.exec(exec_request_3).expect_success().commit(); - builder.exec(exec_request_4).expect_success().commit(); - let account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("must have contract"); @@ -107,10 +57,7 @@ fn should_enforce_intended_execution_contexts() { .get(PACKAGE_ACCESS_KEY) .expect("should have package hash"); - let _new_key = account - .named_keys() - .get(NEW_KEY) - .expect("new key should be there"); + assert!(account.named_keys().get(NEW_KEY).is_none()); // Check version @@ -138,56 +85,22 @@ fn should_enforce_intended_execution_context_direct_by_name() { ) .build(); - let exec_request_2 = { - let args = runtime_args! {}; - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_session_named_key(CONTRACT_HASH_KEY, SESSION_CODE_TEST, args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::new().push_deploy(deploy).build() - }; - - let exec_request_3 = { - let args = runtime_args! {}; - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_session_named_key(CONTRACT_HASH_KEY, CONTRACT_CODE_TEST, args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::new().push_deploy(deploy).build() - }; - - let exec_request_4 = { - let args = runtime_args! {}; - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_session_named_key(CONTRACT_HASH_KEY, ADD_NEW_KEY_AS_SESSION, args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([4; 32]) - .build(); - - ExecuteRequestBuilder::new().push_deploy(deploy).build() - }; + let exec_request_3 = ExecuteRequestBuilder::contract_call_by_name( + *DEFAULT_ACCOUNT_ADDR, + CONTRACT_HASH_KEY, + CONTRACT_CODE_TEST, + runtime_args! {}, + ) + .build(); + let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); builder.exec(exec_request_1).expect_success().commit(); - builder.exec(exec_request_2).expect_success().commit(); - builder.exec(exec_request_3).expect_success().commit(); - builder.exec(exec_request_4).expect_success().commit(); - let account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("must have contract"); @@ -201,10 +114,7 @@ fn should_enforce_intended_execution_context_direct_by_name() { .get(PACKAGE_ACCESS_KEY) .expect("should have package hash"); - let _new_key = account - .named_keys() - .get(NEW_KEY) - .expect("new key should be there"); + assert!(account.named_keys().get(NEW_KEY).is_none()); } #[ignore] @@ -232,53 +142,19 @@ fn should_enforce_intended_execution_context_direct_by_hash() { .named_keys() .get(CONTRACT_HASH_KEY) .expect("should have contract hash") - .into_hash() - .expect("should have hash"); - - let exec_request_2 = { - let args = runtime_args! {}; - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_session_hash(contract_hash.into(), SESSION_CODE_TEST, args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::new().push_deploy(deploy).build() - }; - - let exec_request_3 = { - let args = runtime_args! {}; - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_session_hash(contract_hash.into(), CONTRACT_CODE_TEST, args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([3; 32]) - .build(); - - ExecuteRequestBuilder::new().push_deploy(deploy).build() - }; - - let exec_request_4 = { - let args = runtime_args! {}; - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_session_hash(contract_hash.into(), ADD_NEW_KEY_AS_SESSION, args) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([4; 32]) - .build(); - - ExecuteRequestBuilder::new().push_deploy(deploy).build() - }; - - builder.exec(exec_request_2).expect_success().commit(); + .into_entity_hash(); - builder.exec(exec_request_3).expect_success().commit(); + let contract_hash = contract_hash.unwrap(); - builder.exec(exec_request_4).expect_success().commit(); + let exec_request_3 = ExecuteRequestBuilder::contract_call_by_hash( + *DEFAULT_ACCOUNT_ADDR, + contract_hash, + CONTRACT_CODE_TEST, + runtime_args! {}, + ) + .build(); + + builder.exec(exec_request_3).expect_success().commit(); let account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -293,66 +169,5 @@ fn should_enforce_intended_execution_context_direct_by_hash() { .get(PACKAGE_ACCESS_KEY) .expect("should have package hash"); - let _new_key = account - .named_keys() - .get(NEW_KEY) - .expect("new key should be there"); -} - -#[ignore] -#[test] -fn should_not_call_session_from_contract() { - // This test runs a contract that extends the same key with more data after every call. - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_HEADERS, - RuntimeArgs::default(), - ) - .build(); - - let mut builder = LmdbWasmTestBuilder::default(); - - builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - - builder.exec(exec_request_1).expect_success().commit(); - - let account = builder - .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) - .expect("should have default account"); - - let contract_package_hash = account - .named_keys() - .get(PACKAGE_HASH_KEY) - .cloned() - .expect("should have contract package"); - - let exec_request_2 = { - let args = runtime_args! { - PACKAGE_HASH_KEY => contract_package_hash, - }; - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_contract_by_name( - PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), - SESSION_CODE_CALLER_AS_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::new().push_deploy(deploy).build() - }; - - builder.exec(exec_request_2).commit(); - - let response = builder - .get_last_exec_results() - .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"); - assert_matches!(error, Error::Exec(execution::Error::InvalidContext)); + assert!(account.named_keys().get(NEW_KEY).is_none()) } diff --git a/execution_engine_testing/tests/src/test/counter_factory.rs b/execution_engine_testing/tests/src/test/counter_factory.rs index 0d6637ae88..667fc04bd9 100644 --- a/execution_engine_testing/tests/src/test/counter_factory.rs +++ b/execution_engine_testing/tests/src/test/counter_factory.rs @@ -7,7 +7,8 @@ use casper_engine_test_support::{ }; use casper_execution_engine::{engine_state::Error, execution}; use casper_types::{ - addressable_entity::DEFAULT_ENTRY_POINT_NAME, runtime_args, ContractHash, RuntimeArgs, U512, + addressable_entity::DEFAULT_ENTRY_POINT_NAME, package::PackageKindTag, runtime_args, + AddressableEntityHash, ByteCodeKind, Key, RuntimeArgs, U512, }; const CONTRACT_COUNTER_FACTORY: &str = "counter_factory.wasm"; @@ -87,17 +88,25 @@ fn should_not_call_undefined_entrypoints_on_factory() { fn contract_factory_wasm_should_have_expected_exports() { let (builder, contract_hash) = setup(); + let factory_contract_entity_key = + Key::addressable_entity_key(PackageKindTag::SmartContract, contract_hash); + let factory_contract = builder - .query(None, contract_hash.into(), &[]) + .query(None, factory_contract_entity_key, &[]) .expect("should have contract") .as_addressable_entity() .cloned() .expect("should be contract"); + let factory_contract_byte_code_key = Key::byte_code_key( + ByteCodeKind::V1CasperWasm, + factory_contract.byte_code_addr(), + ); + let factory_contract_wasm = builder - .query(None, factory_contract.contract_wasm_key(), &[]) + .query(None, factory_contract_byte_code_key, &[]) .expect("should have contract wasm") - .as_contract_wasm() + .as_byte_code() .cloned() .expect("should have wasm"); @@ -151,7 +160,7 @@ fn should_install_and_use_factory_pattern() { .named_keys() .get(NEW_COUNTER_1_NAME) .expect("new counter should exist") - .into_contract_hash() + .into_entity_hash() .unwrap(); let new_counter_1_contract = builder @@ -162,7 +171,7 @@ fn should_install_and_use_factory_pattern() { .named_keys() .get(NEW_COUNTER_2_NAME) .expect("new counter should exist") - .into_contract_hash() + .into_entity_hash() .unwrap(); let _new_counter_2_contract = builder @@ -170,9 +179,16 @@ fn should_install_and_use_factory_pattern() { .expect("should have contract instance"); let counter_1_wasm = builder - .query(None, new_counter_1_contract.contract_wasm_key(), &[]) + .query( + None, + Key::byte_code_key( + ByteCodeKind::V1CasperWasm, + new_counter_1_contract.byte_code_addr(), + ), + &[], + ) .expect("should have contract wasm") - .as_contract_wasm() + .as_byte_code() .cloned() .expect("should have wasm"); @@ -206,7 +222,7 @@ fn should_install_and_use_factory_pattern() { builder.exec(decrement_request).commit().expect_success(); } -fn setup() -> (LmdbWasmTestBuilder, ContractHash) { +fn setup() -> (LmdbWasmTestBuilder, AddressableEntityHash) { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); @@ -219,16 +235,14 @@ fn setup() -> (LmdbWasmTestBuilder, ContractHash) { builder.exec(exec_request).commit().expect_success(); - let account_entity_hash = builder - .get_contract_hash_by_account_hash(*DEFAULT_ACCOUNT_ADDR) - .expect("should have account"); let account = builder - .get_addressable_entity(account_entity_hash) + .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should have entity for account"); + let contract_hash_key = account .named_keys() .get("factory_hash") .expect("should have factory hash"); - (builder, contract_hash_key.into_contract_hash().unwrap()) + (builder, contract_hash_key.into_entity_hash().unwrap()) } 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 c1f1a7bb47..64637b5b29 100644 --- a/execution_engine_testing/tests/src/test/deploy/context_association.rs +++ b/execution_engine_testing/tests/src/test/deploy/context_association.rs @@ -52,7 +52,7 @@ fn should_put_system_contract_hashes_to_account_context() { named_keys .get(MINT) .unwrap() - .into_hash() + .into_entity_addr() .expect("should be a hash"), builder.get_mint_contract_hash().value(), "mint_contract_hash should match" @@ -61,7 +61,7 @@ fn should_put_system_contract_hashes_to_account_context() { named_keys .get(HANDLE_PAYMENT) .unwrap() - .into_hash() + .into_entity_addr() .expect("should be a hash"), builder.get_handle_payment_contract_hash().value(), "handle_payment_contract_hash should match" @@ -70,7 +70,7 @@ fn should_put_system_contract_hashes_to_account_context() { named_keys .get(AUCTION) .unwrap() - .into_hash() + .into_entity_addr() .expect("should be a hash"), builder.get_auction_contract_hash().value(), "auction_contract_hash should match" diff --git a/execution_engine_testing/tests/src/test/deploy/receipts.rs b/execution_engine_testing/tests/src/test/deploy/receipts.rs index 0045a3a3e2..e73f926bd7 100644 --- a/execution_engine_testing/tests/src/test/deploy/receipts.rs +++ b/execution_engine_testing/tests/src/test/deploy/receipts.rs @@ -7,9 +7,8 @@ use casper_engine_test_support::{ PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_types::{ - account::AccountHash, runtime_args, system::mint, AccessRights, AddressableEntity, - ContractHash, DeployHash, PublicKey, SecretKey, Transfer, TransferAddr, - DEFAULT_WASMLESS_TRANSFER_COST, U512, + account::AccountHash, runtime_args, system::mint, AccessRights, AddressableEntity, DeployHash, + PublicKey, SecretKey, Transfer, TransferAddr, DEFAULT_WASMLESS_TRANSFER_COST, U512, }; const CONTRACT_TRANSFER_PURSE_TO_ACCOUNT: &str = "transfer_purse_to_account.wasm"; @@ -436,16 +435,15 @@ fn should_record_wasm_transfers_with_subcall() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should have default account"); - let contract_hash = default_account + let entity_hash = default_account .named_keys() .get(HASH_KEY_NAME) .unwrap() - .into_hash() - .map(ContractHash::new) + .into_entity_hash() .expect("should have contract hash"); let contract: AddressableEntity = builder - .get_addressable_entity(contract_hash) + .get_addressable_entity(entity_hash) .expect("should have stored contract"); let contract_purse = contract 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 807ba51b5b..c55a6777b5 100644 --- a/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs +++ b/execution_engine_testing/tests/src/test/deploy/stored_contracts.rs @@ -1,18 +1,15 @@ +use assert_matches::assert_matches; use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_INITIAL_BALANCE, DEFAULT_ACCOUNT_KEY, DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, }; -use casper_execution_engine::{ - engine_state::{self, Error}, - execution, -}; +use casper_execution_engine::{engine_state::Error, execution}; use casper_types::{ account::AccountHash, - package::{ContractVersion, CONTRACT_INITIAL_VERSION}, - runtime_args, - system::mint, - AddressableEntity, ApiError, ContractHash, EraId, ProtocolVersion, RuntimeArgs, U512, + package::{EntityVersion, ENTITY_INITIAL_VERSION}, + runtime_args, AddressableEntity, EntityVersionKey, EraId, PackageHash, ProtocolVersion, + RuntimeArgs, U512, }; const ACCOUNT_1_ADDR: AccountHash = AccountHash::new([42u8; 32]); @@ -20,7 +17,7 @@ const DEFAULT_ACTIVATION_POINT: EraId = EraId::new(1); const DO_NOTHING_NAME: &str = "do_nothing"; const DO_NOTHING_CONTRACT_PACKAGE_HASH_NAME: &str = "do_nothing_package_hash"; const DO_NOTHING_CONTRACT_HASH_NAME: &str = "do_nothing_hash"; -const INITIAL_VERSION: ContractVersion = CONTRACT_INITIAL_VERSION; +const INITIAL_VERSION: EntityVersion = ENTITY_INITIAL_VERSION; const ENTRY_FUNCTION_NAME: &str = "delegate"; const PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::V1_0_0; const STORED_PAYMENT_CONTRACT_NAME: &str = "test_payment_stored.wasm"; @@ -28,12 +25,6 @@ const STORED_PAYMENT_CONTRACT_HASH_NAME: &str = "test_payment_hash"; const STORED_PAYMENT_CONTRACT_PACKAGE_HASH_NAME: &str = "test_payment_package_hash"; const PAY_ENTRYPOINT: &str = "pay"; const TRANSFER_PURSE_TO_ACCOUNT_CONTRACT_NAME: &str = "transfer_purse_to_account"; -// Currently Error enum that holds this variant is private and can't be used otherwise to compare -// message -const EXPECTED_ERROR_MESSAGE: &str = "IncompatibleProtocolMajorVersion { expected: 2, actual: 1 }"; -const EXPECTED_VERSION_ERROR_MESSAGE: &str = - "InvalidContractVersion(ContractVersionKey { protocol_version_major: 2, contract_version: 1 })"; -const EXPECTED_MISSING_ENTRY_POINT_MESSAGE: &str = "NoSuchMethod"; const ARG_TARGET: &str = "target"; const ARG_AMOUNT: &str = "amount"; @@ -46,9 +37,9 @@ fn make_upgrade_request(new_protocol_version: ProtocolVersion) -> UpgradeRequest .with_activation_point(DEFAULT_ACTIVATION_POINT) } -fn store_payment_to_account_context( +fn install_custom_payment( builder: &mut LmdbWasmTestBuilder, -) -> (AddressableEntity, ContractHash) { +) -> (AddressableEntity, PackageHash, U512) { // store payment contract let exec_request = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -64,15 +55,16 @@ fn store_payment_to_account_context( .expect("should have account"); // check account named keys - let hash = default_account + let package_hash = default_account .named_keys() .get(STORED_PAYMENT_CONTRACT_PACKAGE_HASH_NAME) .expect("key should exist") - .into_hash() - .expect("should be a hash") - .into(); + .into_package_hash() + .expect("should be a hash"); + + let exec_cost = builder.last_exec_result().cost().value(); - (default_account, hash) + (default_account, package_hash, exec_cost) } #[ignore] @@ -159,7 +151,7 @@ fn should_fail_if_calling_non_existent_entry_point() { .named_keys() .get(STORED_PAYMENT_CONTRACT_HASH_NAME) .expect("should have standard_payment named key") - .into_hash() + .into_entity_addr() .expect("standard_payment should be an uref"); // next make another deploy that attempts to use the stored payment logic @@ -187,60 +179,73 @@ fn should_fail_if_calling_non_existent_entry_point() { "calling a non-existent entry point should not work" ); - let error_message = builder - .exec_error_message(1) - .expect("should have exec error"); - assert!(error_message.contains(EXPECTED_MISSING_ENTRY_POINT_MESSAGE)); + let expected_error = Error::Exec(execution::Error::NoSuchMethod( + "electric-boogaloo".to_string(), + )); + + builder.assert_error(expected_error); } #[ignore] #[test] fn should_exec_stored_code_by_hash() { - let payment_purse_amount = *DEFAULT_PAYMENT; + let default_payment = *DEFAULT_PAYMENT; // genesis let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); // store payment - let proposer_reward_starting_balance_alpha = builder.get_proposer_purse_balance(); - let (default_account, hash) = store_payment_to_account_context(&mut builder); + let proposer_initial_balance = builder.get_proposer_purse_balance(); + + let (sending_account, custom_payment_package_hash, _) = install_custom_payment(&mut builder); // verify stored contract functions as expected by checking all the maths - let (motes_alpha, modified_balance_alpha) = { - // get modified balance - let modified_balance_alpha: U512 = builder.get_purse_balance(default_account.main_purse()); + let proposer_balance_post_installation = builder.get_proposer_purse_balance(); - let transaction_fee_alpha = - builder.get_proposer_purse_balance() - proposer_reward_starting_balance_alpha; - (transaction_fee_alpha, modified_balance_alpha) - }; + let sending_account_balance: U512 = builder.get_purse_balance(sending_account.main_purse()); - let transferred_amount = 1; + let initial_balance: U512 = U512::from(DEFAULT_ACCOUNT_INITIAL_BALANCE); - // next make another deploy that USES stored payment logic + assert!( + sending_account_balance < initial_balance, + "balance should be less than initial balance" + ); + + assert_eq!( + proposer_balance_post_installation, + proposer_initial_balance + default_payment, + "the full payment goes to the proposer, as configured" + ); - let proposer_reward_starting_balance_bravo = builder.get_proposer_purse_balance(); + assert_eq!( + sending_account_balance, + initial_balance - default_payment, + "current balance = initial balance - default_payment" + ); + + let transferred_amount = U512::one(); + + // next make another deploy that USES stored payment logic { - let exec_request_stored_payment = { - let account_1_account_hash = ACCOUNT_1_ADDR; + let transfer_using_stored_payment = { let deploy = 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_stored_versioned_payment_contract_by_hash( - hash.value(), - Some(CONTRACT_INITIAL_VERSION), + custom_payment_package_hash.value(), + Some(ENTITY_INITIAL_VERSION), PAY_ENTRYPOINT, runtime_args! { - ARG_AMOUNT => payment_purse_amount, + 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(); @@ -248,36 +253,12 @@ fn should_exec_stored_code_by_hash() { ExecuteRequestBuilder::new().push_deploy(deploy).build() }; - builder.exec(exec_request_stored_payment).commit(); + builder.exec(transfer_using_stored_payment).expect_failure(); } - let (motes_bravo, modified_balance_bravo) = { - let modified_balance_bravo: U512 = builder.get_purse_balance(default_account.main_purse()); - - let transaction_fee_bravo = - builder.get_proposer_purse_balance() - proposer_reward_starting_balance_bravo; - - (transaction_fee_bravo, modified_balance_bravo) - }; - - let initial_balance: U512 = U512::from(DEFAULT_ACCOUNT_INITIAL_BALANCE); + let error = builder.get_error().unwrap(); - assert!( - modified_balance_alpha < initial_balance, - "balance should be less than initial balance" - ); - - assert!( - modified_balance_bravo < modified_balance_alpha, - "second modified balance should be less than first modified balance" - ); - - let tally = motes_alpha + motes_bravo + U512::from(transferred_amount) + modified_balance_bravo; - - assert_eq!( - initial_balance, tally, - "no net resources should be gained or lost post-distribution" - ); + assert_matches!(error, Error::Exec(execution::Error::ForgedReference(_))) } #[ignore] @@ -290,7 +271,7 @@ fn should_not_transfer_above_balance_using_stored_payment_code_by_hash() { builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); // store payment - let (default_account, hash) = store_payment_to_account_context(&mut builder); + let (default_account, hash, _) = install_custom_payment(&mut builder); let starting_balance = builder.get_purse_balance(default_account.main_purse()); let transferred_amount = starting_balance - *DEFAULT_PAYMENT + U512::one(); @@ -305,7 +286,7 @@ fn should_not_transfer_above_balance_using_stored_payment_code_by_hash() { ) .with_stored_versioned_payment_contract_by_hash( hash.value(), - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), PAY_ENTRYPOINT, runtime_args! { ARG_AMOUNT => payment_purse_amount, @@ -323,17 +304,9 @@ fn should_not_transfer_above_balance_using_stored_payment_code_by_hash() { .expect_failure() .commit(); - let error = builder.get_error().expect("should have error"); + let error = builder.get_error().unwrap(); - assert!( - matches!( - error, - engine_state::Error::Exec(execution::Error::Revert(ApiError::Mint(mint_error))) - if mint_error == mint::Error::InsufficientFunds as u8, - ), - "Error received {:?}", - error, - ); + assert_matches!(error, Error::Exec(execution::Error::ForgedReference(_))) } #[ignore] @@ -346,27 +319,14 @@ fn should_empty_account_using_stored_payment_code_by_hash() { builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); // store payment - let proposer_reward_starting_balance_alpha = builder.get_proposer_purse_balance(); - let (default_account, hash) = store_payment_to_account_context(&mut builder); + let (default_account, hash, _) = install_custom_payment(&mut builder); let starting_balance = builder.get_purse_balance(default_account.main_purse()); // verify stored contract functions as expected by checking all the maths - let (motes_alpha, modified_balance_alpha) = { - // get modified balance - let modified_balance_alpha: U512 = builder.get_purse_balance(default_account.main_purse()); - - let transaction_fee_alpha = - builder.get_proposer_purse_balance() - proposer_reward_starting_balance_alpha; - (transaction_fee_alpha, modified_balance_alpha) - }; - let transferred_amount = starting_balance - *DEFAULT_PAYMENT; - // next make another deploy that USES stored payment logic - let proposer_reward_starting_balance_bravo = builder.get_proposer_purse_balance(); - { let exec_request_stored_payment = { let account_1_account_hash = ACCOUNT_1_ADDR; @@ -378,7 +338,7 @@ fn should_empty_account_using_stored_payment_code_by_hash() { ) .with_stored_versioned_payment_contract_by_hash( hash.value(), - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), PAY_ENTRYPOINT, runtime_args! { ARG_AMOUNT => payment_purse_amount, @@ -391,44 +351,12 @@ fn should_empty_account_using_stored_payment_code_by_hash() { ExecuteRequestBuilder::new().push_deploy(deploy).build() }; - builder - .exec(exec_request_stored_payment) - .expect_success() - .commit(); + builder.exec(exec_request_stored_payment).expect_failure(); } - let (motes_bravo, modified_balance_bravo) = { - let modified_balance_bravo: U512 = builder.get_purse_balance(default_account.main_purse()); - - let transaction_fee_bravo = - builder.get_proposer_purse_balance() - proposer_reward_starting_balance_bravo; - - (transaction_fee_bravo, modified_balance_bravo) - }; - - let initial_balance: U512 = U512::from(DEFAULT_ACCOUNT_INITIAL_BALANCE); - - assert_eq!( - modified_balance_bravo, - builder.calculate_refund_amount(payment_purse_amount) - ); - - assert!( - modified_balance_alpha < initial_balance, - "balance should be less than initial balance" - ); - - assert!( - modified_balance_bravo < modified_balance_alpha, - "second modified balance should be less than first modified balance" - ); - - let tally = motes_alpha + motes_bravo + transferred_amount + modified_balance_bravo; + let error = builder.get_error().expect("must have error"); - assert_eq!( - initial_balance, tally, - "no net resources should be gained or lost post-distribution" - ); + assert_matches!(error, Error::Exec(execution::Error::ForgedReference(_))) } #[ignore] @@ -440,29 +368,12 @@ fn should_exec_stored_code_by_named_hash() { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - // store payment - let proposer_reward_starting_balance_alpha = builder.get_proposer_purse_balance(); - - let (default_account, _) = store_payment_to_account_context(&mut builder); + install_custom_payment(&mut builder); // verify stored contract functions as expected by checking all the maths - let (motes_alpha, modified_balance_alpha) = { - // get modified balance - let modified_balance_alpha: U512 = builder.get_purse_balance(default_account.main_purse()); - - // get cost - let transaction_fee_alpha = - builder.get_proposer_purse_balance() - proposer_reward_starting_balance_alpha; - - (transaction_fee_alpha, modified_balance_alpha) - }; - let transferred_amount = 1; - // next make another deploy that USES stored payment logic - let proposer_reward_starting_balance_bravo = builder.get_proposer_purse_balance(); - { let exec_request_stored_payment = { let account_1_account_hash = ACCOUNT_1_ADDR; @@ -474,7 +385,7 @@ fn should_exec_stored_code_by_named_hash() { ) .with_stored_versioned_payment_contract_by_name( STORED_PAYMENT_CONTRACT_PACKAGE_HASH_NAME, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), PAY_ENTRYPOINT, runtime_args! { ARG_AMOUNT => payment_purse_amount, @@ -487,36 +398,12 @@ fn should_exec_stored_code_by_named_hash() { ExecuteRequestBuilder::new().push_deploy(deploy).build() }; - builder.exec(exec_request_stored_payment).commit(); - } - - let (motes_bravo, modified_balance_bravo) = { - let modified_balance_bravo: U512 = builder.get_purse_balance(default_account.main_purse()); + builder.exec(exec_request_stored_payment).expect_failure(); - let transaction_fee_bravo = - builder.get_proposer_purse_balance() - proposer_reward_starting_balance_bravo; + let error = builder.get_error().unwrap(); - (transaction_fee_bravo, modified_balance_bravo) - }; - - let initial_balance: U512 = U512::from(DEFAULT_ACCOUNT_INITIAL_BALANCE); - - assert!( - modified_balance_alpha < initial_balance, - "balance should be less than initial balance" - ); - - assert!( - modified_balance_bravo < modified_balance_alpha, - "second modified balance should be less than first modified balance" - ); - - let tally = motes_alpha + motes_bravo + U512::from(transferred_amount) + modified_balance_bravo; - - assert_eq!( - initial_balance, tally, - "no net resources should be gained or lost post-distribution" - ); + assert_matches!(error, Error::Exec(execution::Error::ForgedReference(_))) + } } #[ignore] @@ -590,14 +477,13 @@ fn should_fail_payment_stored_at_named_key_with_incompatible_major_version() { builder.is_error(), "calling a payment module with increased major protocol version should be error" ); - let error_message = builder - .exec_error_message(1) - .expect("should have exec error"); - assert!( - error_message.contains(EXPECTED_ERROR_MESSAGE), - "{:?}", - error_message - ); + + let expected_error = Error::Exec(execution::Error::IncompatibleProtocolMajorVersion { + expected: 2, + actual: 1, + }); + + builder.assert_error(expected_error); } #[ignore] @@ -625,7 +511,7 @@ fn should_fail_payment_stored_at_hash_with_incompatible_major_version() { .named_keys() .get(STORED_PAYMENT_CONTRACT_HASH_NAME) .expect("should have standard_payment named key") - .into_hash() + .into_entity_addr() .expect("standard_payment should be an uref"); // @@ -669,10 +555,12 @@ fn should_fail_payment_stored_at_hash_with_incompatible_major_version() { "calling a payment module with increased major protocol version should be error" ); - let error_message = builder - .exec_error_message(1) - .expect("should have exec error"); - assert!(error_message.contains(EXPECTED_ERROR_MESSAGE)); + let expected_error = Error::Exec(execution::Error::IncompatibleProtocolMajorVersion { + expected: 2, + actual: 1, + }); + + builder.assert_error(expected_error); } #[ignore] @@ -719,7 +607,7 @@ fn should_fail_session_stored_at_named_key_with_incompatible_major_version() { .named_keys() .get(STORED_PAYMENT_CONTRACT_HASH_NAME) .expect("should have standard_payment named key") - .into_hash() + .into_entity_addr() .expect("standard_payment should be an uref"); // // upgrade with new wasm costs with modified mint for given version @@ -849,14 +737,12 @@ fn should_fail_session_stored_at_named_key_with_missing_new_major_version() { builder.is_error(), "calling a session module with increased major protocol version should be error", ); - let error_message = builder - .exec_error_message(1) - .expect("should have exec error"); - assert!( - error_message.contains(EXPECTED_VERSION_ERROR_MESSAGE), - "{}", - error_message - ); + + let entity_version_key = EntityVersionKey::new(2, 1); + + let expected_error = Error::Exec(execution::Error::InvalidEntityVersion(entity_version_key)); + + builder.assert_error(expected_error); } #[ignore] @@ -912,7 +798,7 @@ fn should_fail_session_stored_at_hash_with_incompatible_major_version() { .named_keys() .get(STORED_PAYMENT_CONTRACT_HASH_NAME) .expect("standard_payment should be present in named keys") - .into_hash() + .into_entity_addr() .expect("standard_payment named key should be hash"); let exec_request_stored_payment = { @@ -1010,7 +896,7 @@ fn should_execute_stored_payment_and_session_code_with_new_major_version() { .named_keys() .get(STORED_PAYMENT_CONTRACT_HASH_NAME) .expect("standard_payment should be present in named keys") - .into_hash() + .into_entity_addr() .expect("standard_payment named key should be hash"); let exec_request_stored_payment = { @@ -1040,6 +926,9 @@ fn should_execute_stored_payment_and_session_code_with_new_major_version() { builder .clear_results() .exec(exec_request_stored_payment) - .expect_success() - .commit(); + .expect_failure(); + + let error = builder.get_error().unwrap(); + + assert_matches!(error, Error::Exec(execution::Error::ForgedReference(_))) } diff --git a/execution_engine_testing/tests/src/test/explorer/faucet.rs b/execution_engine_testing/tests/src/test/explorer/faucet.rs index 1c2c8125fb..65c5ea4d74 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet.rs @@ -7,13 +7,14 @@ use casper_engine_test_support::{ DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_types::{ - account::AccountHash, runtime_args, system::mint, ApiError, Key, PublicKey, SecretKey, U512, + account::AccountHash, package::PackageKindTag, runtime_args, system::mint, ApiError, Key, + PublicKey, SecretKey, U512, }; // test constants. use super::{ faucet_test_helpers::{ - get_available_amount, get_faucet_contract_hash, get_faucet_purse, get_remaining_requests, + get_available_amount, get_faucet_entity_hash, get_faucet_purse, get_remaining_requests, query_stored_value, FaucetDeployHelper, FaucetInstallSessionRequestBuilder, FundAccountRequestBuilder, }, @@ -152,6 +153,8 @@ fn should_allow_installer_to_set_variables() { .commit(); let faucet_contract_hash = helper.query_and_set_faucet_contract_hash(&builder); + let faucet_entity_key = + Key::addressable_entity_key(PackageKindTag::SmartContract, faucet_contract_hash); assert_eq!( helper.query_faucet_purse_balance(&builder), @@ -160,7 +163,7 @@ fn should_allow_installer_to_set_variables() { let available_amount: U512 = query_stored_value( &mut builder, - faucet_contract_hash.into(), + faucet_entity_key, vec![AVAILABLE_AMOUNT_NAMED_KEY.to_string()], ); @@ -170,7 +173,7 @@ fn should_allow_installer_to_set_variables() { let time_interval: u64 = query_stored_value( &mut builder, - faucet_contract_hash.into(), + faucet_entity_key, vec![TIME_INTERVAL_NAMED_KEY.to_string()], ); @@ -179,7 +182,7 @@ fn should_allow_installer_to_set_variables() { let distributions_per_interval: u64 = query_stored_value( &mut builder, - faucet_contract_hash.into(), + faucet_entity_key, vec![DISTRIBUTIONS_PER_INTERVAL_NAMED_KEY.to_string()], ); @@ -192,7 +195,7 @@ fn should_allow_installer_to_set_variables() { let available_amount: U512 = query_stored_value( &mut builder, - faucet_contract_hash.into(), + faucet_entity_key, vec![AVAILABLE_AMOUNT_NAMED_KEY.to_string()], ); @@ -200,7 +203,7 @@ fn should_allow_installer_to_set_variables() { let time_interval: u64 = query_stored_value( &mut builder, - faucet_contract_hash.into(), + faucet_entity_key, vec![TIME_INTERVAL_NAMED_KEY.to_string()], ); @@ -208,7 +211,7 @@ fn should_allow_installer_to_set_variables() { let distributions_per_interval: u64 = query_stored_value( &mut builder, - faucet_contract_hash.into(), + faucet_entity_key, vec![DISTRIBUTIONS_PER_INTERVAL_NAMED_KEY.to_string()], ); @@ -390,7 +393,9 @@ fn should_not_fund_once_exhausted() { helper.query_and_set_faucet_contract_hash(&builder); - let faucet_contract_hash = get_faucet_contract_hash(&builder, installer_account); + let faucet_contract_hash = get_faucet_entity_hash(&builder, installer_account); + let faucet_entity_key = + Key::addressable_entity_key(PackageKindTag::SmartContract, faucet_contract_hash); let faucet_purse = get_faucet_purse(&builder, installer_account); let faucet_purse_balance = builder.get_purse_balance(faucet_purse); @@ -492,7 +497,7 @@ fn should_not_fund_once_exhausted() { // faucet may resume distributions once block time is > last_distribution_time + time_interval. let last_distribution_time = query_stored_value::( &mut builder, - faucet_contract_hash.into(), + faucet_entity_key, [LAST_DISTRIBUTION_TIME_NAMED_KEY.to_string()].into(), ); assert_eq!(last_distribution_time, 0); @@ -521,7 +526,7 @@ fn should_not_fund_once_exhausted() { let last_distribution_time = query_stored_value::( &mut builder, - faucet_contract_hash.into(), + faucet_entity_key, [LAST_DISTRIBUTION_TIME_NAMED_KEY.to_string()].into(), ); @@ -529,7 +534,7 @@ fn should_not_fund_once_exhausted() { let remaining_requests = query_stored_value::( &mut builder, - faucet_contract_hash.into(), + faucet_entity_key, [REMAINING_REQUESTS_NAMED_KEY.to_string()].into(), ); @@ -578,7 +583,9 @@ fn should_allow_installer_to_fund_freely() { helper.query_and_set_faucet_contract_hash(&builder); - let faucet_contract_hash = get_faucet_contract_hash(&builder, installer_account); + let faucet_contract_hash = get_faucet_entity_hash(&builder, installer_account); + let faucet_entity_key = + Key::addressable_entity_key(PackageKindTag::SmartContract, faucet_contract_hash); let faucet_purse = get_faucet_purse(&builder, installer_account); let faucet_purse_balance = builder.get_purse_balance(faucet_purse); @@ -586,7 +593,7 @@ fn should_allow_installer_to_fund_freely() { let available_amount = query_stored_value::( &mut builder, - faucet_contract_hash.into(), + faucet_entity_key, [AVAILABLE_AMOUNT_NAMED_KEY.to_string()].into(), ); @@ -601,7 +608,7 @@ fn should_allow_installer_to_fund_freely() { let available_amount = query_stored_value::( &mut builder, - faucet_contract_hash.into(), + faucet_entity_key, [AVAILABLE_AMOUNT_NAMED_KEY.to_string()].into(), ); @@ -745,16 +752,13 @@ fn should_allow_funding_by_an_authorized_account() { .get(&format!("{}_{}", FAUCET_CONTRACT_NAMED_KEY, FAUCET_ID)) .expect("failed to find faucet named key"); + let key = Key::contract_entity_key(faucet_named_key.into_entity_hash().expect( + "must convert to entity hash\ + ", + )); + let maybe_authorized_account_public_key = builder - .query( - None, - Key::Hash( - faucet_named_key - .into_hash() - .expect("failed to convert key into hash"), - ), - &[AUTHORIZED_ACCOUNT_NAMED_KEY.to_string()], - ) + .query(None, key, &[AUTHORIZED_ACCOUNT_NAMED_KEY.to_string()]) .expect("failed to find authorized account named key") .as_cl_value() .expect("failed to convert into cl value") @@ -775,15 +779,7 @@ fn should_allow_funding_by_an_authorized_account() { .commit(); let maybe_authorized_account_public_key = builder - .query( - None, - Key::Hash( - faucet_named_key - .into_hash() - .expect("failed to convert key into hash"), - ), - &[AUTHORIZED_ACCOUNT_NAMED_KEY.to_string()], - ) + .query(None, key, &[AUTHORIZED_ACCOUNT_NAMED_KEY.to_string()]) .expect("failed to find authorized account named key") .as_cl_value() .expect("failed to convert into cl value") @@ -842,7 +838,7 @@ fn should_allow_funding_by_an_authorized_account() { .commit(); let exec_results = builder - .get_last_exec_results() + .get_last_exec_result() .expect("failed to get exec results"); let exec_result = exec_results @@ -869,10 +865,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 = 83_594_845_660; - const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 648_705_070; - const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 3_244_975_770; - const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 3_364_807_470; + const EXPECTED_FAUCET_INSTALL_COST: u64 = 84_201_467_790; + const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 650_487_100; + const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 3_247_573_380; + const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 3_368_370_660; let installer_account = AccountHash::new([1u8; 32]); let user_account: AccountHash = AccountHash::new([2u8; 32]); @@ -963,7 +959,7 @@ fn faucet_costs() { let faucet_call_by_installer_cost = builder.last_exec_gas_cost(); - let faucet_contract_hash = get_faucet_contract_hash(&builder, installer_account); + let faucet_contract_hash = get_faucet_entity_hash(&builder, installer_account); let faucet_call_by_user_request = { let deploy_item = DeployItemBuilder::new() 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 818b9bb5d5..7e8c82e445 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 @@ -6,8 +6,8 @@ use casper_engine_test_support::{ }; use casper_execution_engine::engine_state::ExecuteRequest; use casper_types::{ - account::AccountHash, bytesrepr::FromBytes, runtime_args, system::mint, AddressableEntity, - CLTyped, ContractHash, Key, PublicKey, URef, U512, + account::AccountHash, bytesrepr::FromBytes, package::PackageKindTag, runtime_args, + system::mint, AddressableEntity, AddressableEntityHash, CLTyped, Key, PublicKey, URef, U512, }; use super::{ @@ -128,7 +128,7 @@ impl Default for FaucetInstallSessionRequestBuilder { #[derive(Debug, Copy, Clone)] pub struct FaucetConfigRequestBuilder { installer_account: AccountHash, - faucet_contract_hash: Option, + faucet_contract_hash: Option, available_amount: Option, time_interval: Option, distributions_per_interval: Option, @@ -140,7 +140,7 @@ impl FaucetConfigRequestBuilder { self } - pub fn with_faucet_contract_hash(mut self, contract_hash: ContractHash) -> Self { + pub fn with_faucet_contract_hash(mut self, contract_hash: AddressableEntityHash) -> Self { self.faucet_contract_hash = Some(contract_hash); self } @@ -194,7 +194,7 @@ impl Default for FaucetConfigRequestBuilder { pub struct FaucetAuthorizeAccountRequestBuilder { installer_account: AccountHash, authorized_account_public_key: Option, - faucet_contract_hash: Option, + faucet_contract_hash: Option, } impl FaucetAuthorizeAccountRequestBuilder { @@ -202,7 +202,10 @@ impl FaucetAuthorizeAccountRequestBuilder { FaucetAuthorizeAccountRequestBuilder::default() } - pub fn with_faucet_contract_hash(mut self, faucet_contract_hash: Option) -> Self { + pub fn with_faucet_contract_hash( + mut self, + faucet_contract_hash: Option, + ) -> Self { self.faucet_contract_hash = faucet_contract_hash; self } @@ -259,7 +262,7 @@ impl FaucetCallerAccount { } pub struct FaucetFundRequestBuilder { - faucet_contract_hash: Option, + faucet_contract_hash: Option, caller_account: FaucetCallerAccount, arg_target: Option, arg_fund_amount: Option, @@ -298,7 +301,10 @@ impl FaucetFundRequestBuilder { self } - pub fn with_faucet_contract_hash(mut self, faucet_contract_hash: ContractHash) -> Self { + pub fn with_faucet_contract_hash( + mut self, + faucet_contract_hash: AddressableEntityHash, + ) -> Self { self.faucet_contract_hash = Some(faucet_contract_hash); self } @@ -377,31 +383,31 @@ pub fn query_stored_value( .expect("must get value") } -pub fn get_faucet_contract_hash( +pub fn get_faucet_entity_hash( builder: &LmdbWasmTestBuilder, installer_account: AccountHash, -) -> ContractHash { +) -> AddressableEntityHash { builder .get_expected_addressable_entity_by_account_hash(installer_account) .named_keys() .get(&format!("{}_{}", FAUCET_CONTRACT_NAMED_KEY, FAUCET_ID)) .cloned() - .and_then(Key::into_hash) - .map(ContractHash::new) + .and_then(Key::into_entity_addr) + .map(AddressableEntityHash::new) .expect("failed to find faucet contract") } -pub fn get_faucet_contract( +pub fn get_faucet_entity( builder: &LmdbWasmTestBuilder, installer_account: AccountHash, ) -> AddressableEntity { builder - .get_addressable_entity(get_faucet_contract_hash(builder, installer_account)) + .get_addressable_entity(get_faucet_entity_hash(builder, installer_account)) .expect("failed to find faucet contract") } pub fn get_faucet_purse(builder: &LmdbWasmTestBuilder, installer_account: AccountHash) -> URef { - get_faucet_contract(builder, installer_account) + get_faucet_entity(builder, installer_account) .named_keys() .get(FAUCET_PURSE_NAMED_KEY) .cloned() @@ -411,12 +417,12 @@ pub fn get_faucet_purse(builder: &LmdbWasmTestBuilder, installer_account: Accoun pub fn get_available_amount( builder: &LmdbWasmTestBuilder, - faucet_contract_hash: ContractHash, + faucet_contract_hash: AddressableEntityHash, ) -> U512 { builder .query( None, - faucet_contract_hash.into(), + Key::addressable_entity_key(PackageKindTag::SmartContract, faucet_contract_hash), &[AVAILABLE_AMOUNT_NAMED_KEY.to_string()], ) .expect("failed to find available amount named key") @@ -429,12 +435,12 @@ pub fn get_available_amount( pub fn get_remaining_requests( builder: &LmdbWasmTestBuilder, - faucet_contract_hash: ContractHash, + faucet_contract_hash: AddressableEntityHash, ) -> U512 { builder .query( None, - faucet_contract_hash.into(), + Key::addressable_entity_key(PackageKindTag::SmartContract, faucet_contract_hash), &[REMAINING_REQUESTS_NAMED_KEY.to_string()], ) .expect("failed to find available amount named key") @@ -453,7 +459,7 @@ pub struct FaucetDeployHelper { faucet_purse_fund_amount: U512, faucet_installer_session: String, faucet_id: u64, - faucet_contract_hash: Option, + faucet_contract_hash: Option, faucet_distributions_per_interval: Option, faucet_available_amount: Option, faucet_time_interval: Option, @@ -509,8 +515,8 @@ impl FaucetDeployHelper { pub fn query_and_set_faucet_contract_hash( &mut self, builder: &LmdbWasmTestBuilder, - ) -> ContractHash { - let contract_hash = get_faucet_contract_hash(builder, self.installer_account()); + ) -> AddressableEntityHash { + let contract_hash = get_faucet_entity_hash(builder, self.installer_account()); self.faucet_contract_hash = Some(contract_hash); contract_hash @@ -529,7 +535,7 @@ impl FaucetDeployHelper { self.faucet_purse_fund_amount } - pub fn faucet_contract_hash(&self) -> Option { + pub fn faucet_contract_hash(&self) -> Option { self.faucet_contract_hash } diff --git a/execution_engine_testing/tests/src/test/groups.rs b/execution_engine_testing/tests/src/test/groups.rs index 15f43fb030..50f0b6ae2a 100644 --- a/execution_engine_testing/tests/src/test/groups.rs +++ b/execution_engine_testing/tests/src/test/groups.rs @@ -3,16 +3,15 @@ use once_cell::sync::Lazy; use casper_engine_test_support::{ DeployItemBuilder, ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, + DEFAULT_PAYMENT, MINIMUM_ACCOUNT_CREATION_BALANCE, }; use casper_execution_engine::{engine_state::Error, execution}; use casper_types::{ - account::AccountHash, package::CONTRACT_INITIAL_VERSION, runtime_args, Key, RuntimeArgs, U512, + account::AccountHash, package::ENTITY_INITIAL_VERSION, runtime_args, Key, RuntimeArgs, U512, }; -use crate::wasm_utils; +use crate::{lmdb_fixture, wasm_utils}; -const CONTRACT_GROUPS: &str = "groups.wasm"; const PACKAGE_HASH_KEY: &str = "package_hash_key"; const PACKAGE_ACCESS_KEY: &str = "package_access_key"; const RESTRICTED_SESSION: &str = "restricted_session"; @@ -29,26 +28,21 @@ const CALL_RESTRICTED_ENTRY_POINTS: &str = "call_restricted_entry_points"; const ARG_AMOUNT: &str = "amount"; const ARG_TARGET: &str = "target"; +const GROUPS_FIXTURE: &str = "groups"; + static TRANSFER_1_AMOUNT: Lazy = Lazy::new(|| U512::from(MINIMUM_ACCOUNT_CREATION_BALANCE) + 1000); +fn setup_from_lmdb_fixture() -> LmdbWasmTestBuilder { + let (builder, _, _) = lmdb_fixture::builder_from_global_state_fixture(GROUPS_FIXTURE); + + builder +} + #[ignore] #[test] fn should_call_group_restricted_session() { - // This test runs a contract that's after every call extends the same key with - // more data - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_GROUPS, - RuntimeArgs::default(), - ) - .build(); - - let mut builder = LmdbWasmTestBuilder::default(); - - builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - - builder.exec(exec_request_1).expect_success().commit(); + let mut builder = setup_from_lmdb_fixture(); let account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -63,54 +57,27 @@ fn should_call_group_restricted_session() { .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! {}; - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_contract_by_name( - PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), - RESTRICTED_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::new().push_deploy(deploy).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 exec_request_2 = ExecuteRequestBuilder::versioned_contract_call_by_name( + *DEFAULT_ACCOUNT_ADDR, + PACKAGE_HASH_KEY, + Some(ENTITY_INITIAL_VERSION), + RESTRICTED_SESSION, + runtime_args! {}, + ) + .build(); - builder.exec(exec_request_2).expect_success().commit(); + builder.exec(exec_request_2).expect_failure(); - let _account = builder - .query(None, Key::Account(*DEFAULT_ACCOUNT_ADDR), &[]) - .expect("should query account") - .as_cl_value() - .cloned() - .expect("should be account"); + builder.assert_error(Error::Exec(execution::Error::InvalidContext)) } #[ignore] #[test] fn should_call_group_restricted_session_caller() { - // This test runs a contract that's after every call extends the same key with - // more data - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_GROUPS, - RuntimeArgs::default(), - ) - .build(); - - let mut builder = LmdbWasmTestBuilder::default(); - - builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - - builder.exec(exec_request_1).expect_success().commit(); + let mut builder = setup_from_lmdb_fixture(); let account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -125,47 +92,28 @@ fn should_call_group_restricted_session_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 = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_contract_by_name( - PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), - RESTRICTED_SESSION_CALLER, - args, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([3; 32]) - .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 exec_request_2 = ExecuteRequestBuilder::versioned_contract_call_by_name( + *DEFAULT_ACCOUNT_ADDR, + PACKAGE_HASH_KEY, + Some(ENTITY_INITIAL_VERSION), + RESTRICTED_SESSION, + runtime_args! { + PACKAGE_HASH_ARG => package_hash.into_package_hash() + }, + ) + .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() - }; - builder.exec(exec_request_2).expect_success().commit(); + builder.exec(exec_request_2).expect_failure(); - let _account = builder - .query(None, Key::Account(*DEFAULT_ACCOUNT_ADDR), &[]) - .expect("should query account") - .as_cl_value() - .cloned() - .expect("should be account"); + builder.assert_error(Error::Exec(execution::Error::InvalidContext)); } #[test] #[ignore] fn should_not_call_restricted_session_from_wrong_account() { - // This test runs a contract that's after every call extends the same key with - // more data - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_GROUPS, - RuntimeArgs::default(), - ) - .build(); - let exec_request_2 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, CONTRACT_TRANSFER_TO_ACCOUNT, @@ -173,11 +121,7 @@ fn should_not_call_restricted_session_from_wrong_account() { ) .build(); - let mut builder = LmdbWasmTestBuilder::default(); - - builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - - builder.exec(exec_request_1).expect_success().commit(); + let mut builder = setup_from_lmdb_fixture(); builder.exec(exec_request_2).expect_success().commit(); @@ -198,8 +142,8 @@ fn should_not_call_restricted_session_from_wrong_account() { let deploy = DeployItemBuilder::new() .with_address(ACCOUNT_1_ADDR) .with_stored_versioned_contract_by_hash( - package_hash.into_hash().expect("should be hash"), - Some(CONTRACT_INITIAL_VERSION), + package_hash.into_package_addr().expect("should be hash"), + Some(ENTITY_INITIAL_VERSION), RESTRICTED_SESSION, args, ) @@ -221,7 +165,7 @@ fn should_not_call_restricted_session_from_wrong_account() { .expect("should be account"); let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last response"); assert_eq!(response.len(), 1); let exec_response = response.last().expect("should have response"); @@ -232,15 +176,6 @@ fn should_not_call_restricted_session_from_wrong_account() { #[test] #[ignore] fn should_not_call_restricted_session_caller_from_wrong_account() { - // This test runs a contract that's after every call extends the same key with - // more data - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_GROUPS, - RuntimeArgs::default(), - ) - .build(); - let exec_request_2 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, CONTRACT_TRANSFER_TO_ACCOUNT, @@ -248,11 +183,7 @@ fn should_not_call_restricted_session_caller_from_wrong_account() { ) .build(); - let mut builder = LmdbWasmTestBuilder::default(); - - builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - - builder.exec(exec_request_1).expect_success().commit(); + let mut builder = setup_from_lmdb_fixture(); builder.exec(exec_request_2).expect_success().commit(); @@ -276,8 +207,8 @@ fn should_not_call_restricted_session_caller_from_wrong_account() { let deploy = DeployItemBuilder::new() .with_address(ACCOUNT_1_ADDR) .with_stored_versioned_contract_by_hash( - package_hash.into_hash().expect("should be hash"), - Some(CONTRACT_INITIAL_VERSION), + package_hash.into_package_addr().expect("should be hash"), + Some(ENTITY_INITIAL_VERSION), RESTRICTED_SESSION_CALLER, args, ) @@ -299,7 +230,7 @@ fn should_not_call_restricted_session_caller_from_wrong_account() { .expect("should be account"); let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last response"); assert_eq!(response.len(), 1); let exec_response = response.last().expect("should have response"); @@ -310,20 +241,7 @@ fn should_not_call_restricted_session_caller_from_wrong_account() { #[ignore] #[test] fn should_call_group_restricted_contract() { - // This test runs a contract that's after every call extends the same key with - // more data - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_GROUPS, - RuntimeArgs::default(), - ) - .build(); - - let mut builder = LmdbWasmTestBuilder::default(); - - builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - - builder.exec(exec_request_1).expect_success().commit(); + let mut builder = setup_from_lmdb_fixture(); let account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -349,7 +267,7 @@ fn should_call_group_restricted_contract() { .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), RESTRICTED_CONTRACT, args, ) @@ -374,14 +292,6 @@ fn should_call_group_restricted_contract() { #[ignore] #[test] fn should_not_call_group_restricted_contract_from_wrong_account() { - // This test runs a contract that's after every call extends the same key with - // more data - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_GROUPS, - RuntimeArgs::default(), - ) - .build(); let exec_request_2 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, CONTRACT_TRANSFER_TO_ACCOUNT, @@ -389,11 +299,7 @@ fn should_not_call_group_restricted_contract_from_wrong_account() { ) .build(); - let mut builder = LmdbWasmTestBuilder::default(); - - builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - - builder.exec(exec_request_1).expect_success().commit(); + let mut builder = setup_from_lmdb_fixture(); builder.exec(exec_request_2).expect_success().commit(); let account = builder @@ -419,8 +325,8 @@ fn should_not_call_group_restricted_contract_from_wrong_account() { let deploy = DeployItemBuilder::new() .with_address(ACCOUNT_1_ADDR) .with_stored_versioned_contract_by_hash( - package_hash.into_hash().expect("should be hash"), - Some(CONTRACT_INITIAL_VERSION), + package_hash.into_package_addr().expect("should be hash"), + Some(ENTITY_INITIAL_VERSION), RESTRICTED_CONTRACT, args, ) @@ -435,7 +341,7 @@ fn should_not_call_group_restricted_contract_from_wrong_account() { builder.exec(exec_request_3).commit(); let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last response"); assert_eq!(response.len(), 1); let exec_response = response.last().expect("should have response"); @@ -446,20 +352,7 @@ fn should_not_call_group_restricted_contract_from_wrong_account() { #[ignore] #[test] fn should_call_group_unrestricted_contract_caller() { - // This test runs a contract that's after every call extends the same key with - // more data - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_GROUPS, - RuntimeArgs::default(), - ) - .build(); - - let mut builder = LmdbWasmTestBuilder::default(); - - builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - - builder.exec(exec_request_1).expect_success().commit(); + let mut builder = setup_from_lmdb_fixture(); let account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -482,7 +375,7 @@ fn should_call_group_unrestricted_contract_caller() { .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), UNRESTRICTED_CONTRACT_CALLER, args, ) @@ -506,12 +399,6 @@ fn should_call_group_unrestricted_contract_caller() { #[ignore] #[test] fn should_call_unrestricted_contract_caller_from_different_account() { - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_GROUPS, - RuntimeArgs::default(), - ) - .build(); let exec_request_2 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, CONTRACT_TRANSFER_TO_ACCOUNT, @@ -519,11 +406,7 @@ fn should_call_unrestricted_contract_caller_from_different_account() { ) .build(); - let mut builder = LmdbWasmTestBuilder::default(); - - builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - - builder.exec(exec_request_1).expect_success().commit(); + let mut builder = setup_from_lmdb_fixture(); builder.exec(exec_request_2).expect_success().commit(); let account = builder @@ -539,28 +422,21 @@ fn should_call_unrestricted_contract_caller_from_different_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! { + // 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 exec_request_3 = ExecuteRequestBuilder::versioned_contract_call_by_hash( + *DEFAULT_ACCOUNT_ADDR, + package_hash + .into_package_hash() + .expect("must have package hash"), + Some(ENTITY_INITIAL_VERSION), + UNRESTRICTED_CONTRACT_CALLER, + runtime_args! { PACKAGE_HASH_ARG => *package_hash, - }; - let deploy = DeployItemBuilder::new() - .with_address(ACCOUNT_1_ADDR) - .with_stored_versioned_contract_by_hash( - package_hash.into_hash().expect("should be hash"), - Some(CONTRACT_INITIAL_VERSION), - UNRESTRICTED_CONTRACT_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::new().push_deploy(deploy).build() - }; + }, + ) + .build(); builder.exec(exec_request_3).expect_success().commit(); } @@ -568,14 +444,6 @@ fn should_call_unrestricted_contract_caller_from_different_account() { #[ignore] #[test] fn should_call_group_restricted_contract_as_session() { - // This test runs a contract that's after every call extends the same key with - // more data - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_GROUPS, - RuntimeArgs::default(), - ) - .build(); let exec_request_2 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, CONTRACT_TRANSFER_TO_ACCOUNT, @@ -583,11 +451,7 @@ fn should_call_group_restricted_contract_as_session() { ) .build(); - let mut builder = LmdbWasmTestBuilder::default(); - - builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - - builder.exec(exec_request_1).expect_success().commit(); + let mut builder = setup_from_lmdb_fixture(); builder.exec(exec_request_2).expect_success().commit(); let account = builder @@ -603,43 +467,30 @@ fn should_call_group_restricted_contract_as_session() { .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! { + // 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 exec_request_3 = ExecuteRequestBuilder::versioned_contract_call_by_hash( + *DEFAULT_ACCOUNT_ADDR, + package_hash + .into_package_hash() + .expect("must convert to package hash"), + Some(ENTITY_INITIAL_VERSION), + RESTRICTED_CONTRACT_CALLER_AS_SESSION, + runtime_args! { PACKAGE_HASH_ARG => *package_hash, - }; - let deploy = DeployItemBuilder::new() - .with_address(*DEFAULT_ACCOUNT_ADDR) - .with_stored_versioned_contract_by_hash( - package_hash.into_hash().expect("should be hash"), - Some(CONTRACT_INITIAL_VERSION), - RESTRICTED_CONTRACT_CALLER_AS_SESSION, - args, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR]) - .with_deploy_hash([4; 32]) - .build(); + }, + ) + .build(); - ExecuteRequestBuilder::new().push_deploy(deploy).build() - }; + builder.exec(exec_request_3).expect_failure(); - builder.exec(exec_request_3).expect_success().commit(); + builder.assert_error(Error::Exec(execution::Error::InvalidContext)) } #[ignore] #[test] fn should_call_group_restricted_contract_as_session_from_wrong_account() { - // This test runs a contract that's after every call extends the same key with - // more data - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_GROUPS, - RuntimeArgs::default(), - ) - .build(); let exec_request_2 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, CONTRACT_TRANSFER_TO_ACCOUNT, @@ -647,11 +498,7 @@ fn should_call_group_restricted_contract_as_session_from_wrong_account() { ) .build(); - let mut builder = LmdbWasmTestBuilder::default(); - - builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - - builder.exec(exec_request_1).expect_success().commit(); + let mut builder = setup_from_lmdb_fixture(); builder.exec(exec_request_2).expect_success().commit(); let account = builder @@ -667,33 +514,26 @@ fn should_call_group_restricted_contract_as_session_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! { + // 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 exec_request_3 = ExecuteRequestBuilder::versioned_contract_call_by_hash( + ACCOUNT_1_ADDR, + package_hash + .into_package_hash() + .expect("must convert to package hash"), + Some(ENTITY_INITIAL_VERSION), + RESTRICTED_CONTRACT_CALLER_AS_SESSION, + runtime_args! { PACKAGE_HASH_ARG => *package_hash, - }; - let deploy = DeployItemBuilder::new() - .with_address(ACCOUNT_1_ADDR) - .with_stored_versioned_contract_by_hash( - package_hash.into_hash().expect("should be hash"), - Some(CONTRACT_INITIAL_VERSION), - RESTRICTED_CONTRACT_CALLER_AS_SESSION, - args, - ) - .with_empty_payment_bytes(runtime_args! { ARG_AMOUNT => *DEFAULT_PAYMENT, }) - .with_authorization_keys(&[ACCOUNT_1_ADDR]) - .with_deploy_hash([4; 32]) - .build(); - - ExecuteRequestBuilder::new().push_deploy(deploy).build() - }; + }, + ) + .build(); builder.exec(exec_request_3).commit(); let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last response"); assert_eq!(response.len(), 1); let exec_response = response.last().expect("should have response"); @@ -704,20 +544,7 @@ fn should_call_group_restricted_contract_as_session_from_wrong_account() { #[ignore] #[test] fn should_not_call_uncallable_contract_from_deploy() { - // This test runs a contract that's after every call extends the same key with - // more data - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_GROUPS, - RuntimeArgs::default(), - ) - .build(); - - let mut builder = LmdbWasmTestBuilder::default(); - - builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - - builder.exec(exec_request_1).expect_success().commit(); + let mut builder = setup_from_lmdb_fixture(); let account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -743,7 +570,7 @@ fn should_not_call_uncallable_contract_from_deploy() { .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), UNCALLABLE_SESSION, args, ) @@ -757,7 +584,7 @@ fn should_not_call_uncallable_contract_from_deploy() { builder.exec(exec_request_2).commit(); let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last response"); assert_eq!(response.len(), 1); let exec_response = response.last().expect("should have response"); @@ -772,7 +599,7 @@ fn should_not_call_uncallable_contract_from_deploy() { .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), CALL_RESTRICTED_ENTRY_POINTS, args, ) @@ -784,26 +611,15 @@ fn should_not_call_uncallable_contract_from_deploy() { ExecuteRequestBuilder::new().push_deploy(deploy).build() }; - builder.exec(exec_request_3).expect_success().commit(); + builder.exec(exec_request_3).expect_failure(); + + builder.assert_error(Error::Exec(execution::Error::InvalidContext)) } #[ignore] #[test] fn should_not_call_uncallable_session_from_deploy() { - // This test runs a contract that's after every call extends the same key with - // more data - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_GROUPS, - RuntimeArgs::default(), - ) - .build(); - - let mut builder = LmdbWasmTestBuilder::default(); - - builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - - builder.exec(exec_request_1).expect_success().commit(); + let mut builder = setup_from_lmdb_fixture(); let account = builder .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) @@ -829,7 +645,7 @@ fn should_not_call_uncallable_session_from_deploy() { .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), UNCALLABLE_CONTRACT, args, ) @@ -843,7 +659,7 @@ fn should_not_call_uncallable_session_from_deploy() { builder.exec(exec_request_2).commit(); let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last response"); assert_eq!(response.len(), 1); let exec_response = response.last().expect("should have response"); @@ -858,7 +674,7 @@ fn should_not_call_uncallable_session_from_deploy() { .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), CALL_RESTRICTED_ENTRY_POINTS, args, ) @@ -869,7 +685,9 @@ fn should_not_call_uncallable_session_from_deploy() { ExecuteRequestBuilder::new().push_deploy(deploy).build() }; - builder.exec(exec_request_3).expect_success().commit(); + builder.exec(exec_request_3).expect_failure(); + + builder.assert_error(Error::Exec(execution::Error::InvalidContext)) } #[test] @@ -878,25 +696,13 @@ 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. - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_GROUPS, - RuntimeArgs::default(), - ) - .build(); - let exec_request_2 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, CONTRACT_TRANSFER_TO_ACCOUNT, runtime_args! { ARG_TARGET => ACCOUNT_1_ADDR, ARG_AMOUNT => *TRANSFER_1_AMOUNT }, ) .build(); - - let mut builder = LmdbWasmTestBuilder::default(); - - builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - - builder.exec(exec_request_1).expect_success().commit(); + let mut builder = setup_from_lmdb_fixture(); builder.exec(exec_request_2).expect_success().commit(); @@ -922,9 +728,9 @@ fn should_not_call_group_restricted_stored_payment_code_from_invalid_account() { .with_session_bytes(wasm_utils::do_nothing_bytes(), RuntimeArgs::default()) .with_stored_versioned_payment_contract_by_hash( package_hash - .into_hash() + .into_package_addr() .expect("must have created package hash"), - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), "restricted_standard_payment", args, ) @@ -945,7 +751,7 @@ fn should_not_call_group_restricted_stored_payment_code_from_invalid_account() { .expect("should be account"); let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last response"); assert_eq!(response.len(), 1); let exec_response = response.last().expect("should have response"); @@ -958,12 +764,6 @@ fn should_not_call_group_restricted_stored_payment_code_from_invalid_account() { 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. - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_GROUPS, - RuntimeArgs::default(), - ) - .build(); let exec_request_2 = ExecuteRequestBuilder::standard( *DEFAULT_ACCOUNT_ADDR, @@ -972,11 +772,7 @@ fn should_call_group_restricted_stored_payment_code() { ) .build(); - let mut builder = LmdbWasmTestBuilder::default(); - - builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); - - builder.exec(exec_request_1).expect_success().commit(); + let mut builder = setup_from_lmdb_fixture(); builder.exec(exec_request_2).expect_success().commit(); @@ -1003,9 +799,9 @@ fn should_call_group_restricted_stored_payment_code() { // .with_stored_versioned_contract_by_name(name, version, entry_point, args) .with_stored_versioned_payment_contract_by_hash( package_hash - .into_hash() + .into_package_addr() .expect("must have created package hash"), - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), "restricted_standard_payment", args, ) @@ -1016,5 +812,7 @@ fn should_call_group_restricted_stored_payment_code() { ExecuteRequestBuilder::new().push_deploy(deploy).build() }; - builder.exec(exec_request_3).expect_success().commit(); + builder.exec(exec_request_3).expect_failure(); + + builder.assert_error(Error::Exec(execution::Error::InvalidContext)); } 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 d8b274bc95..e94e2c7c76 100644 --- a/execution_engine_testing/tests/src/test/host_function_costs.rs +++ b/execution_engine_testing/tests/src/test/host_function_costs.rs @@ -2,7 +2,7 @@ use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, PRODUCTION_RUN_GENESIS_REQUEST, }; -use casper_types::{bytesrepr::Bytes, runtime_args, ContractHash, RuntimeArgs}; +use casper_types::{bytesrepr::Bytes, runtime_args, AddressableEntityHash, RuntimeArgs}; const HOST_FUNCTION_COSTS_NAME: &str = "host_function_costs.wasm"; const CONTRACT_KEY_NAME: &str = "contract"; @@ -38,11 +38,11 @@ fn should_measure_gas_cost() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should have account"); - let contract_hash: ContractHash = account + let contract_hash: AddressableEntityHash = account .named_keys() .get(CONTRACT_KEY_NAME) .expect("contract hash") - .into_hash() + .into_entity_addr() .expect("should be hash") .into(); @@ -106,11 +106,11 @@ fn should_measure_nested_host_function_call_cost() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should have account"); - let contract_hash: ContractHash = account + let contract_hash: AddressableEntityHash = account .named_keys() .get(CONTRACT_KEY_NAME) .expect("contract hash") - .into_hash() + .into_entity_addr() .expect("should be hash") .into(); @@ -184,11 +184,11 @@ fn should_measure_argument_size_in_host_function_call() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should have account"); - let contract_hash: ContractHash = account + let contract_hash: AddressableEntityHash = account .named_keys() .get(CONTRACT_KEY_NAME) .expect("contract hash") - .into_hash() + .into_entity_addr() .expect("should be hash") .into(); diff --git a/execution_engine_testing/tests/src/test/manage_groups.rs b/execution_engine_testing/tests/src/test/manage_groups.rs index 8f201e0807..71940f4b7b 100644 --- a/execution_engine_testing/tests/src/test/manage_groups.rs +++ b/execution_engine_testing/tests/src/test/manage_groups.rs @@ -10,7 +10,7 @@ use casper_engine_test_support::{ use casper_execution_engine::{engine_state::Error, execution}; use casper_types::{ addressable_entity::{self, MAX_GROUPS}, - package::CONTRACT_INITIAL_VERSION, + package::ENTITY_INITIAL_VERSION, runtime_args, Group, RuntimeArgs, }; @@ -76,7 +76,7 @@ fn should_create_and_remove_group() { .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), CREATE_GROUP, DEFAULT_CREATE_GROUP_ARGS.clone(), ) @@ -93,9 +93,7 @@ fn should_create_and_remove_group() { let query_result = builder .query(None, *package_hash, &[]) .expect("should have result"); - let contract_package = query_result - .as_contract_package() - .expect("should be package"); + let contract_package = query_result.as_package().expect("should be package"); assert_eq!(contract_package.groups().len(), 1); let group_1 = contract_package .groups() @@ -114,7 +112,7 @@ fn should_create_and_remove_group() { .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), REMOVE_GROUP, args, ) @@ -131,9 +129,7 @@ fn should_create_and_remove_group() { let query_result = builder .query(None, *package_hash, &[]) .expect("should have result"); - let contract_package = query_result - .as_contract_package() - .expect("should be package"); + let contract_package = query_result.as_package().expect("should be package"); assert_eq!( contract_package.groups().get(&Group::new(GROUP_1_NAME)), None @@ -179,7 +175,7 @@ fn should_create_and_extend_user_group() { .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), CREATE_GROUP, DEFAULT_CREATE_GROUP_ARGS.clone(), ) @@ -196,9 +192,7 @@ fn should_create_and_extend_user_group() { let query_result = builder .query(None, *package_hash, &[]) .expect("should have result"); - let contract_package = query_result - .as_contract_package() - .expect("should be package"); + let contract_package = query_result.as_package().expect("should be package"); assert_eq!(contract_package.groups().len(), 1); let group_1 = contract_package .groups() @@ -218,7 +212,7 @@ fn should_create_and_extend_user_group() { .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), EXTEND_GROUP_UREFS, args, ) @@ -235,9 +229,7 @@ fn should_create_and_extend_user_group() { let query_result = builder .query(None, *package_hash, &[]) .expect("should have result"); - let contract_package = query_result - .as_contract_package() - .expect("should be package"); + let contract_package = query_result.as_package().expect("should be package"); let group_1_extended = contract_package .groups() .get(&Group::new(GROUP_1_NAME)) @@ -286,7 +278,7 @@ fn should_create_and_remove_urefs_from_group() { .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), CREATE_GROUP, DEFAULT_CREATE_GROUP_ARGS.clone(), ) @@ -303,9 +295,7 @@ fn should_create_and_remove_urefs_from_group() { let query_result = builder .query(None, *package_hash, &[]) .expect("should have result"); - let contract_package = query_result - .as_contract_package() - .expect("should be package"); + let contract_package = query_result.as_package().expect("should be package"); assert_eq!(contract_package.groups().len(), 1); let group_1 = contract_package .groups() @@ -327,7 +317,7 @@ fn should_create_and_remove_urefs_from_group() { .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), REMOVE_GROUP_UREFS, args, ) @@ -344,9 +334,7 @@ fn should_create_and_remove_urefs_from_group() { let query_result = builder .query(None, *package_hash, &[]) .expect("should have result"); - let contract_package = query_result - .as_contract_package() - .expect("should be package"); + let contract_package = query_result.as_package().expect("should be package"); let group_1_modified = contract_package .groups() .get(&Group::new(GROUP_1_NAME)) @@ -392,7 +380,7 @@ fn should_limit_max_urefs_while_extending() { .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), CREATE_GROUP, DEFAULT_CREATE_GROUP_ARGS.clone(), ) @@ -409,9 +397,7 @@ fn should_limit_max_urefs_while_extending() { let query_result = builder .query(None, *package_hash, &[]) .expect("should have result"); - let contract_package = query_result - .as_contract_package() - .expect("should be package"); + let contract_package = query_result.as_package().expect("should be package"); assert_eq!(contract_package.groups().len(), 1); let group_1 = contract_package .groups() @@ -431,7 +417,7 @@ fn should_limit_max_urefs_while_extending() { .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), EXTEND_GROUP_UREFS, args, ) @@ -456,7 +442,7 @@ fn should_limit_max_urefs_while_extending() { .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( PACKAGE_HASH_KEY, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), EXTEND_GROUP_UREFS, args, ) @@ -473,9 +459,7 @@ fn should_limit_max_urefs_while_extending() { let query_result = builder .query(None, *package_hash, &[]) .expect("should have result"); - let contract_package = query_result - .as_contract_package() - .expect("should be package"); + let contract_package = query_result.as_package().expect("should be package"); let group_1_modified = contract_package .groups() .get(&Group::new(GROUP_1_NAME)) diff --git a/execution_engine_testing/tests/src/test/mod.rs b/execution_engine_testing/tests/src/test/mod.rs index 263169bc60..f3f5394f83 100644 --- a/execution_engine_testing/tests/src/test/mod.rs +++ b/execution_engine_testing/tests/src/test/mod.rs @@ -10,7 +10,8 @@ mod gas_counter; mod get_balance; mod groups; mod host_function_costs; -mod manage_groups; +// TODO: Revisit this module and check relevancy. +// mod manage_groups; mod private_chain; mod regression; mod step; 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 ea8d99d1c9..522b6bd25d 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 @@ -282,8 +282,9 @@ fn should_accumulate_fees_after_upgrade() { // Check handle payments has rewards purse let handle_payment_hash = builder.get_handle_payment_contract_hash(); + let handle_payment_contract = builder - .query(None, handle_payment_hash.into(), &[]) + .query(None, Key::Hash(handle_payment_hash.value()), &[]) .expect("should have handle payment contract") .into_contract() .expect("should have legacy Contract under the Key::Contract variant"); 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 6af9881992..bdbea6efcf 100644 --- a/execution_engine_testing/tests/src/test/private_chain/management.rs +++ b/execution_engine_testing/tests/src/test/private_chain/management.rs @@ -22,7 +22,7 @@ use casper_types::{ mint, standard_payment::{self, ARG_AMOUNT}, }, - ApiError, CLType, CLValue, ContractHash, ContractPackageHash, GenesisAccount, Key, Package, + AddressableEntityHash, ApiError, CLType, CLValue, GenesisAccount, Key, Package, PackageHash, RuntimeArgs, U512, }; use tempfile::TempDir; @@ -478,25 +478,26 @@ fn administrator_account_should_disable_any_contract_used_as_session() { .get_entity_by_account_hash(*ACCOUNT_1_ADDR) .expect("should have account 1 after genesis"); - let stored_contract_key = account_1_genesis + let stored_entity_key = account_1_genesis .named_keys() .get(DO_NOTHING_HASH_NAME) .unwrap(); - let stored_contract_hash = stored_contract_key - .into_hash() - .map(ContractHash::new) + + let stored_entity_hash = stored_entity_key + .into_entity_addr() + .map(AddressableEntityHash::new) .expect("should have stored contract hash"); let do_nothing_contract_package_key = { let addressable_entity = builder - .get_addressable_entity(stored_contract_hash) + .get_addressable_entity(stored_entity_hash) .expect("should be entity"); - Key::from(addressable_entity.contract_package_hash()) + Key::from(addressable_entity.package_hash()) }; let do_nothing_contract_package_hash = do_nothing_contract_package_key - .into_hash() - .map(ContractPackageHash::new) + .into_package_addr() + .map(PackageHash::new) .expect("should be package hash"); let contract_package_before = Package::try_from( @@ -506,7 +507,7 @@ fn administrator_account_should_disable_any_contract_used_as_session() { ) .expect("should be contract package"); assert!( - contract_package_before.is_contract_enabled(&stored_contract_hash), + contract_package_before.is_entity_enabled(&stored_entity_hash), "newly stored contract should be enabled" ); @@ -524,7 +525,7 @@ fn administrator_account_should_disable_any_contract_used_as_session() { let disable_request = { let session_args = runtime_args! { ARG_CONTRACT_PACKAGE_HASH => do_nothing_contract_package_hash, - ARG_CONTRACT_HASH => stored_contract_hash, + ARG_CONTRACT_HASH => stored_entity_hash, }; ExecuteRequestBuilder::standard(*DEFAULT_ADMIN_ACCOUNT_ADDR, DISABLE_CONTRACT, session_args) @@ -544,7 +545,7 @@ fn administrator_account_should_disable_any_contract_used_as_session() { contract_package_before, contract_package_after_disable, "contract package should be disabled" ); - assert!(!contract_package_after_disable.is_contract_enabled(&stored_contract_hash),); + assert!(!contract_package_after_disable.is_entity_enabled(&stored_entity_hash),); let call_delegate_requests_1 = { // Unable to call disabled stored contract directly @@ -558,7 +559,7 @@ fn administrator_account_should_disable_any_contract_used_as_session() { let call_delegate_by_hash = ExecuteRequestBuilder::contract_call_by_hash( *ACCOUNT_1_ADDR, - stored_contract_hash, + stored_entity_hash, DELEGATE_ENTRYPOINT, RuntimeArgs::default(), ) @@ -566,7 +567,7 @@ fn administrator_account_should_disable_any_contract_used_as_session() { let call_delegate_from_wasm = make_call_contract_session_request( *ACCOUNT_1_ADDR, - stored_contract_hash, + stored_entity_hash, DELEGATE_ENTRYPOINT, RuntimeArgs::default(), ); @@ -587,8 +588,8 @@ fn administrator_account_should_disable_any_contract_used_as_session() { assert!( matches!( error, - Error::Exec(execution::Error::DisabledContract(disabled_contract_hash)) - if disabled_contract_hash == stored_contract_hash + Error::Exec(execution::Error::DisabledEntity(disabled_contract_hash)) + if disabled_contract_hash == stored_entity_hash ), "expected disabled contract error, found {:?}", error @@ -599,7 +600,7 @@ fn administrator_account_should_disable_any_contract_used_as_session() { let enable_request = { let session_args = runtime_args! { ARG_CONTRACT_PACKAGE_HASH => do_nothing_contract_package_hash, - ARG_CONTRACT_HASH => stored_contract_hash, + ARG_CONTRACT_HASH => stored_entity_hash, }; ExecuteRequestBuilder::standard(*DEFAULT_ADMIN_ACCOUNT_ADDR, ENABLE_CONTRACT, session_args) @@ -620,7 +621,7 @@ fn administrator_account_should_disable_any_contract_used_as_session() { let call_delegate_by_hash = ExecuteRequestBuilder::contract_call_by_hash( *ACCOUNT_1_ADDR, - stored_contract_hash, + stored_entity_hash, DELEGATE_ENTRYPOINT, RuntimeArgs::default(), ) @@ -628,7 +629,7 @@ fn administrator_account_should_disable_any_contract_used_as_session() { let call_delegate_from_wasm = make_call_contract_session_request( *ACCOUNT_1_ADDR, - stored_contract_hash, + stored_entity_hash, DELEGATE_ENTRYPOINT, RuntimeArgs::default(), ); @@ -674,25 +675,26 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { .get_entity_by_account_hash(*ACCOUNT_1_ADDR) .expect("should have account 1 after genesis"); - let stored_contract_key = account_1_genesis + let stored_entity_key = account_1_genesis .named_keys() .get(TEST_PAYMENT_STORED_HASH_NAME) .unwrap(); - let stored_contract_hash = stored_contract_key - .into_hash() - .map(ContractHash::new) - .expect("should have stored contract hash"); + + let stored_entity_hash = stored_entity_key + .into_entity_addr() + .map(AddressableEntityHash::new) + .expect("should have stored entity hash"); let test_payment_stored_package_key = { let addressable_entity = builder - .get_addressable_entity(stored_contract_hash) + .get_addressable_entity(stored_entity_hash) .expect("should be addressable entity"); - Key::from(addressable_entity.contract_package_hash()) + Key::from(addressable_entity.package_hash()) }; let test_payment_stored_package_hash = test_payment_stored_package_key - .into_hash() - .map(ContractPackageHash::new) + .into_package_addr() + .map(PackageHash::new) .expect("should have contract package"); let contract_package_before = Package::try_from( @@ -702,7 +704,7 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { ) .expect("should be contract package"); assert!( - contract_package_before.is_contract_enabled(&stored_contract_hash), + contract_package_before.is_entity_enabled(&stored_entity_hash), "newly stored contract should be enabled" ); @@ -730,13 +732,13 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { ExecuteRequestBuilder::new().push_deploy(deploy).build() }; - builder.exec(exec_request_1).expect_success().commit(); + builder.exec(exec_request_1).expect_failure(); // Disable payment contract let disable_request = { let session_args = runtime_args! { ARG_CONTRACT_PACKAGE_HASH => test_payment_stored_package_hash, - ARG_CONTRACT_HASH => stored_contract_hash, + ARG_CONTRACT_HASH => stored_entity_hash, }; ExecuteRequestBuilder::standard(*DEFAULT_ADMIN_ACCOUNT_ADDR, DISABLE_CONTRACT, session_args) @@ -756,7 +758,7 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { contract_package_before, contract_package_after_disable, "contract package should be disabled" ); - assert!(!contract_package_after_disable.is_contract_enabled(&stored_contract_hash),); + assert!(!contract_package_after_disable.is_entity_enabled(&stored_entity_hash),); let call_stored_payment_requests_1 = { let payment_args = runtime_args! { @@ -789,7 +791,7 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { let deploy = DeployItemBuilder::new() .with_address(sender) .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) - .with_stored_payment_hash(stored_contract_hash, PAY_ENTRYPOINT, payment_args) + .with_stored_payment_hash(stored_entity_hash, PAY_ENTRYPOINT, payment_args) .with_authorization_keys(&[sender]) .with_deploy_hash(deploy_hash) .build(); @@ -805,8 +807,8 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { assert!( matches!( error, - Error::Exec(execution::Error::DisabledContract(disabled_contract_hash)) - if disabled_contract_hash == stored_contract_hash + Error::Exec(execution::Error::DisabledEntity(disabled_contract_hash)) + if disabled_contract_hash == stored_entity_hash ), "expected disabled contract error, found {:?}", error @@ -817,7 +819,7 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { let enable_request = { let session_args = runtime_args! { ARG_CONTRACT_PACKAGE_HASH => test_payment_stored_package_hash, - ARG_CONTRACT_HASH => stored_contract_hash, + ARG_CONTRACT_HASH => stored_entity_hash, }; ExecuteRequestBuilder::standard(*DEFAULT_ADMIN_ACCOUNT_ADDR, ENABLE_CONTRACT, session_args) @@ -857,7 +859,7 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { let deploy = DeployItemBuilder::new() .with_address(sender) .with_session_bytes(wasm_utils::do_minimum_bytes(), session_args) - .with_stored_payment_hash(stored_contract_hash, PAY_ENTRYPOINT, payment_args) + .with_stored_payment_hash(stored_entity_hash, PAY_ENTRYPOINT, payment_args) .with_authorization_keys(&[sender]) .with_deploy_hash(deploy_hash) .build(); @@ -868,7 +870,7 @@ fn administrator_account_should_disable_any_contract_used_as_payment() { }; for exec_request in call_stored_payment_requests_2 { - builder.exec(exec_request).expect_success().commit(); + builder.exec(exec_request).expect_failure(); } } @@ -935,7 +937,7 @@ fn should_not_allow_delegate_on_private_chain() { fn make_call_contract_session_request( account_hash: AccountHash, - contract_hash: ContractHash, + contract_hash: AddressableEntityHash, entrypoint: &str, arguments: RuntimeArgs, ) -> ExecuteRequest { 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 c0783bbad0..067c4183e7 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 @@ -491,11 +491,8 @@ fn should_not_allow_payment_to_purse_in_stored_payment() { let error = builder.get_error().expect("should have error"); assert!( - matches!( - error, - Error::Exec(execution::Error::Revert(revert)) if revert == mint::Error::DisabledUnrestrictedTransfers.into() - ), - "expected DisabledUnrestrictedTransfers error, found {:?}", + matches!(error, Error::Exec(execution::Error::ForgedReference(_))), + "expected InvalidContext error, found {:?}", error ); } 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 943b8a7ae0..7932f0ef41 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1071.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1071.rs @@ -32,7 +32,7 @@ fn should_run_ee_1071_regression() { .named_keys() .get(CONTRACT_HASH_NAME) .expect("should have hash")) - .into_hash() + .into_entity_addr() .expect("should be hash") .into(); 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 c0bfc897a9..88025a5e38 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1129.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1129.rs @@ -90,7 +90,7 @@ fn should_run_ee_1129_underfunded_delegate_call() { builder.exec(exec_request).commit(); let error = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have results") .get(0) .expect("should have first result") @@ -154,7 +154,7 @@ fn should_run_ee_1129_underfunded_add_bid_call() { builder.exec(exec_request).commit(); let error = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have results") .get(0) .expect("should have first result") @@ -202,7 +202,7 @@ fn should_run_ee_1129_underfunded_mint_contract_call() { builder.exec(exec_request).commit(); let error = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have results") .get(0) .expect("should have first result") @@ -250,7 +250,7 @@ fn should_not_panic_when_calling_session_contract_by_uref() { builder.exec(exec_request).commit(); let error = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have results") .get(0) .expect("should have first result") @@ -296,7 +296,7 @@ fn should_not_panic_when_calling_payment_contract_by_uref() { builder.exec(exec_request).commit(); let error = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have results") .get(0) .expect("should have first result") @@ -349,7 +349,7 @@ fn should_not_panic_when_calling_contract_package_by_uref() { builder.exec(exec_request).commit(); let error = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have results") .get(0) .expect("should have first result") @@ -400,7 +400,7 @@ fn should_not_panic_when_calling_payment_versioned_contract_by_uref() { builder.exec(exec_request).commit(); let error = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have results") .get(0) .expect("should have first result") @@ -455,7 +455,7 @@ fn should_not_panic_when_calling_module_without_memory() { builder.exec(exec_request).commit(); let error = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have results") .get(0) .expect("should have first result") 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 03af3555a5..8c42a3b43f 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_1174.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_1174.rs @@ -42,7 +42,7 @@ fn should_run_ee_1174_delegation_rate_too_high() { builder.exec(add_bid_request).commit(); let error = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have results") .get(0) .expect("should have first result") 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 0285e517a9..1d18a0dd61 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_460.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_460.rs @@ -2,7 +2,7 @@ use casper_engine_test_support::{ ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, PRODUCTION_RUN_GENESIS_REQUEST, }; -use casper_types::{execution::TransformKind, runtime_args, U512}; +use casper_types::{execution::TransformKind, package::PackageKindTag, runtime_args, Key, U512}; const CONTRACT_EE_460_REGRESSION: &str = "ee_460_regression.wasm"; @@ -28,13 +28,14 @@ fn should_run_ee_460_no_side_effects_on_error_regression() { // mint uref, which should mean no new purses are created in case of // transfer error. This is considered sufficient cause to confirm that the // mint uref is left untouched. - let mint_contract_uref = builder.get_mint_contract_hash(); + let mint_entity_key = + Key::addressable_entity_key(PackageKindTag::System, builder.get_mint_contract_hash()); let effects = &builder.get_effects()[0]; let mint_transforms = effects .transforms() .iter() - .find(|transform| transform.key() == &mint_contract_uref.into()) + .find(|transform| transform.key() == &mint_entity_key) // Skips the Identity writes introduced since payment code execution for brevity of the // check .filter(|transform| transform.kind() != &TransformKind::Identity); 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 3872214f27..71705a91ce 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_572.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_572.rs @@ -72,7 +72,7 @@ fn should_run_ee_572_regression() { ACCOUNT_2_ADDR, CONTRACT_ESCALATE, runtime_args! { - "contract_hash" => contract.into_hash().expect("should be hash"), + "contract_hash" => contract.into_entity_addr().expect("should be hash"), }, ) .build(); 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 4fde259d8a..1402261217 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_599.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_599.rs @@ -75,7 +75,7 @@ fn should_not_be_able_to_transfer_funds_with_transfer_purse_to_purse() { let exec_request_3 = { let args = runtime_args! { "method" => "call", - "contract_key" => transfer_funds.into_hash().expect("should be hash"), + "contract_key" => transfer_funds.into_entity_addr().expect("should be hash"), "sub_contract_method_fwd" => "transfer_from_purse_to_purse_ext", }; ExecuteRequestBuilder::standard(VICTIM_ADDR, CONTRACT_EE_599_REGRESSION, args).build() @@ -135,7 +135,7 @@ fn should_not_be_able_to_transfer_funds_with_transfer_from_purse_to_account() { let exec_request_3 = { let args = runtime_args! { "method" => "call".to_string(), - "contract_key" => transfer_funds.into_hash().expect("should get key"), + "contract_key" => transfer_funds.into_entity_addr().expect("should get key"), "sub_contract_method_fwd" => "transfer_from_purse_to_account_ext", }; ExecuteRequestBuilder::standard(VICTIM_ADDR, CONTRACT_EE_599_REGRESSION, args).build() @@ -203,7 +203,7 @@ fn should_not_be_able_to_transfer_funds_with_transfer_to_account() { let exec_request_3 = { let args = runtime_args! { "method" => "call", - "contract_key" => transfer_funds.into_hash().expect("should be hash"), + "contract_key" => transfer_funds.into_entity_addr().expect("should be hash"), "sub_contract_method_fwd" => "transfer_to_account_ext", }; ExecuteRequestBuilder::standard(VICTIM_ADDR, CONTRACT_EE_599_REGRESSION, args).build() @@ -263,7 +263,7 @@ fn should_not_be_able_to_get_main_purse_in_invalid_builder() { let exec_request_3 = { let args = runtime_args! { "method" => "call".to_string(), - "contract_key" => transfer_funds.into_hash().expect("should be hash"), + "contract_key" => transfer_funds.into_entity_addr().expect("should be hash"), "sub_contract_method_fwd" => "transfer_to_account_ext", }; ExecuteRequestBuilder::standard(VICTIM_ADDR, CONTRACT_EE_599_REGRESSION, args).build() 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 4fe54478e0..674bbba3f3 100644 --- a/execution_engine_testing/tests/src/test/regression/ee_601.rs +++ b/execution_engine_testing/tests/src/test/regression/ee_601.rs @@ -3,7 +3,8 @@ use casper_engine_test_support::{ DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_types::{ - execution::TransformKind, runtime_args, CLValue, Key, RuntimeArgs, StoredValue, + execution::TransformKind, package::PackageKindTag, runtime_args, CLValue, Key, RuntimeArgs, + StoredValue, }; const ARG_AMOUNT: &str = "amount"; @@ -34,16 +35,17 @@ fn should_run_ee_601_pay_session_new_uref_collision() { .run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST) .exec(exec_request); - let contract_key: Key = builder - .get_contract_hash_by_account_hash(*DEFAULT_ACCOUNT_ADDR) - .expect("must have contract hash associated with default account") - .into(); + let entity_hash = builder + .get_entity_hash_by_account_hash(*DEFAULT_ACCOUNT_ADDR) + .expect("must have contract hash associated with default account"); + + let entity_key = Key::addressable_entity_key(PackageKindTag::Account, entity_hash); let effects = &builder.get_effects()[0]; let mut add_keys_iter = effects .transforms() .iter() - .filter(|transform| transform.key() == &contract_key) + .filter(|transform| transform.key() == &entity_key) .map(|transform| transform.kind()); let payment_uref = match add_keys_iter.next().unwrap() { TransformKind::AddKeys(named_keys) => named_keys.get("new_uref_result-payment").unwrap(), 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 9ac58ef554..f00c418f04 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1470.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1470.rs @@ -12,7 +12,7 @@ use casper_types::{ account::AccountHash, runtime_args, system::{auction, auction::DelegationRate, mint}, - AccessRights, CLTyped, CLValue, ContractHash, ContractPackageHash, Digest, EraId, Key, + AccessRights, AddressableEntityHash, CLTyped, CLValue, Digest, EraId, Key, PackageHash, ProtocolVersion, RuntimeArgs, StoredValue, StoredValueTypeMismatch, URef, U512, }; @@ -117,29 +117,29 @@ fn gh_1470_call_contract_should_verify_group_access() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("must have default contract package"); - let contract_hash_key = account + let entity_hash_key = account .named_keys() .get(gh_1470_regression::CONTRACT_HASH_NAME) .cloned() .unwrap(); - let contract_hash = contract_hash_key - .into_hash() - .map(ContractHash::new) + let entity_hash = entity_hash_key + .into_entity_addr() + .map(AddressableEntityHash::new) .unwrap(); - let contract_package_hash_key = account + let package_hash_key = account .named_keys() - .get(gh_1470_regression::CONTRACT_PACKAGE_HASH_NAME) + .get(gh_1470_regression::PACKAGE_HASH_NAME) .cloned() .unwrap(); - let contract_package_hash = contract_package_hash_key - .into_hash() - .map(ContractPackageHash::new) + let package_hash = package_hash_key + .into_package_addr() + .map(PackageHash::new) .unwrap(); let call_contract_request = { let args = runtime_args! { gh_1470_regression_call::ARG_TEST_METHOD => gh_1470_regression_call::METHOD_CALL_DO_NOTHING, - gh_1470_regression_call::ARG_CONTRACT_HASH => contract_hash, + gh_1470_regression_call::ARG_CONTRACT_HASH => entity_hash, }; ExecuteRequestBuilder::standard(ACCOUNT_1_ADDR, GH_1470_REGRESSION_CALL, args).build() }; @@ -147,7 +147,7 @@ fn gh_1470_call_contract_should_verify_group_access() { builder.exec(call_contract_request).commit(); let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last response"); assert_eq!(response.len(), 1); let exec_response = response.last().expect("should have response"); @@ -159,7 +159,7 @@ fn gh_1470_call_contract_should_verify_group_access() { let call_versioned_contract_request = { let args = runtime_args! { gh_1470_regression_call::ARG_TEST_METHOD => gh_1470_regression_call::METHOD_CALL_VERSIONED_DO_NOTHING, - gh_1470_regression_call::ARG_CONTRACT_PACKAGE_HASH => contract_package_hash, + gh_1470_regression_call::ARG_CONTRACT_PACKAGE_HASH => package_hash, }; ExecuteRequestBuilder::standard(ACCOUNT_1_ADDR, GH_1470_REGRESSION_CALL, args).build() }; @@ -167,7 +167,7 @@ fn gh_1470_call_contract_should_verify_group_access() { builder.exec(call_versioned_contract_request).commit(); let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last response"); assert_eq!(response.len(), 1); let exec_response = response.last().expect("should have response"); @@ -326,24 +326,24 @@ fn gh_1470_call_contract_should_ignore_optional_args() { .get(gh_1470_regression::CONTRACT_HASH_NAME) .cloned() .unwrap(); - let contract_hash = contract_hash_key - .into_hash() - .map(ContractHash::new) + let entity_hash = contract_hash_key + .into_entity_addr() + .map(AddressableEntityHash::new) .unwrap(); - let contract_package_hash_key = account + let package_hash_key = account .named_keys() - .get(gh_1470_regression::CONTRACT_PACKAGE_HASH_NAME) + .get(gh_1470_regression::PACKAGE_HASH_NAME) .cloned() .unwrap(); - let contract_package_hash = contract_package_hash_key - .into_hash() - .map(ContractPackageHash::new) + let package_hash = package_hash_key + .into_package_addr() + .map(PackageHash::new) .unwrap(); let call_contract_request = { let args = runtime_args! { gh_1470_regression_call::ARG_TEST_METHOD => gh_1470_regression_call::METHOD_CALL_DO_NOTHING_NO_OPTIONALS, - gh_1470_regression_call::ARG_CONTRACT_HASH => contract_hash, + gh_1470_regression_call::ARG_CONTRACT_HASH => entity_hash, }; ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, GH_1470_REGRESSION_CALL, args) .build() @@ -357,7 +357,7 @@ fn gh_1470_call_contract_should_ignore_optional_args() { let call_versioned_contract_request = { let args = runtime_args! { gh_1470_regression_call::ARG_TEST_METHOD => gh_1470_regression_call::METHOD_CALL_VERSIONED_DO_NOTHING_NO_OPTIONALS, - gh_1470_regression_call::ARG_CONTRACT_PACKAGE_HASH => contract_package_hash, + gh_1470_regression_call::ARG_CONTRACT_PACKAGE_HASH => package_hash, }; ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, GH_1470_REGRESSION_CALL, args) .build() @@ -392,24 +392,24 @@ fn gh_1470_call_contract_should_not_accept_extra_args() { .get(gh_1470_regression::CONTRACT_HASH_NAME) .cloned() .unwrap(); - let contract_hash = contract_hash_key - .into_hash() - .map(ContractHash::new) + let entity_hash = contract_hash_key + .into_entity_addr() + .map(AddressableEntityHash::new) .unwrap(); - let contract_package_hash_key = account + let package_hash_key = account .named_keys() - .get(gh_1470_regression::CONTRACT_PACKAGE_HASH_NAME) + .get(gh_1470_regression::PACKAGE_HASH_NAME) .cloned() .unwrap(); - let contract_package_hash = contract_package_hash_key - .into_hash() - .map(ContractPackageHash::new) + let package_hash = package_hash_key + .into_package_addr() + .map(PackageHash::new) .unwrap(); let call_contract_request = { let args = runtime_args! { gh_1470_regression_call::ARG_TEST_METHOD => gh_1470_regression_call::METHOD_CALL_DO_NOTHING_EXTRA, - gh_1470_regression_call::ARG_CONTRACT_HASH => contract_hash, + gh_1470_regression_call::ARG_CONTRACT_HASH => entity_hash, }; ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, GH_1470_REGRESSION_CALL, args) .build() @@ -423,7 +423,7 @@ fn gh_1470_call_contract_should_not_accept_extra_args() { let call_versioned_contract_request = { let args = runtime_args! { gh_1470_regression_call::ARG_TEST_METHOD => gh_1470_regression_call::METHOD_CALL_VERSIONED_DO_NOTHING_EXTRA, - gh_1470_regression_call::ARG_CONTRACT_PACKAGE_HASH => contract_package_hash, + gh_1470_regression_call::ARG_CONTRACT_PACKAGE_HASH => package_hash, }; ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, GH_1470_REGRESSION_CALL, args) .build() @@ -453,30 +453,30 @@ fn gh_1470_call_contract_should_verify_wrong_argument_types() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("must have contract"); - let contract_hash_key = account + let entity_hash_key = account .named_keys() .get(gh_1470_regression::CONTRACT_HASH_NAME) .cloned() .unwrap(); - let contract_hash = contract_hash_key - .into_hash() - .map(ContractHash::new) + let entity_hash = entity_hash_key + .into_entity_addr() + .map(AddressableEntityHash::new) .unwrap(); - let contract_package_hash_key = account + let package_hash_key = account .named_keys() - .get(gh_1470_regression::CONTRACT_PACKAGE_HASH_NAME) + .get(gh_1470_regression::PACKAGE_HASH_NAME) .cloned() .unwrap(); - let contract_package_hash = contract_package_hash_key - .into_hash() - .map(ContractPackageHash::new) + let package_hash = package_hash_key + .into_package_addr() + .map(PackageHash::new) .unwrap(); let call_contract_request = { let args = runtime_args! { gh_1470_regression_call::ARG_TEST_METHOD => gh_1470_regression_call::METHOD_CALL_DO_NOTHING_TYPE_MISMATCH, - gh_1470_regression_call::ARG_CONTRACT_HASH => contract_hash, }; + gh_1470_regression_call::ARG_CONTRACT_HASH => entity_hash, }; ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, GH_1470_REGRESSION_CALL, args) .build() }; @@ -484,7 +484,7 @@ fn gh_1470_call_contract_should_verify_wrong_argument_types() { builder.exec(call_contract_request).commit(); let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last response"); assert_eq!(response.len(), 1); let exec_response = response.last().expect("should have response"); @@ -497,7 +497,7 @@ fn gh_1470_call_contract_should_verify_wrong_argument_types() { let args = runtime_args! { gh_1470_regression_call::ARG_TEST_METHOD => gh_1470_regression_call::METHOD_CALL_VERSIONED_DO_NOTHING_TYPE_MISMATCH, - gh_1470_regression_call::ARG_CONTRACT_PACKAGE_HASH => contract_package_hash, }; + gh_1470_regression_call::ARG_CONTRACT_PACKAGE_HASH => package_hash, }; ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, GH_1470_REGRESSION_CALL, args) .build() }; @@ -505,7 +505,7 @@ fn gh_1470_call_contract_should_verify_wrong_argument_types() { builder.exec(call_versioned_contract_request).commit(); let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last response"); assert_eq!(response.len(), 1); let exec_response = response.last().expect("should have response"); @@ -559,30 +559,30 @@ fn gh_1470_call_contract_should_verify_wrong_optional_argument_types() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("must have default contract package"); - let contract_hash_key = account + let entity_hash_key = account .named_keys() .get(gh_1470_regression::CONTRACT_HASH_NAME) .cloned() .unwrap(); - let contract_hash = contract_hash_key - .into_hash() - .map(ContractHash::new) + let entity_hash = entity_hash_key + .into_entity_addr() + .map(AddressableEntityHash::new) .unwrap(); - let contract_package_hash_key = account + let package_hash_key = account .named_keys() - .get(gh_1470_regression::CONTRACT_PACKAGE_HASH_NAME) + .get(gh_1470_regression::PACKAGE_HASH_NAME) .cloned() .unwrap(); - let contract_package_hash = contract_package_hash_key - .into_hash() - .map(ContractPackageHash::new) + let package_hash = package_hash_key + .into_package_addr() + .map(PackageHash::new) .unwrap(); let call_contract_request = { let args = runtime_args! { gh_1470_regression_call::ARG_TEST_METHOD => gh_1470_regression_call::METHOD_CALL_DO_NOTHING_OPTIONAL_TYPE_MISMATCH, - gh_1470_regression_call::ARG_CONTRACT_HASH => contract_hash, + gh_1470_regression_call::ARG_CONTRACT_HASH => entity_hash, }; ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, GH_1470_REGRESSION_CALL, args) .build() @@ -591,7 +591,7 @@ fn gh_1470_call_contract_should_verify_wrong_optional_argument_types() { builder.exec(call_contract_request).commit(); let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last response"); assert_eq!(response.len(), 1); let exec_response = response.last().expect("should have response"); @@ -603,7 +603,7 @@ fn gh_1470_call_contract_should_verify_wrong_optional_argument_types() { let call_versioned_contract_request = { let args = runtime_args! { gh_1470_regression_call::ARG_TEST_METHOD => gh_1470_regression_call::METHOD_CALL_VERSIONED_DO_NOTHING_OPTIONAL_TYPE_MISMATCH, - gh_1470_regression_call::ARG_CONTRACT_PACKAGE_HASH => contract_package_hash, + gh_1470_regression_call::ARG_CONTRACT_PACKAGE_HASH => package_hash, }; ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, GH_1470_REGRESSION_CALL, args) .build() @@ -612,7 +612,7 @@ fn gh_1470_call_contract_should_verify_wrong_optional_argument_types() { builder.exec(call_versioned_contract_request).commit(); let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last response"); assert_eq!(response.len(), 1); let exec_response = response.last().expect("should have response"); @@ -686,6 +686,9 @@ fn should_transfer_after_major_version_bump_from_1_2_0() { let transfer = ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_args) .with_protocol_version(new_protocol_version) .build(); + + println!("About to execute"); + builder.exec(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 a7ef271a48..ae28fc58b4 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1688.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1688.rs @@ -4,7 +4,7 @@ use casper_engine_test_support::{ }; use casper_execution_engine::engine_state::ExecuteRequest; use casper_types::{ - runtime_args, system::standard_payment::ARG_AMOUNT, ContractHash, ContractPackageHash, + runtime_args, system::standard_payment::ARG_AMOUNT, AddressableEntityHash, PackageHash, RuntimeArgs, }; @@ -12,10 +12,10 @@ const GH_1688_REGRESSION: &str = "gh_1688_regression.wasm"; const METHOD_PUT_KEY: &str = "put_key"; const NEW_KEY_NAME: &str = "Hello"; -const CONTRACT_PACKAGE_KEY: &str = "contract_package"; +const PACKAGE_KEY: &str = "contract_package"; const CONTRACT_HASH_KEY: &str = "contract_hash"; -fn setup() -> (LmdbWasmTestBuilder, ContractPackageHash, ContractHash) { +fn setup() -> (LmdbWasmTestBuilder, PackageHash, AddressableEntityHash) { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); @@ -35,30 +35,30 @@ fn setup() -> (LmdbWasmTestBuilder, ContractPackageHash, ContractHash) { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .unwrap(); - let contract_package_hash_key = account + let package_hash_key = account .named_keys() - .get(CONTRACT_PACKAGE_KEY) + .get(PACKAGE_KEY) .expect("should have package hash"); - let contract_hash_key = account + let entity_hash_key = account .named_keys() .get(CONTRACT_HASH_KEY) .expect("should have hash"); - let contract_package_hash = contract_package_hash_key - .into_hash() - .map(ContractPackageHash::new) + let contract_package_hash = package_hash_key + .into_package_addr() + .map(PackageHash::new) .expect("should be hash"); - let contract_hash = contract_hash_key - .into_hash() - .map(ContractHash::new) + let entity_hash = entity_hash_key + .into_entity_addr() + .map(AddressableEntityHash::new) .expect("should be hash"); - (builder, contract_package_hash, contract_hash) + (builder, contract_package_hash, entity_hash) } -fn test(request_builder: impl FnOnce(ContractPackageHash, ContractHash) -> ExecuteRequest) { +fn test(request_builder: impl FnOnce(PackageHash, AddressableEntityHash) -> ExecuteRequest) { let (mut builder, contract_package_hash, contract_hash) = setup(); let exec_request = request_builder(contract_package_hash, contract_hash); @@ -113,7 +113,7 @@ fn should_run_gh_1688_regression_stored_versioned_contract_by_name() { let deploy = DeployItemBuilder::new() .with_address(*DEFAULT_ACCOUNT_ADDR) .with_stored_versioned_contract_by_name( - CONTRACT_PACKAGE_KEY, + PACKAGE_KEY, None, METHOD_PUT_KEY, RuntimeArgs::default(), 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 87a6a99b59..476208dfae 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_1931.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_1931.rs @@ -33,5 +33,5 @@ fn should_query_contract_package() { .query(None, contract_package_hash, &[]) .expect("failed to find contract package"); - assert!(matches!(contract_package, StoredValue::ContractPackage(_))); + assert!(matches!(contract_package, StoredValue::Package(_))); } 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 75f2f0fa1a..0a70f7adf7 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_2280.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_2280.rs @@ -7,9 +7,9 @@ use casper_engine_test_support::{ PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_types::{ - account::AccountHash, runtime_args, system::mint, ContractHash, EraId, Gas, HostFunction, - HostFunctionCost, HostFunctionCosts, Key, MintCosts, Motes, ProtocolVersion, PublicKey, - SecretKey, SystemConfig, UpgradeConfig, WasmConfig, DEFAULT_MAX_STACK_HEIGHT, + account::AccountHash, runtime_args, system::mint, AddressableEntityHash, EraId, Gas, + HostFunction, HostFunctionCost, HostFunctionCosts, Key, MintCosts, Motes, ProtocolVersion, + PublicKey, SecretKey, SystemConfig, UpgradeConfig, WasmConfig, DEFAULT_MAX_STACK_HEIGHT, DEFAULT_WASM_MAX_MEMORY, U512, }; @@ -696,7 +696,7 @@ fn gh_2280_stored_faucet_call_should_cost_the_same() { } struct TestContext { - gh_2280_regression: ContractHash, + gh_2280_regression: AddressableEntityHash, } fn setup() -> (LmdbWasmTestBuilder, TestContext) { @@ -723,8 +723,8 @@ fn setup() -> (LmdbWasmTestBuilder, TestContext) { .named_keys() .get(HASH_KEY_NAME) .cloned() - .and_then(Key::into_hash) - .map(ContractHash::new) + .and_then(Key::into_entity_addr) + .map(AddressableEntityHash::new) .expect("should have key"); (builder, TestContext { gh_2280_regression }) 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 0e7f5705cd..6fa2123a37 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_3097.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_3097.rs @@ -3,9 +3,9 @@ use casper_engine_test_support::{ PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_types::{ - runtime_args, ContractHash, ContractPackageHash, ContractVersionKey, RuntimeArgs, + runtime_args, AddressableEntityHash, EntityVersionKey, PackageHash, RuntimeArgs, }; -use gh_1470_regression::CONTRACT_PACKAGE_HASH_NAME; +use gh_1470_regression::PACKAGE_HASH_NAME; const GH_3097_REGRESSION_WASM: &str = "gh_3097_regression.wasm"; const GH_3097_REGRESSION_CALL_WASM: &str = "gh_3097_regression_call.wasm"; @@ -45,29 +45,29 @@ fn should_run_regression() { .named_keys() .get(DISABLED_CONTRACT_HASH_KEY) .unwrap() - .into_hash() - .map(ContractHash::new) + .into_entity_addr() + .map(AddressableEntityHash::new) .unwrap(); let enabled_contract_hash = account .named_keys() .get(ENABLED_CONTRACT_HASH_KEY) .unwrap() - .into_hash() - .map(ContractHash::new) + .into_entity_addr() + .map(AddressableEntityHash::new) .unwrap(); let contract_package_hash = account .named_keys() .get(CONTRACT_PACKAGE_HASH_KEY) .unwrap() - .into_hash() - .map(ContractPackageHash::new) + .into_package_addr() + .map(PackageHash::new) .unwrap(); // Versioned contract calls by name let direct_call_latest_request = ExecuteRequestBuilder::versioned_contract_call_by_name( *DEFAULT_ACCOUNT_ADDR, - CONTRACT_PACKAGE_HASH_NAME, + PACKAGE_HASH_NAME, None, DO_SOMETHING_ENTRYPOINT, RuntimeArgs::new(), @@ -76,7 +76,7 @@ fn should_run_regression() { let direct_call_v2_request = ExecuteRequestBuilder::versioned_contract_call_by_name( *DEFAULT_ACCOUNT_ADDR, - CONTRACT_PACKAGE_HASH_NAME, + PACKAGE_HASH_NAME, Some(2), DO_SOMETHING_ENTRYPOINT, RuntimeArgs::new(), @@ -85,7 +85,7 @@ fn should_run_regression() { let direct_call_v1_request = ExecuteRequestBuilder::versioned_contract_call_by_name( *DEFAULT_ACCOUNT_ADDR, - CONTRACT_PACKAGE_HASH_NAME, + PACKAGE_HASH_NAME, Some(1), DO_SOMETHING_ENTRYPOINT, RuntimeArgs::new(), @@ -112,9 +112,9 @@ fn should_run_regression() { matches!( error, casper_execution_engine::engine_state::Error::Exec( - casper_execution_engine::execution::Error::InvalidContractVersion(version) + casper_execution_engine::execution::Error::InvalidEntityVersion(version) ) - if version == ContractVersionKey::new(1, 1), + if version == EntityVersionKey::new(1, 1), ), "Expected invalid contract version, found {:?}", error, @@ -169,9 +169,9 @@ fn should_run_regression() { matches!( error, casper_execution_engine::engine_state::Error::Exec( - casper_execution_engine::execution::Error::InvalidContractVersion(version) + casper_execution_engine::execution::Error::InvalidEntityVersion(version) ) - if version == ContractVersionKey::new(1, 1), + if version == EntityVersionKey::new(1, 1), ), "Expected invalid contract version, found {:?}", error, @@ -229,9 +229,9 @@ fn should_run_regression() { matches!( error, casper_execution_engine::engine_state::Error::Exec( - casper_execution_engine::execution::Error::InvalidContractVersion(version) + casper_execution_engine::execution::Error::InvalidEntityVersion(version) ) - if version == ContractVersionKey::new(1, 1), + if version == EntityVersionKey::new(1, 1), ), "Expected invalid contract version, found {:?}", error, @@ -282,7 +282,7 @@ fn should_run_regression() { matches!( error, casper_execution_engine::engine_state::Error::Exec( - casper_execution_engine::execution::Error::DisabledContract(contract_hash) + casper_execution_engine::execution::Error::DisabledEntity(contract_hash) ) if contract_hash == disabled_contract_hash ), @@ -308,7 +308,7 @@ fn should_run_regression() { matches!( error, casper_execution_engine::engine_state::Error::Exec( - casper_execution_engine::execution::Error::DisabledContract(contract_hash) + casper_execution_engine::execution::Error::DisabledEntity(contract_hash) ) if contract_hash == disabled_contract_hash ), @@ -348,7 +348,7 @@ fn should_run_regression() { matches!( error, casper_execution_engine::engine_state::Error::Exec( - casper_execution_engine::execution::Error::DisabledContract(contract_hash) + casper_execution_engine::execution::Error::DisabledEntity(contract_hash) ) if contract_hash == disabled_contract_hash ), 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 1441382caa..a97b4cdca0 100644 --- a/execution_engine_testing/tests/src/test/regression/gh_3710.rs +++ b/execution_engine_testing/tests/src/test/regression/gh_3710.rs @@ -239,8 +239,12 @@ fn gh_3710_should_produce_era_summary_in_a_step() { mod fixture { use std::collections::BTreeMap; - use casper_engine_test_support::{DEFAULT_ACCOUNT_PUBLIC_KEY, PRODUCTION_RUN_GENESIS_REQUEST}; + use casper_engine_test_support::{ + ExecuteRequestBuilder, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY, + PRODUCTION_RUN_GENESIS_REQUEST, + }; use casper_types::{ + runtime_args, system::auction::{EraInfo, SeigniorageAllocation}, EraId, Key, KeyTag, StoredValue, U512, }; @@ -248,10 +252,37 @@ mod fixture { use super::{FIXTURE_N_ERAS, GH_3710_FIXTURE}; use crate::lmdb_fixture; + #[ignore = "RUN_FIXTURE_GENERATORS env var should be enabled"] + #[test] + fn generate_call_stack_fixture() { + const CALL_STACK_FIXTURE: &str = "call_stack_fixture"; + const CONTRACT_RECURSIVE_SUBCALL: &str = "get_call_stack_recursive_subcall.wasm"; + + if !lmdb_fixture::is_fixture_generator_enabled() { + println!("Enable the RUN_FIXTURE_GENERATORS variable"); + return; + } + + let genesis_request = PRODUCTION_RUN_GENESIS_REQUEST.clone(); + + lmdb_fixture::generate_fixture(CALL_STACK_FIXTURE, genesis_request, |builder| { + let execute_request = ExecuteRequestBuilder::standard( + *DEFAULT_ACCOUNT_ADDR, + CONTRACT_RECURSIVE_SUBCALL, + runtime_args! {}, + ) + .build(); + + builder.exec(execute_request).expect_success().commit(); + }) + .unwrap(); + } + #[ignore = "RUN_FIXTURE_GENERATORS env var should be enabled"] #[test] fn generate_era_info_bloat_fixture() { if !lmdb_fixture::is_fixture_generator_enabled() { + println!("Enable the RUN_FIXTURE_GENERATORS variable"); return; } // To generate this fixture again you have to re-run this code release-1.4.13. 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 621de0d085..ade932341b 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 @@ -22,7 +22,7 @@ const CONTRACT_TRANSFER_TO_ACCOUNT_U512: &str = "transfer_to_account_u512.wasm"; // This value is not systemic, as code is added the size of WASM will increase, // you can change this value to reflect the increase in WASM size. const HOST_FUNCTION_METRICS_STANDARD_SIZE: usize = 97_569; -const HOST_FUNCTION_METRICS_STANDARD_GAS_COST: u64 = 347_080_271_020; +const HOST_FUNCTION_METRICS_STANDARD_GAS_COST: u64 = 364_682_740_480; /// Acceptable size regression/improvement in percentage. const SIZE_MARGIN: usize = 5; 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 d60c790371..00ab37b26e 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20210707.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20210707.rs @@ -8,7 +8,7 @@ use casper_execution_engine::{ }; use casper_types::{ account::AccountHash, runtime_args, system::mint, AccessRights, AddressableEntity, - ContractHash, PublicKey, RuntimeArgs, SecretKey, URef, U512, + AddressableEntityHash, PublicKey, RuntimeArgs, SecretKey, URef, U512, }; use once_cell::sync::Lazy; @@ -65,14 +65,14 @@ fn transfer(sender: AccountHash, target: AccountHash, amount: u64) -> ExecuteReq .build() } -fn get_account_contract_hash(contract: &AddressableEntity) -> ContractHash { - contract +fn get_account_entity_hash(entity: &AddressableEntity) -> AddressableEntityHash { + entity .named_keys() .get(CONTRACT_HASH_NAME) .cloned() .expect("should have contract hash") - .into_hash() - .map(ContractHash::new) + .into_entity_addr() + .map(AddressableEntityHash::new) .unwrap() } @@ -105,7 +105,7 @@ fn should_transfer_funds_from_contract_to_new_account() { let account = builder.get_expected_addressable_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR); - let contract_hash = get_account_contract_hash(&account); + let contract_hash = get_account_entity_hash(&account); assert!(builder.get_entity_by_account_hash(*BOB_ADDR).is_none()); @@ -150,7 +150,7 @@ fn should_transfer_funds_from_contract_to_existing_account() { let account = builder.get_expected_addressable_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR); - let contract_hash = get_account_contract_hash(&account); + let contract_hash = get_account_entity_hash(&account); let call_request = ExecuteRequestBuilder::contract_call_by_hash( *DEFAULT_ACCOUNT_ADDR, @@ -236,7 +236,7 @@ fn should_not_transfer_funds_from_forged_purse_to_owned_purse() { let bob = builder.get_expected_addressable_entity_by_account_hash(*BOB_ADDR); let bob_main_purse = bob.main_purse(); - let contract_hash = get_account_contract_hash(&account); + let contract_hash = get_account_entity_hash(&account); let call_request = ExecuteRequestBuilder::contract_call_by_hash( *DEFAULT_ACCOUNT_ADDR, @@ -279,7 +279,7 @@ fn should_not_transfer_funds_into_bob_purse() { let bob = builder.get_expected_addressable_entity_by_account_hash(*BOB_ADDR); let bob_main_purse = bob.main_purse(); - let contract_hash = get_account_contract_hash(&account); + let contract_hash = get_account_entity_hash(&account); let call_request = ExecuteRequestBuilder::contract_call_by_hash( *DEFAULT_ACCOUNT_ADDR, @@ -319,7 +319,7 @@ fn should_not_transfer_from_hardcoded_purse() { let account = builder.get_expected_addressable_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR); - let contract_hash = get_account_contract_hash(&account); + let contract_hash = get_account_entity_hash(&account); let call_request = ExecuteRequestBuilder::contract_call_by_hash( *DEFAULT_ACCOUNT_ADDR, @@ -368,7 +368,7 @@ fn should_not_refund_to_bob_and_charge_alice() { let bob = builder.get_expected_addressable_entity_by_account_hash(*BOB_ADDR); let bob_main_purse = bob.main_purse(); - let contract_hash = get_account_contract_hash(&account); + let contract_hash = get_account_entity_hash(&account); let call_request = { let args = runtime_args! { @@ -424,7 +424,7 @@ fn should_not_charge_alice_for_execution() { let bob = builder.get_expected_addressable_entity_by_account_hash(*BOB_ADDR); let bob_main_purse = bob.main_purse(); - let contract_hash = get_account_contract_hash(&account); + let contract_hash = get_account_entity_hash(&account); let call_request = { let args = runtime_args! { @@ -477,7 +477,7 @@ fn should_not_charge_for_execution_from_hardcoded_purse() { let account = builder.get_expected_addressable_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR); - let contract_hash = get_account_contract_hash(&account); + let contract_hash = get_account_entity_hash(&account); let call_request = { let args = runtime_args! { 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 87286eb9d0..70ddb0e6ab 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20211110.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20211110.rs @@ -7,7 +7,7 @@ use casper_types::{ account::AccountHash, runtime_args, system::{mint, standard_payment}, - ContractHash, Key, U512, + AddressableEntityHash, Key, U512, }; const RECURSE_ENTRYPOINT: &str = "recurse"; @@ -64,7 +64,7 @@ fn regression_20211110() { .get(CONTRACT_HASH_NAME) .unwrap() { - Key::Hash(addr) => ContractHash::new(*addr), + Key::AddressableEntity((_, addr)) => AddressableEntityHash::new(*addr), _ => panic!("Couldn't find regression contract."), }; 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 6faca772a6..4a7a36db14 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220204.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220204.rs @@ -3,18 +3,18 @@ use casper_engine_test_support::{ PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_execution_engine::{engine_state, execution}; -use casper_types::{runtime_args, system::mint, AccessRights, ApiError, RuntimeArgs}; +use casper_types::{runtime_args, AccessRights, RuntimeArgs}; const REGRESSION_20220204_CONTRACT: &str = "regression_20220204.wasm"; const REGRESSION_20220204_CALL_CONTRACT: &str = "regression_20220204_call.wasm"; const REGRESSION_20220204_NONTRIVIAL_CONTRACT: &str = "regression_20220204_nontrivial.wasm"; -const TRANSFER_MAIN_PURSE_AS_SESSION: &str = "transfer_main_purse_as_session"; + const NONTRIVIAL_ARG_AS_CONTRACT: &str = "nontrivial_arg_as_contract"; const ARG_ENTRYPOINT: &str = "entrypoint"; const ARG_PURSE: &str = "purse"; const ARG_NEW_ACCESS_RIGHTS: &str = "new_access_rights"; const TRANSFER_AS_CONTRACT: &str = "transfer_as_contract"; -const TRANSFER_AS_SESSION: &str = "transfer_as_session"; + const CONTRACT_HASH_NAME: &str = "regression-contract-hash"; #[ignore] @@ -245,222 +245,6 @@ fn regression_20220204_as_contract_by_hash_attenuated() { ); } -#[ignore] -#[test] -fn regression_20220204_as_session() { - // Demonstrates that a stored session cannot transfer funds. - let entrypoint = TRANSFER_AS_SESSION; - let new_access_rights = AccessRights::READ_ADD_WRITE; - let mut builder = setup(); - let exec_request_1 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - REGRESSION_20220204_CALL_CONTRACT, - runtime_args! { - ARG_NEW_ACCESS_RIGHTS => new_access_rights.bits(), - ARG_ENTRYPOINT => entrypoint, - }, - ) - .build(); - builder.exec(exec_request_1).commit(); - let error = builder.get_error().expect("should have returned an error"); - assert!( - matches!( - error, - engine_state::Error::Exec(execution::Error::Revert(ApiError::Mint(mint_error))) - if mint_error == mint::Error::InvalidContext as u8 - ), - "Expected revert but received {:?}", - error - ); -} - -#[ignore] -#[test] -fn regression_20220204_as_session_attenuated() { - let contract = REGRESSION_20220204_CALL_CONTRACT; - let entrypoint = TRANSFER_AS_SESSION; - let new_access_rights = AccessRights::ADD; - let mut builder = setup(); - let exec_request_2 = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - contract, - runtime_args! { - ARG_NEW_ACCESS_RIGHTS => new_access_rights.bits(), - ARG_ENTRYPOINT => entrypoint, - }, - ) - .build(); - builder.exec(exec_request_2).commit(); - let error = builder.get_error().expect("should have returned an error"); - assert!( - matches!( - error, - engine_state::Error::Exec(execution::Error::Revert(ApiError::Mint(mint_error))) - if mint_error == mint::Error::InvalidContext as u8 - ), - "Expected revert but received {:?}", - error - ); -} - -#[ignore] -#[test] -fn regression_20220204_as_session_by_hash() { - let entrypoint = TRANSFER_AS_SESSION; - let new_access_rights = AccessRights::READ_ADD_WRITE; - let mut builder = setup(); - let account = builder - .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) - .expect("should have account"); - let main_purse = account.main_purse(); - let exec_request = ExecuteRequestBuilder::contract_call_by_name( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_HASH_NAME, - entrypoint, - runtime_args! { - ARG_NEW_ACCESS_RIGHTS => new_access_rights.bits(), - ARG_PURSE => main_purse, - }, - ) - .build(); - builder.exec(exec_request).commit(); - let error = builder.get_error().expect("should have returned an error"); - assert!( - matches!( - error, - engine_state::Error::Exec(execution::Error::Revert(ApiError::Mint(mint_error))) - if mint_error == mint::Error::InvalidContext as u8 - ), - "Expected revert but received {:?}", - error - ); -} - -#[ignore] -#[test] -fn regression_20220204_as_session_by_hash_attenuated() { - let entrypoint = TRANSFER_AS_SESSION; - let new_access_rights = AccessRights::READ; - let mut builder = setup(); - let account = builder - .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) - .expect("should have account"); - let main_purse = account.main_purse(); - let exec_request = ExecuteRequestBuilder::contract_call_by_name( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_HASH_NAME, - entrypoint, - runtime_args! { - ARG_NEW_ACCESS_RIGHTS => new_access_rights.bits(), - ARG_PURSE => main_purse, - }, - ) - .build(); - builder.exec(exec_request).commit(); - let error = builder.get_error().expect("should have returned an error"); - assert!( - matches!( - error, - engine_state::Error::Exec(execution::Error::Revert(ApiError::Mint(mint_error))) - if mint_error == mint::Error::InvalidContext as u8 - ), - "Expected revert but received {:?}", - error - ); - let entrypoint = TRANSFER_AS_SESSION; - let new_access_rights = AccessRights::ADD; - let mut builder = setup(); - let account = builder - .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) - .expect("should have account"); - let main_purse = account.main_purse(); - let exec_request = ExecuteRequestBuilder::contract_call_by_name( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_HASH_NAME, - entrypoint, - runtime_args! { - ARG_NEW_ACCESS_RIGHTS => new_access_rights.bits(), - ARG_PURSE => main_purse, - }, - ) - .build(); - builder.exec(exec_request).commit(); - let error = builder.get_error().expect("should have returned an error"); - assert!( - matches!( - error, - engine_state::Error::Exec(execution::Error::Revert(ApiError::Mint(mint_error))) - if mint_error == mint::Error::InvalidContext as u8 - ), - "Expected revert but received {:?}", - error - ); -} - -#[ignore] -#[test] -fn regression_20220204_main_purse_as_session() { - let mut builder = setup(); - - let exec_request = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - REGRESSION_20220204_CALL_CONTRACT, - runtime_args! { - ARG_NEW_ACCESS_RIGHTS => AccessRights::READ_ADD_WRITE.bits(), - ARG_ENTRYPOINT => TRANSFER_MAIN_PURSE_AS_SESSION, - }, - ) - .build(); - - builder.exec(exec_request).commit(); - - // This test fails because mint's transfer in a StoredSession is disabled for security reasons - // introduced as part of EE-1217. This assertion will serve as a reference point when the - // restriction will be lifted, and this test needs to be updated accordingly. - - let error = builder.get_error().expect("should have returned an error"); - assert!( - matches!( - error, - engine_state::Error::Exec(execution::Error::Revert(ApiError::Mint(mint_error))) - if mint_error == mint::Error::InvalidContext as u8, - ), - "Expected revert but received {:?}", - error - ); -} - -#[ignore] -#[test] -fn regression_20220204_main_purse_as_session_by_hash() { - let mut builder = setup(); - - let exec_request = ExecuteRequestBuilder::contract_call_by_name( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_HASH_NAME, - TRANSFER_MAIN_PURSE_AS_SESSION, - RuntimeArgs::default(), - ) - .build(); - - builder.exec(exec_request).commit(); - - // This test fails because mint's transfer in a StoredSession is disabled for security reasons - // introduced as part of EE-1217. This assertion will serve as a reference point when the - // restriction will be lifted, and this test needs to be updated accordingly. - - let error = builder.get_error().expect("should have returned an error"); - assert!( - matches!( - error, - engine_state::Error::Exec(execution::Error::Revert(ApiError::Mint(mint_error))) - if mint_error == mint::Error::InvalidContext as u8, - ), - "Expected revert but received {:?}", - error - ); -} - fn setup() -> LmdbWasmTestBuilder { let mut builder = LmdbWasmTestBuilder::default(); builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); 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 bae36f26cf..f9dda5efc3 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220217.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220217.rs @@ -78,7 +78,7 @@ fn regression_20220217_transfer_mint_by_package_hash_from_main_purse() { let mint = builder .get_addressable_entity(mint_hash) .expect("should have mint contract"); - let mint_package_hash = mint.contract_package_hash(); + let mint_package_hash = mint.package_hash(); let exec_request = ExecuteRequestBuilder::versioned_contract_call_by_hash( ACCOUNT_1_ADDR, 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 f177e54c3e..0cd90f84d2 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220303.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220303.rs @@ -6,6 +6,7 @@ use std::{ use casper_engine_test_support::{LmdbWasmTestBuilder, UpgradeRequestBuilder}; use casper_execution_engine::engine_state::SystemContractRegistry; use casper_types::{ + contracts::ContractHash, system::{self, mint}, AccessRights, CLValue, Digest, EraId, Key, ProtocolVersion, StoredValue, URef, }; @@ -58,8 +59,11 @@ fn test_upgrade(major_bump: u32, minor_bump: u32, patch_bump: u32, upgrade_entri .expect("should contract hash") }; let old_protocol_version = lmdb_fixture_state.genesis_protocol_version(); + + let legacy_mint_hash = ContractHash::new(mint_contract_hash.value()); + let old_contract = builder - .get_legacy_contract(mint_contract_hash) + .get_legacy_contract(legacy_mint_hash) .expect("should have mint contract"); assert_eq!(old_contract.protocol_version(), old_protocol_version); let new_protocol_version = ProtocolVersion::from_parts( @@ -102,12 +106,12 @@ fn test_upgrade(major_bump: u32, minor_bump: u32, patch_bump: u32, upgrade_entri .get_addressable_entity(mint_contract_hash) .expect("should have mint contract"); assert_eq!( - old_contract.contract_package_hash(), - new_contract.contract_package_hash() + old_contract.contract_package_hash().value(), + new_contract.package_hash().value() ); assert_eq!( - old_contract.contract_wasm_hash(), - new_contract.contract_wasm_hash() + old_contract.contract_wasm_hash().value(), + new_contract.byte_code_hash().value() ); assert_ne!(old_contract.entry_points(), new_contract.entry_points()); assert_eq!( 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 07c8b83fc0..2ed0af92be 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 @@ -8,7 +8,8 @@ use casper_engine_test_support::{ PRODUCTION_RUN_GENESIS_REQUEST, }; use casper_types::{ - execution::TransformKind, runtime_args, system::standard_payment, ContractHash, Key, URef, U512, + execution::TransformKind, runtime_args, system::standard_payment, AddressableEntityHash, Key, + URef, U512, }; #[ignore] @@ -40,7 +41,7 @@ fn contract_transforms_should_be_ordered_in_the_effects() { .get("ordered-transforms-contract-hash") .unwrap() { - Key::Hash(addr) => ContractHash::new(*addr), + Key::AddressableEntity((_package_kind, addr)) => AddressableEntityHash::new(*addr), _ => panic!("Couldn't find ordered-transforms contract."), }; diff --git a/execution_engine_testing/tests/src/test/step.rs b/execution_engine_testing/tests/src/test/step.rs index 58bc6a5dc9..a1228dec24 100644 --- a/execution_engine_testing/tests/src/test/step.rs +++ b/execution_engine_testing/tests/src/test/step.rs @@ -15,8 +15,8 @@ use casper_types::{ }, mint::TOTAL_SUPPLY_KEY, }, - CLValue, ContractHash, EraId, GenesisAccount, GenesisValidator, Key, Motes, ProtocolVersion, - PublicKey, SecretKey, U512, + AddressableEntityHash, CLValue, EraId, GenesisAccount, GenesisValidator, Key, Motes, + ProtocolVersion, PublicKey, SecretKey, U512, }; static ACCOUNT_1_PK: Lazy = Lazy::new(|| { @@ -35,11 +35,11 @@ const ACCOUNT_2_BOND: u64 = 200_000_000; fn get_named_key( builder: &mut LmdbWasmTestBuilder, - contract_hash: ContractHash, + entity_hash: AddressableEntityHash, name: &str, ) -> Key { *builder - .get_addressable_entity(contract_hash) + .get_addressable_entity(entity_hash) .expect("should have contract") .named_keys() .get(name) diff --git a/execution_engine_testing/tests/src/test/storage_costs.rs b/execution_engine_testing/tests/src/test/storage_costs.rs index 36b31cf23e..0ab78b84c4 100644 --- a/execution_engine_testing/tests/src/test/storage_costs.rs +++ b/execution_engine_testing/tests/src/test/storage_costs.rs @@ -12,9 +12,9 @@ use casper_execution_engine::engine_state::EngineConfigBuilder; use casper_types::DEFAULT_ADD_BID_COST; use casper_types::{ bytesrepr::{Bytes, ToBytes}, - BrTableCost, CLValue, ContractHash, ControlFlowCosts, EraId, HostFunction, HostFunctionCosts, - OpcodeCosts, ProtocolVersion, RuntimeArgs, StorageCosts, StoredValue, WasmConfig, - DEFAULT_MAX_STACK_HEIGHT, DEFAULT_WASM_MAX_MEMORY, U512, + AddressableEntityHash, BrTableCost, CLValue, ControlFlowCosts, EraId, HostFunction, + HostFunctionCosts, OpcodeCosts, ProtocolVersion, RuntimeArgs, StorageCosts, StoredValue, + WasmConfig, DEFAULT_MAX_STACK_HEIGHT, DEFAULT_WASM_MAX_MEMORY, U512, }; #[cfg(not(feature = "use-as-wasm"))] use casper_types::{ @@ -133,6 +133,7 @@ static NEW_HOST_FUNCTION_COSTS: Lazy = Lazy::new(|| HostFunct blake2b: HostFunction::fixed(0), random_bytes: HostFunction::fixed(0), enable_contract_version: HostFunction::fixed(0), + add_session_version: HostFunction::fixed(0), }); static STORAGE_COSTS_ONLY: Lazy = Lazy::new(|| { WasmConfig::new( @@ -241,7 +242,7 @@ fn should_verify_isolated_auction_storage_is_free() { .named_keys() .get(AUCTION) .unwrap() - .into_hash() + .into_entity_addr() .unwrap() .into(), auction::METHOD_ADD_BID, @@ -301,13 +302,12 @@ fn should_measure_gas_cost_for_storage_usage_write() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should have account"); - let contract_hash: ContractHash = account + let contract_hash: AddressableEntityHash = account .named_keys() .get(CONTRACT_KEY_NAME) .expect("contract hash") - .into_hash() - .expect("should be hash") - .into(); + .into_entity_hash() + .expect("should be hash"); // // Measure small write @@ -413,13 +413,12 @@ fn should_measure_unisolated_gas_cost_for_storage_usage_write() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should have account"); - let contract_hash: ContractHash = account + let contract_hash: AddressableEntityHash = account .named_keys() .get(CONTRACT_KEY_NAME) .expect("contract hash") - .into_hash() - .expect("should be hash") - .into(); + .into_entity_hash() + .expect("should be hash"); // // Measure small write @@ -525,13 +524,12 @@ fn should_measure_gas_cost_for_storage_usage_add() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should have account"); - let contract_hash: ContractHash = account + let contract_hash: AddressableEntityHash = account .named_keys() .get(CONTRACT_KEY_NAME) .expect("contract hash") - .into_hash() - .expect("should be hash") - .into(); + .into_entity_hash() + .expect("should be hash"); // // Measure small add @@ -641,13 +639,12 @@ fn should_measure_unisolated_gas_cost_for_storage_usage_add() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should have account"); - let contract_hash: ContractHash = account + let contract_hash: AddressableEntityHash = account .named_keys() .get(CONTRACT_KEY_NAME) .expect("contract hash") - .into_hash() - .expect("should be hash") - .into(); + .into_entity_hash() + .expect("should be hash"); // // Measure small add @@ -753,13 +750,12 @@ fn should_verify_new_uref_is_charging_for_storage() { let balance_before = builder.get_purse_balance(account.main_purse()); - let contract_hash: ContractHash = account + let contract_hash: AddressableEntityHash = account .named_keys() .get(CONTRACT_KEY_NAME) .expect("contract hash") - .into_hash() - .expect("should be hash") - .into(); + .into_entity_hash() + .expect("should be hash"); let exec_request = ExecuteRequestBuilder::contract_call_by_hash( *DEFAULT_ACCOUNT_ADDR, @@ -798,13 +794,12 @@ fn should_verify_put_key_is_charging_for_storage() { let balance_before = builder.get_purse_balance(account.main_purse()); - let contract_hash: ContractHash = account + let contract_hash: AddressableEntityHash = account .named_keys() .get(CONTRACT_KEY_NAME) .expect("contract hash") - .into_hash() - .expect("should be hash") - .into(); + .into_entity_hash() + .expect("should be hash"); let exec_request = ExecuteRequestBuilder::contract_call_by_hash( *DEFAULT_ACCOUNT_ADDR, @@ -843,13 +838,12 @@ fn should_verify_remove_key_is_charging_for_storage() { let balance_before = builder.get_purse_balance(account.main_purse()); - let contract_hash: ContractHash = account + let contract_hash: AddressableEntityHash = account .named_keys() .get(CONTRACT_KEY_NAME) .expect("contract hash") - .into_hash() - .expect("should be hash") - .into(); + .into_entity_hash() + .expect("should be hash"); let exec_request = ExecuteRequestBuilder::contract_call_by_hash( *DEFAULT_ACCOUNT_ADDR, @@ -888,13 +882,12 @@ fn should_verify_create_contract_at_hash_is_charging_for_storage() { let balance_before = builder.get_purse_balance(account.main_purse()); - let contract_hash: ContractHash = account + let contract_hash: AddressableEntityHash = account .named_keys() .get(CONTRACT_KEY_NAME) .expect("contract hash") - .into_hash() - .expect("should be hash") - .into(); + .into_entity_hash() + .expect("should be hash"); let exec_request = ExecuteRequestBuilder::contract_call_by_hash( *DEFAULT_ACCOUNT_ADDR, @@ -933,13 +926,12 @@ fn should_verify_create_contract_user_group_is_charging_for_storage() { let balance_before = builder.get_purse_balance(account.main_purse()); - let contract_hash: ContractHash = account + let contract_hash: AddressableEntityHash = account .named_keys() .get(CONTRACT_KEY_NAME) .expect("contract hash") - .into_hash() - .expect("should be hash") - .into(); + .into_entity_hash() + .expect("should be hash"); let exec_request = ExecuteRequestBuilder::contract_call_by_hash( *DEFAULT_ACCOUNT_ADDR, @@ -1012,13 +1004,12 @@ fn should_verify_subcall_new_uref_is_charging_for_storage() { let balance_before = builder.get_purse_balance(account.main_purse()); - let contract_hash: ContractHash = account + let contract_hash: AddressableEntityHash = account .named_keys() .get(CONTRACT_KEY_NAME) .expect("contract hash") - .into_hash() - .expect("should be hash") - .into(); + .into_entity_hash() + .expect("should be hash"); let exec_request = ExecuteRequestBuilder::contract_call_by_hash( *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 3e90671da9..4ad7911c94 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 @@ -6,12 +6,12 @@ use once_cell::sync::Lazy; use tempfile::TempDir; use casper_engine_test_support::{ - utils, ExecuteRequestBuilder, LmdbWasmTestBuilder, StepRequestBuilder, UpgradeRequestBuilder, - 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, + utils, ExecuteRequestBuilder, LmdbWasmTestBuilder, StepRequestBuilder, 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, }; use casper_execution_engine::{ engine_state::{ @@ -25,21 +25,20 @@ use casper_types::{ self, account::AccountHash, api_error::ApiError, + package::PackageKindTag, runtime_args, system::{ self, auction::{ self, BidsExt, DelegationRate, EraValidators, Error as AuctionError, UnbondingPurses, - ValidatorWeights, WithdrawPurses, ARG_AMOUNT, ARG_DELEGATION_RATE, ARG_DELEGATOR, - ARG_NEW_VALIDATOR, ARG_PUBLIC_KEY, ARG_VALIDATOR, ERA_ID_KEY, INITIAL_ERA_ID, + ValidatorWeights, ARG_AMOUNT, ARG_DELEGATION_RATE, ARG_DELEGATOR, ARG_NEW_VALIDATOR, + ARG_PUBLIC_KEY, ARG_VALIDATOR, ERA_ID_KEY, INITIAL_ERA_ID, }, }, - EraId, GenesisAccount, GenesisValidator, Motes, ProtocolVersion, PublicKey, SecretKey, U256, - U512, + EraId, GenesisAccount, GenesisValidator, Key, Motes, ProtocolVersion, PublicKey, SecretKey, + U256, U512, }; -use crate::lmdb_fixture; - const ARG_TARGET: &str = "target"; const CONTRACT_TRANSFER_TO_ACCOUNT: &str = "transfer_to_account_u512.wasm"; @@ -49,7 +48,6 @@ const CONTRACT_WITHDRAW_BID: &str = "withdraw_bid.wasm"; const CONTRACT_DELEGATE: &str = "delegate.wasm"; const CONTRACT_UNDELEGATE: &str = "undelegate.wasm"; const CONTRACT_REDELEGATE: &str = "redelegate.wasm"; -const DO_NOTHING_WASM: &str = "do_nothing.wasm"; const TRANSFER_AMOUNT: u64 = MINIMUM_ACCOUNT_CREATION_BALANCE + 1000; @@ -98,11 +96,6 @@ static ACCOUNT_2_ADDR: Lazy = Lazy::new(|| AccountHash::from(&*ACCO const ACCOUNT_2_BALANCE: u64 = MINIMUM_ACCOUNT_CREATION_BALANCE; const ACCOUNT_2_BOND: u64 = 200_000; -static GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY: Lazy = Lazy::new(|| { - let secret_key = SecretKey::ed25519_from_bytes([200; SecretKey::ED25519_LENGTH]).unwrap(); - PublicKey::from(&secret_key) -}); - static BID_ACCOUNT_1_PK: Lazy = Lazy::new(|| { let secret_key = SecretKey::ed25519_from_bytes([204; SecretKey::ED25519_LENGTH]).unwrap(); PublicKey::from(&secret_key) @@ -402,8 +395,10 @@ fn should_run_delegate_and_undelegate() { ); assert_eq!(*active_bid.delegation_rate(), ADD_BID_DELEGATION_RATE_1); + let auction_key = Key::addressable_entity_key(PackageKindTag::System, auction_hash); + let auction_stored_value = builder - .query(None, auction_hash.into(), &[]) + .query(None, auction_key, &[]) .expect("should query auction hash"); let _auction = auction_stored_value .as_addressable_entity() @@ -843,7 +838,7 @@ fn should_release_founder_stake() { let error = { let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last exec result"); let exec_response = response.last().expect("should have response"); exec_response @@ -2366,7 +2361,7 @@ fn should_not_partially_undelegate_uninitialized_vesting_schedule() { builder.exec(partial_undelegate).commit(); let error = { let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last exec result"); let exec_response = response.last().expect("should have response"); exec_response @@ -2440,7 +2435,7 @@ fn should_not_fully_undelegate_uninitialized_vesting_schedule() { builder.exec(full_undelegate).commit(); let error = { let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last exec result"); let exec_response = response.last().expect("should have response"); exec_response @@ -2572,7 +2567,7 @@ fn should_not_undelegate_vfta_holder_stake() { builder.exec(partial_unbond).commit(); let error = { let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last exec result"); let exec_response = response.last().expect("should have response"); exec_response @@ -2638,7 +2633,7 @@ fn should_release_vfta_holder_stake() { let error = { let response = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have last exec result"); let exec_response = response.last().expect("should have response"); exec_response @@ -3345,48 +3340,6 @@ fn should_delegate_and_redelegate() { ); } -#[ignore] -#[test] -fn should_upgrade_unbonding_purses_from_rel_1_4_2() { - // The `lmdb_fixture::RELEASE_1_4_2` has a single withdraw key - // present in the unbonding queue at the upgrade point - let (mut builder, lmdb_fixture_state, _temp_dir) = - lmdb_fixture::builder_from_global_state_fixture(lmdb_fixture::RELEASE_1_4_2); - - let previous_protocol_version = lmdb_fixture_state.genesis_protocol_version(); - - let new_protocol_version = ProtocolVersion::from_parts( - previous_protocol_version.value().major, - previous_protocol_version.value().minor + 1, - 0, - ); - - let mut upgrade_request = { - UpgradeRequestBuilder::new() - .with_current_protocol_version(previous_protocol_version) - .with_new_protocol_version(new_protocol_version) - .with_activation_point(EraId::new(1u64)) - .build() - }; - - builder - .upgrade_with_upgrade_request_and_config(None, &mut upgrade_request) - .expect_upgrade_success(); - - let unbonding_purses: UnbondingPurses = builder.get_unbonds(); - assert_eq!(unbonding_purses.len(), 1); - - let unbond_list = unbonding_purses - .get(&NON_FOUNDER_VALIDATOR_1_ADDR) - .expect("should have unbonding purse for non founding validator"); - assert_eq!(unbond_list.len(), 1); - assert_eq!( - unbond_list[0].validator_public_key(), - &*NON_FOUNDER_VALIDATOR_1_PK - ); - assert!(unbond_list[0].new_validator().is_none()) -} - #[ignore] #[test] fn should_handle_redelegation_to_inactive_validator() { @@ -3568,431 +3521,6 @@ fn should_handle_redelegation_to_inactive_validator() { ); } -#[ignore] -#[test] -fn should_continue_auction_state_from_release_1_4_x() { - // The `lmdb_fixture::RELEASE_1_4_3` has three withdraw keys - // in the unbonding queue which will each be processed - // in the three eras after the upgrade. - let (mut builder, lmdb_fixture_state, _temp_dir) = - lmdb_fixture::builder_from_global_state_fixture(lmdb_fixture::RELEASE_1_4_3); - - let withdraw_purses: WithdrawPurses = builder.get_withdraw_purses(); - - assert_eq!(withdraw_purses.len(), 1); - - let previous_protocol_version = lmdb_fixture_state.genesis_protocol_version(); - - let new_protocol_version = ProtocolVersion::from_parts( - previous_protocol_version.value().major, - previous_protocol_version.value().minor + 1, - 0, - ); - - let mut upgrade_request = { - UpgradeRequestBuilder::new() - .with_current_protocol_version(previous_protocol_version) - .with_new_protocol_version(new_protocol_version) - .with_activation_point(EraId::new(20u64)) - .with_new_unbonding_delay(DEFAULT_UNBONDING_DELAY) - .build() - }; - - builder - .upgrade_with_upgrade_request_and_config(None, &mut upgrade_request) - .expect_upgrade_success(); - - let unbonding_purses: UnbondingPurses = builder.get_unbonds(); - assert_eq!(unbonding_purses.len(), 1); - - let unbond_list = unbonding_purses - .get(&NON_FOUNDER_VALIDATOR_1_ADDR) - .expect("should have unbonding purse for non founding validator"); - assert_eq!(unbond_list.len(), 3); - assert_eq!( - unbond_list[0].validator_public_key(), - &*NON_FOUNDER_VALIDATOR_1_PK - ); - assert!(unbond_list[0].new_validator().is_none()); - assert!(unbond_list[1].new_validator().is_none()); - assert!(unbond_list[2].new_validator().is_none()); - - let accounts = vec![*BID_ACCOUNT_1_ADDR, *BID_ACCOUNT_2_ADDR, *DELEGATOR_1_ADDR]; - - for legacy_account in accounts { - let do_nothing_request = - ExecuteRequestBuilder::standard(legacy_account, DO_NOTHING_WASM, runtime_args! {}) - .build(); - - builder.exec(do_nothing_request).expect_success().commit(); - } - - let delegator_1_undelegate_purse = builder - .get_entity_by_account_hash(*BID_ACCOUNT_1_ADDR) - .expect("should have account") - .main_purse(); - - let delegator_2_undelegate_purse = builder - .get_entity_by_account_hash(*BID_ACCOUNT_2_ADDR) - .expect("should have account") - .main_purse(); - - let delegator_3_undelegate_purse = builder - .get_entity_by_account_hash(*DELEGATOR_1_ADDR) - .expect("should have account") - .main_purse(); - - let delegator_1_purse_balance_pre_step = - builder.get_purse_balance(delegator_1_undelegate_purse); - - let delegator_2_purse_balance_pre_step = - builder.get_purse_balance(delegator_2_undelegate_purse); - - let delegator_3_purse_balance_pre_step = - builder.get_purse_balance(delegator_3_undelegate_purse); - - builder.advance_era(); - - let delegator_1_purse_balance_post_step = - builder.get_purse_balance(delegator_1_undelegate_purse); - - assert_eq!( - delegator_1_purse_balance_post_step, - delegator_1_purse_balance_pre_step + U512::from(UNDELEGATE_AMOUNT_1) - ); - - let delegator_2_purse_balance_post_step = - builder.get_purse_balance(delegator_2_undelegate_purse); - - assert_eq!( - delegator_2_purse_balance_post_step, - delegator_2_purse_balance_pre_step + U512::from(UNDELEGATE_AMOUNT_1) - ); - - let delegator_3_purse_balance_post_step = - builder.get_purse_balance(delegator_3_undelegate_purse); - - assert_eq!( - delegator_3_purse_balance_post_step, - delegator_3_purse_balance_pre_step + U512::from(UNDELEGATE_AMOUNT_1) - ); - - let delegator_4_fund_request = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_TRANSFER_TO_ACCOUNT, - runtime_args! { - ARG_TARGET => *DELEGATOR_2_ADDR, - ARG_AMOUNT => U512::from(TRANSFER_AMOUNT) - }, - ) - .build(); - - builder - .exec(delegator_4_fund_request) - .expect_success() - .commit(); - - let delegator_4_validator_1_delegate_request = ExecuteRequestBuilder::standard( - *DELEGATOR_2_ADDR, - CONTRACT_DELEGATE, - runtime_args! { - ARG_AMOUNT => U512::from(DELEGATE_AMOUNT_1), - ARG_VALIDATOR => NON_FOUNDER_VALIDATOR_1_PK.clone(), - ARG_DELEGATOR => DELEGATOR_2.clone(), - }, - ) - .build(); - - builder - .exec(delegator_4_validator_1_delegate_request) - .expect_success() - .commit(); - - let delegator_4_redelegate_request = ExecuteRequestBuilder::standard( - *DELEGATOR_2_ADDR, - CONTRACT_REDELEGATE, - runtime_args! { - ARG_AMOUNT => U512::from(UNDELEGATE_AMOUNT_1 + DEFAULT_MINIMUM_DELEGATION_AMOUNT), - ARG_VALIDATOR => NON_FOUNDER_VALIDATOR_1_PK.clone(), - ARG_DELEGATOR => DELEGATOR_2.clone(), - ARG_NEW_VALIDATOR => GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY.clone() - }, - ) - .build(); - - builder - .exec(delegator_4_redelegate_request) - .expect_success() - .commit(); - - let delegator_4_purse = builder - .get_entity_by_account_hash(*DELEGATOR_2_ADDR) - .expect("must have account") - .main_purse(); - - let delegator_4_purse_balance_before = builder.get_purse_balance(delegator_4_purse); - - let actual_unbonding_delay = builder.get_unbonding_delay(); - - assert_eq!(actual_unbonding_delay, DEFAULT_UNBONDING_DELAY); - - for _ in 0..=actual_unbonding_delay { - let delegator_4_redelegate_purse_balance = builder.get_purse_balance(delegator_4_purse); - assert_eq!( - delegator_4_redelegate_purse_balance, - delegator_4_purse_balance_before - ); - - builder.advance_era(); - } - - let delegator_4_purse_balance_after = builder.get_purse_balance(delegator_4_purse); - - // redelegation will not transfer funds back to the user - // therefore the balance must remain the same - assert_eq!( - delegator_4_purse_balance_before, - delegator_4_purse_balance_after - ); - - let bids = builder.get_bids(); - assert_eq!(bids.len(), 8); - - let delegator = bids - .delegator_by_public_keys(&NON_FOUNDER_VALIDATOR_1_PK, &DELEGATOR_2) - .expect("delegator should exist"); - let delegated_amount_1 = delegator.staked_amount(); - assert_eq!( - delegated_amount_1, - U512::from(DELEGATE_AMOUNT_1 - UNDELEGATE_AMOUNT_1 - DEFAULT_MINIMUM_DELEGATION_AMOUNT) - ); - - let delegator = bids - .delegator_by_public_keys(&GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY, &DELEGATOR_2) - .expect("delegator should exist"); - let redelegated_amount_1 = delegator.staked_amount(); - assert_eq!( - redelegated_amount_1, - U512::from(UNDELEGATE_AMOUNT_1 + DEFAULT_MINIMUM_DELEGATION_AMOUNT) - ); -} - -#[ignore] -#[test] -fn should_transfer_to_main_purse_when_validator_is_no_longer_active() { - let (mut builder, lmdb_fixture_state, _temp_dir) = - lmdb_fixture::builder_from_global_state_fixture(lmdb_fixture::RELEASE_1_4_3); - - let withdraw_purses: WithdrawPurses = builder.get_withdraw_purses(); - assert_eq!(withdraw_purses.len(), 1); - - let previous_protocol_version = lmdb_fixture_state.genesis_protocol_version(); - let new_protocol_version = ProtocolVersion::from_parts( - previous_protocol_version.value().major, - previous_protocol_version.value().minor + 1, - 0, - ); - - let mut upgrade_request = { - UpgradeRequestBuilder::new() - .with_current_protocol_version(previous_protocol_version) - .with_new_protocol_version(new_protocol_version) - .with_activation_point(EraId::new(20u64)) - .build() - }; - - builder - .upgrade_with_upgrade_request_and_config(None, &mut upgrade_request) - .expect_upgrade_success(); - - let unbonding_purses: UnbondingPurses = builder.get_unbonds(); - assert_eq!(unbonding_purses.len(), 1); - - let unbond_list = unbonding_purses - .get(&NON_FOUNDER_VALIDATOR_1_ADDR) - .expect("should have unbonding purses for non founding validator"); - assert_eq!(unbond_list.len(), 3); - assert_eq!( - unbond_list[0].validator_public_key(), - &*NON_FOUNDER_VALIDATOR_1_PK - ); - assert!(unbond_list[0].new_validator().is_none()); - assert!(unbond_list[1].new_validator().is_none()); - assert!(unbond_list[2].new_validator().is_none()); - - let do_nothing_request = - ExecuteRequestBuilder::standard(*BID_ACCOUNT_1_ADDR, DO_NOTHING_WASM, runtime_args! {}) - .build(); - - builder.exec(do_nothing_request).expect_success().commit(); - - let delegator_1_undelegate_purse = builder - .get_entity_by_account_hash(*BID_ACCOUNT_1_ADDR) - .expect("should have account") - .main_purse(); - - let delegator_1_purse_balance_pre_step = - builder.get_purse_balance(delegator_1_undelegate_purse); - - builder.advance_era(); - - let delegator_1_purse_balance_post_step = - builder.get_purse_balance(delegator_1_undelegate_purse); - - assert_eq!( - delegator_1_purse_balance_post_step, - delegator_1_purse_balance_pre_step + U512::from(UNDELEGATE_AMOUNT_1) - ); - - let do_nothing_request = - ExecuteRequestBuilder::standard(*BID_ACCOUNT_2_ADDR, DO_NOTHING_WASM, runtime_args! {}) - .build(); - - builder.exec(do_nothing_request).expect_success().commit(); - - let delegator_2_undelegate_purse = builder - .get_entity_by_account_hash(*BID_ACCOUNT_2_ADDR) - .expect("should have account") - .main_purse(); - - let delegator_2_purse_balance_pre_step = - builder.get_purse_balance(delegator_2_undelegate_purse); - - builder.advance_era(); - - let delegator_2_purse_balance_post_step = - builder.get_purse_balance(delegator_2_undelegate_purse); - - assert_eq!( - delegator_2_purse_balance_post_step, - delegator_2_purse_balance_pre_step + U512::from(UNDELEGATE_AMOUNT_1) - ); - - let do_nothing_request = - ExecuteRequestBuilder::standard(*DELEGATOR_1_ADDR, DO_NOTHING_WASM, runtime_args! {}) - .build(); - - builder.exec(do_nothing_request).expect_success().commit(); - - let delegator_3_undelegate_purse = builder - .get_entity_by_account_hash(*DELEGATOR_1_ADDR) - .expect("should have account") - .main_purse(); - - let delegator_3_purse_balance_pre_step = - builder.get_purse_balance(delegator_3_undelegate_purse); - - builder.advance_era(); - - let delegator_3_purse_balance_post_step = - builder.get_purse_balance(delegator_3_undelegate_purse); - - assert_eq!( - delegator_3_purse_balance_post_step, - delegator_3_purse_balance_pre_step + U512::from(UNDELEGATE_AMOUNT_1) - ); - - let delegator_4_fund_request = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_TRANSFER_TO_ACCOUNT, - runtime_args! { - ARG_TARGET => *DELEGATOR_2_ADDR, - ARG_AMOUNT => U512::from(TRANSFER_AMOUNT) - }, - ) - .build(); - - builder - .exec(delegator_4_fund_request) - .expect_success() - .commit(); - - let delegator_4_validator_1_delegate_request = ExecuteRequestBuilder::standard( - *DELEGATOR_2_ADDR, - CONTRACT_DELEGATE, - runtime_args! { - ARG_AMOUNT => U512::from(DELEGATE_AMOUNT_1), - ARG_VALIDATOR => GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY.clone(), - ARG_DELEGATOR => DELEGATOR_2.clone(), - }, - ) - .build(); - - builder - .exec(delegator_4_validator_1_delegate_request) - .expect_success() - .commit(); - - let delegator_4_redelegate_request = ExecuteRequestBuilder::standard( - *DELEGATOR_2_ADDR, - CONTRACT_REDELEGATE, - runtime_args! { - ARG_AMOUNT => U512::from(UNDELEGATE_AMOUNT_1 + DEFAULT_MINIMUM_DELEGATION_AMOUNT), - ARG_VALIDATOR => GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY.clone(), - ARG_DELEGATOR => DELEGATOR_2.clone(), - ARG_NEW_VALIDATOR => NON_FOUNDER_VALIDATOR_1_PK.clone() - }, - ) - .build(); - - builder - .exec(delegator_4_redelegate_request) - .expect_success() - .commit(); - - let withdraw_request = ExecuteRequestBuilder::standard( - *NON_FOUNDER_VALIDATOR_1_ADDR, - CONTRACT_WITHDRAW_BID, - runtime_args! { - ARG_PUBLIC_KEY => NON_FOUNDER_VALIDATOR_1_PK.clone(), - ARG_AMOUNT => U512::from(ADD_BID_AMOUNT_1), - }, - ) - .build(); - - builder.exec(withdraw_request).expect_success().commit(); - - builder.advance_eras_by_default_auction_delay(); - - let delegator_4_purse = builder - .get_entity_by_account_hash(*DELEGATOR_2_ADDR) - .expect("must have account") - .main_purse(); - - let delegator_4_purse_balance_before = builder.get_purse_balance(delegator_4_purse); - - for _ in 0..(builder.get_unbonding_delay() - builder.get_auction_delay()) { - let delegator_4_redelegate_purse_balance = builder.get_purse_balance(delegator_4_purse); - assert_eq!( - delegator_4_redelegate_purse_balance, - delegator_4_purse_balance_before - ); - - builder.advance_era(); - } - - let delegator_4_purse_balance_after = builder.get_purse_balance(delegator_4_purse); - - let bids = builder.get_bids(); - assert!(bids.validator_bid(&NON_FOUNDER_VALIDATOR_1_PK).is_none()); - - // Since we have re-delegated to an inactive validator, - // the funds should cycle back to the delegator. - assert_eq!( - delegator_4_purse_balance_before + UNDELEGATE_AMOUNT_1 + DEFAULT_MINIMUM_DELEGATION_AMOUNT, - delegator_4_purse_balance_after - ); - - let delegator = bids - .delegator_by_public_keys(&GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY, &DELEGATOR_2) - .expect("should have delegator"); - let delegated_amount_1 = delegator.staked_amount(); - assert_eq!( - delegated_amount_1, - U512::from(DELEGATE_AMOUNT_1 - UNDELEGATE_AMOUNT_1 - DEFAULT_MINIMUM_DELEGATION_AMOUNT) - ); -} - #[ignore] #[test] fn should_enforce_minimum_delegation_amount() { 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 eb8d13fbb4..f6ffc5481d 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/genesis.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/genesis.rs @@ -13,8 +13,8 @@ use casper_execution_engine::engine_state::{ run_genesis_request::RunGenesisRequest, }; use casper_types::{ - account::AccountHash, system::auction::DelegationRate, GenesisAccount, GenesisValidator, Motes, - ProtocolVersion, PublicKey, SecretKey, StoredValue, U512, + account::AccountHash, package::PackageKindTag, system::auction::DelegationRate, GenesisAccount, + GenesisValidator, Key, Motes, ProtocolVersion, PublicKey, SecretKey, StoredValue, U512, }; const GENESIS_CONFIG_HASH: [u8; 32] = [127; 32]; @@ -95,10 +95,14 @@ fn should_run_genesis() { assert_eq!(account_1_balance_actual, U512::from(ACCOUNT_1_BALANCE)); assert_eq!(account_2_balance_actual, U512::from(ACCOUNT_2_BALANCE)); - let mint_contract_hash = builder.get_mint_contract_hash(); - let handle_payment_contract_hash = builder.get_handle_payment_contract_hash(); + let mint_contract_key = + Key::addressable_entity_key(PackageKindTag::System, builder.get_mint_contract_hash()); + let handle_payment_contract_key = Key::addressable_entity_key( + PackageKindTag::System, + builder.get_handle_payment_contract_hash(), + ); - let result = builder.query(None, mint_contract_hash.into(), &[]); + let result = builder.query(None, mint_contract_key, &[]); if let Ok(StoredValue::AddressableEntity(_)) = result { // Contract exists at mint contract hash } else { @@ -106,7 +110,7 @@ fn should_run_genesis() { } if let Ok(StoredValue::AddressableEntity(_)) = - builder.query(None, handle_payment_contract_hash.into(), &[]) + builder.query(None, handle_payment_contract_key, &[]) { // Contract exists at handle payment contract hash } else { diff --git a/execution_engine_testing/tests/src/test/system_costs.rs b/execution_engine_testing/tests/src/test/system_costs.rs index d7ae56e707..80b47a3d92 100644 --- a/execution_engine_testing/tests/src/test/system_costs.rs +++ b/execution_engine_testing/tests/src/test/system_costs.rs @@ -88,7 +88,7 @@ fn add_bid_and_withdraw_bid_have_expected_costs() { .named_keys() .get(AUCTION) .unwrap() - .into_hash() + .into_entity_addr() .unwrap() .into(), auction::METHOD_ADD_BID, @@ -131,7 +131,7 @@ fn add_bid_and_withdraw_bid_have_expected_costs() { .named_keys() .get(AUCTION) .unwrap() - .into_hash() + .into_entity_addr() .unwrap() .into(), auction::METHOD_WITHDRAW_BID, @@ -228,7 +228,7 @@ fn upgraded_add_bid_and_withdraw_bid_have_expected_costs() { .named_keys() .get(AUCTION) .unwrap() - .into_hash() + .into_entity_addr() .unwrap() .into(), auction::METHOD_ADD_BID, @@ -266,7 +266,7 @@ fn upgraded_add_bid_and_withdraw_bid_have_expected_costs() { .named_keys() .get(AUCTION) .unwrap() - .into_hash() + .into_entity_addr() .unwrap() .into(), auction::METHOD_WITHDRAW_BID, @@ -346,7 +346,7 @@ fn delegate_and_undelegate_have_expected_costs() { .named_keys() .get(AUCTION) .unwrap() - .into_hash() + .into_entity_addr() .unwrap() .into(), auction::METHOD_DELEGATE, @@ -389,7 +389,7 @@ fn delegate_and_undelegate_have_expected_costs() { .named_keys() .get(AUCTION) .unwrap() - .into_hash() + .into_entity_addr() .unwrap() .into(), auction::METHOD_REDELEGATE, @@ -421,7 +421,7 @@ fn delegate_and_undelegate_have_expected_costs() { .named_keys() .get(AUCTION) .unwrap() - .into_hash() + .into_entity_addr() .unwrap() .into(), auction::METHOD_UNDELEGATE, @@ -545,7 +545,7 @@ fn upgraded_delegate_and_undelegate_have_expected_costs() { .named_keys() .get(AUCTION) .unwrap() - .into_hash() + .into_entity_addr() .unwrap() .into(), auction::METHOD_DELEGATE, @@ -581,7 +581,7 @@ fn upgraded_delegate_and_undelegate_have_expected_costs() { .named_keys() .get(AUCTION) .unwrap() - .into_hash() + .into_entity_addr() .unwrap() .into(), auction::METHOD_REDELEGATE, @@ -607,7 +607,7 @@ fn upgraded_delegate_and_undelegate_have_expected_costs() { .named_keys() .get(AUCTION) .unwrap() - .into_hash() + .into_entity_addr() .unwrap() .into(), auction::METHOD_UNDELEGATE, @@ -812,7 +812,7 @@ fn should_charge_for_erroneous_system_contract_calls() { builder.exec(exec_request).commit(); let _error = builder - .get_last_exec_results() + .get_last_exec_result() .expect("should have results") .get(0) .expect("should have first result") @@ -968,6 +968,7 @@ fn should_verify_wasm_add_bid_wasm_cost_is_not_recursive() { blake2b: HostFunction::fixed(0), random_bytes: HostFunction::fixed(0), enable_contract_version: HostFunction::fixed(0), + add_session_version: HostFunction::fixed(0), }; let new_wasm_config = WasmConfig::new( diff --git a/execution_engine_testing/tests/src/test/upgrade.rs b/execution_engine_testing/tests/src/test/upgrade.rs index c390d11a9f..81972450ca 100644 --- a/execution_engine_testing/tests/src/test/upgrade.rs +++ b/execution_engine_testing/tests/src/test/upgrade.rs @@ -1,28 +1,40 @@ use casper_engine_test_support::{ - ExecuteRequestBuilder, LmdbWasmTestBuilder, DEFAULT_ACCOUNT_ADDR, - PRODUCTION_RUN_GENESIS_REQUEST, + ExecuteRequestBuilder, LmdbWasmTestBuilder, UpgradeRequestBuilder, DEFAULT_ACCOUNT_ADDR, + MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST, }; + +use casper_execution_engine::{engine_state, execution::Error}; use casper_types::{ - package::{ContractVersion, CONTRACT_INITIAL_VERSION}, - runtime_args, CLValue, ContractPackageHash, RuntimeArgs, StoredValue, + account::AccountHash, + addressable_entity::{AssociatedKeys, Weight}, + package::{EntityVersion, ENTITY_INITIAL_VERSION}, + runtime_args, + system::mint, + AddressableEntityHash, CLValue, EraId, PackageHash, ProtocolVersion, RuntimeArgs, StoredValue, }; const DO_NOTHING_STORED_CONTRACT_NAME: &str = "do_nothing_stored"; const DO_NOTHING_STORED_UPGRADER_CONTRACT_NAME: &str = "do_nothing_stored_upgrader"; const DO_NOTHING_STORED_CALLER_CONTRACT_NAME: &str = "do_nothing_stored_caller"; +const PURSE_HOLDER_STORED_CALLER_CONTRACT_NAME: &str = "purse_holder_stored_caller"; +const PURSE_HOLDER_STORED_CONTRACT_NAME: &str = "purse_holder_stored"; +const PURSE_HOLDER_STORED_UPGRADER_CONTRACT_NAME: &str = "purse_holder_stored_upgrader"; +const UPGRADE_THRESHOLD_CONTRACT_NAME: &str = "upgrade_threshold.wasm"; +const UPGRADE_THRESHOLD_UPGRADER: &str = "upgrade_threshold_upgrader.wasm"; + const ENTRY_FUNCTION_NAME: &str = "delegate"; const DO_NOTHING_CONTRACT_NAME: &str = "do_nothing_package_hash"; const DO_NOTHING_HASH_KEY_NAME: &str = "do_nothing_hash"; -const INITIAL_VERSION: ContractVersion = CONTRACT_INITIAL_VERSION; -const UPGRADED_VERSION: ContractVersion = INITIAL_VERSION + 1; + +const INITIAL_VERSION: EntityVersion = ENTITY_INITIAL_VERSION; +const UPGRADED_VERSION: EntityVersion = INITIAL_VERSION + 1; const PURSE_NAME_ARG_NAME: &str = "purse_name"; const PURSE_1: &str = "purse_1"; const METHOD_REMOVE: &str = "remove"; const VERSION: &str = "version"; -const PURSE_HOLDER_STORED_CALLER_CONTRACT_NAME: &str = "purse_holder_stored_caller"; -const PURSE_HOLDER_STORED_CONTRACT_NAME: &str = "purse_holder_stored"; -const PURSE_HOLDER_STORED_UPGRADER_CONTRACT_NAME: &str = "purse_holder_stored_upgrader"; + const HASH_KEY_NAME: &str = "purse_holder"; + const TOTAL_PURSES: usize = 3; const PURSE_NAME: &str = "purse_name"; const ENTRY_POINT_NAME: &str = "entry_point"; @@ -75,8 +87,19 @@ fn should_upgrade_do_nothing_to_do_something_version_hash_call() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should get account 1"); + let entity_hash = account_1 + .named_keys() + .get(DO_NOTHING_HASH_KEY_NAME) + .expect("must have do-nothing-hash") + .into_entity_hash() + .unwrap(); + + let entity = builder + .get_addressable_entity(entity_hash) + .expect("must have entity"); + assert!( - account_1.named_keys().get(PURSE_1).is_none(), + entity.named_keys().get(PURSE_1).is_none(), "purse should not exist", ); @@ -118,8 +141,19 @@ fn should_upgrade_do_nothing_to_do_something_version_hash_call() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should get account 1"); + let entity_hash = account_1 + .named_keys() + .get("end of upgrade") + .expect("must have do-nothing-hash") + .into_entity_hash() + .unwrap(); + + let entity = builder + .get_addressable_entity(entity_hash) + .expect("must have entity"); + assert!( - account_1.named_keys().get(PURSE_1).is_some(), + entity.named_keys().get(PURSE_1).is_some(), "purse should exist", ); } @@ -155,14 +189,14 @@ fn should_upgrade_do_nothing_to_do_something_contract_call() { .named_keys() .get(DO_NOTHING_HASH_KEY_NAME) .expect("should have key of do_nothing_hash") - .into_hash() + .into_entity_addr() .expect("should have into hash"); let stored_contract_package_hash = account_1 .named_keys() .get(DO_NOTHING_CONTRACT_NAME) .expect("should have key of do_nothing_hash") - .into_hash() + .into_package_addr() .expect("should have hash"); // Calling initial stored version from contract package hash, should have no effects @@ -184,8 +218,19 @@ fn should_upgrade_do_nothing_to_do_something_contract_call() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should get account 1"); + let entity_hash = account_1 + .named_keys() + .get(DO_NOTHING_HASH_KEY_NAME) + .expect("must have do-nothing-hash") + .into_entity_hash() + .unwrap(); + + let entity = builder + .get_addressable_entity(entity_hash) + .expect("must have entity"); + assert!( - account_1.named_keys().get(PURSE_1).is_none(), + entity.named_keys().get(PURSE_1).is_none(), "purse should not exist", ); @@ -208,7 +253,7 @@ fn should_upgrade_do_nothing_to_do_something_contract_call() { .named_keys() .get(DO_NOTHING_CONTRACT_NAME) .expect("should have key of do_nothing_hash") - .into_hash() + .into_package_addr() .expect("should have hash"); // Calling upgraded stored version, expecting purse creation @@ -231,8 +276,19 @@ fn should_upgrade_do_nothing_to_do_something_contract_call() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should get account 1"); + let entity_hash = account_1 + .named_keys() + .get("end of upgrade") + .expect("must have do-nothing-hash") + .into_entity_hash() + .unwrap(); + + let entity = builder + .get_addressable_entity(entity_hash) + .expect("must have entity"); + assert!( - account_1.named_keys().get(PURSE_1).is_some(), + entity.named_keys().get(PURSE_1).is_some(), "purse should exist", ); } @@ -270,11 +326,11 @@ fn should_be_able_to_observe_state_transition_across_upgrade() { "version uref should exist on install" ); - let stored_package_hash: ContractPackageHash = account + let stored_package_hash: PackageHash = account .named_keys() .get(HASH_KEY_NAME) .expect("should have stored uref") - .into_hash() + .into_package_addr() .expect("should have hash") .into(); @@ -368,14 +424,14 @@ fn should_support_extending_functionality() { .named_keys() .get(HASH_KEY_NAME) .expect("should have stored uref") - .into_hash() + .into_package_addr() .expect("should have hash"); let stored_hash = account .named_keys() .get(PURSE_HOLDER_STORED_CONTRACT_NAME) .expect("should have stored uref") - .into_hash() + .into_entity_addr() .expect("should have hash") .into(); @@ -444,7 +500,7 @@ fn should_support_extending_functionality() { .named_keys() .get(PURSE_HOLDER_STORED_CONTRACT_NAME) .expect("should have stored uref") - .into_hash() + .into_entity_addr() .expect("should have hash") .into(); assert_ne!(stored_hash, stored_hash_2); @@ -511,14 +567,14 @@ fn should_maintain_named_keys_across_upgrade() { .named_keys() .get(PURSE_HOLDER_STORED_CONTRACT_NAME) .expect("should have stored hash") - .into_hash() + .into_entity_addr() .expect("should have hash"); let stored_package_hash = account .named_keys() .get(HASH_KEY_NAME) .expect("should have stored package hash") - .into_hash() + .into_package_hash() .expect("should have hash"); // add several purse urefs to named_keys @@ -611,16 +667,16 @@ fn should_fail_upgrade_for_locked_contract() { .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) .expect("should have account"); - let stored_package_hash: ContractPackageHash = account + let stored_package_hash: PackageHash = account .named_keys() .get(HASH_KEY_NAME) .expect("should have stored package hash") - .into_hash() + .into_package_addr() .expect("should have hash") .into(); let contract_package = builder - .get_contract_package(stored_package_hash) + .get_package(stored_package_hash) .expect("should get package hash"); // Ensure that our current package is indeed locked. @@ -642,3 +698,461 @@ fn should_fail_upgrade_for_locked_contract() { assert!(builder.exec(exec_request).is_error()); } } + +#[ignore] +#[test] +fn should_only_upgrade_if_threshold_is_met() { + const CONTRACT_HASH_NAME: &str = "contract_hash_name"; + const PACKAGE_HASH_KEY_NAME: &str = "contract_package_hash"; + + const ENTRYPOINT_ADD_ASSOCIATED_KEY: &str = "add_associated_key"; + const ENTRYPOINT_MANAGE_ACTION_THRESHOLD: &str = "manage_action_threshold"; + + const ARG_ENTITY_ACCOUNT_HASH: &str = "entity_account_hash"; + const ARG_KEY_WEIGHT: &str = "key_weight"; + const ARG_NEW_UPGRADE_THRESHOLD: &str = "new_threshold"; + const ARG_CONTRACT_PACKAGE: &str = "contract_package_hash"; + + let mut builder = LmdbWasmTestBuilder::default(); + + builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); + + let install_request = ExecuteRequestBuilder::standard( + *DEFAULT_ACCOUNT_ADDR, + UPGRADE_THRESHOLD_CONTRACT_NAME, + runtime_args! {}, + ) + .build(); + + builder.exec(install_request).expect_success().commit(); + + let entity = builder + .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) + .expect("must have default addressable entity"); + + let upgrade_threshold_contract_hash = entity + .named_keys() + .get(CONTRACT_HASH_NAME) + .expect("must have named key entry for contract hash") + .into_entity_addr() + .map(AddressableEntityHash::new) + .expect("must get contract hash"); + + let upgrade_threshold_package_hash = entity + .named_keys() + .get(PACKAGE_HASH_KEY_NAME) + .expect("must have named key entry for package hash") + .into_package_addr() + .map(PackageHash::new) + .expect("must get package hash"); + + let upgrade_threshold_contract_entity = builder + .get_addressable_entity(upgrade_threshold_contract_hash) + .expect("must have upgrade threshold entity"); + + let actual_associated_keys = upgrade_threshold_contract_entity.associated_keys(); + let mut expected_associated_keys = AssociatedKeys::new(*DEFAULT_ACCOUNT_ADDR, Weight::new(1)); + assert_eq!(&expected_associated_keys, actual_associated_keys); + + let mut entity_account_hashes = + vec![AccountHash::new([10u8; 32]), AccountHash::new([11u8; 32])]; + + for entity_account_hash in &entity_account_hashes { + expected_associated_keys + .add_key(*entity_account_hash, Weight::new(1)) + .expect("must add associated key"); + + let execute_request = ExecuteRequestBuilder::contract_call_by_hash( + *DEFAULT_ACCOUNT_ADDR, + upgrade_threshold_contract_hash, + ENTRYPOINT_ADD_ASSOCIATED_KEY, + runtime_args! { + ARG_ENTITY_ACCOUNT_HASH => *entity_account_hash, + ARG_KEY_WEIGHT => 1u8 + }, + ) + .build(); + + builder.exec(execute_request).expect_success().commit(); + } + + let update_upgrade_threshold_request = ExecuteRequestBuilder::contract_call_by_hash( + *DEFAULT_ACCOUNT_ADDR, + upgrade_threshold_contract_hash, + ENTRYPOINT_MANAGE_ACTION_THRESHOLD, + runtime_args! { + ARG_NEW_UPGRADE_THRESHOLD => 3u8 + }, + ) + .build(); + + builder + .exec(update_upgrade_threshold_request) + .expect_success() + .commit(); + + let upgrade_threshold_contract_entity = builder + .get_addressable_entity(upgrade_threshold_contract_hash) + .expect("must have upgrade threshold entity"); + + let updated_associated_keys = upgrade_threshold_contract_entity.associated_keys(); + assert_eq!(&expected_associated_keys, updated_associated_keys); + + let updated_action_threshold = upgrade_threshold_contract_entity.action_thresholds(); + assert_eq!( + updated_action_threshold.upgrade_management(), + &Weight::new(3u8) + ); + + let invalid_upgrade_request = ExecuteRequestBuilder::standard( + *DEFAULT_ACCOUNT_ADDR, + UPGRADE_THRESHOLD_UPGRADER, + runtime_args! { + ARG_CONTRACT_PACKAGE => upgrade_threshold_package_hash + }, + ) + .build(); + + builder.exec(invalid_upgrade_request).expect_failure(); + + builder.assert_error(engine_state::Error::Exec( + Error::UpgradeAuthorizationFailure, + )); + + let authorization_keys = { + entity_account_hashes.push(*DEFAULT_ACCOUNT_ADDR); + entity_account_hashes + }; + + let valid_upgrade_request = ExecuteRequestBuilder::with_authorization_keys( + *DEFAULT_ACCOUNT_ADDR, + UPGRADE_THRESHOLD_UPGRADER, + runtime_args! { + ARG_CONTRACT_PACKAGE => upgrade_threshold_package_hash + }, + &authorization_keys, + ) + .build(); + + builder + .exec(valid_upgrade_request) + .expect_success() + .commit(); +} + +fn setup_upgrade_threshold_state() -> (LmdbWasmTestBuilder, ProtocolVersion, AccountHash) { + const ACCOUNT_1_ADDR: AccountHash = AccountHash::new([1u8; 32]); + const UPGRADE_THRESHOLDS_FIXTURE: &str = "upgrade_thresholds"; + + let (mut builder, lmdb_fixture_state, _temp_dir) = + crate::lmdb_fixture::builder_from_global_state_fixture(UPGRADE_THRESHOLDS_FIXTURE); + + let current_protocol_version = lmdb_fixture_state.genesis_protocol_version(); + + let new_protocol_version = + ProtocolVersion::from_parts(current_protocol_version.value().major + 1, 0, 0); + + let activation_point = EraId::new(0u64); + + let mut upgrade_request = UpgradeRequestBuilder::new() + .with_current_protocol_version(current_protocol_version) + .with_new_protocol_version(new_protocol_version) + .with_activation_point(activation_point) + .build(); + + builder + .upgrade_with_upgrade_request_using_scratch( + builder.get_engine_state().config().clone(), + &mut upgrade_request, + ) + .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), + }, + ) + .with_protocol_version(new_protocol_version) + .build(); + + builder.exec(transfer).expect_success().commit(); + + (builder, new_protocol_version, ACCOUNT_1_ADDR) +} + +#[ignore] +#[test] +fn should_migrate_with_correct_upgrade_thresholds() { + let (mut builder, new_protocol_version, _) = setup_upgrade_threshold_state(); + + let default_addressable_entity = builder + .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) + .expect("must have default entity"); + + let contract_hash = default_addressable_entity + .named_keys() + .get(PURSE_HOLDER_STORED_CONTRACT_NAME) + .map(|holder_key| holder_key.into_hash_addr().map(AddressableEntityHash::new)) + .unwrap() + .expect("must convert to hash"); + + let exec_request = ExecuteRequestBuilder::standard( + *DEFAULT_ACCOUNT_ADDR, + &format!("{}.wasm", PURSE_HOLDER_STORED_CALLER_CONTRACT_NAME), + runtime_args! { + ENTRY_POINT_NAME => VERSION, + 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 + .get_addressable_entity(contract_hash) + .expect("must have purse holder entity hash"); + + let actual_associated_keys = purse_holder_as_entity.associated_keys(); + + let expect_associated_keys = AssociatedKeys::new(*DEFAULT_ACCOUNT_ADDR, Weight::new(1)); + + assert_eq!(actual_associated_keys, &expect_associated_keys); +} + +#[ignore] +#[test] +fn should_correctly_set_upgrade_threshold_on_entity_upgrade() { + let (mut builder, new_protocol_version, entity_1) = setup_upgrade_threshold_state(); + + let default_addressable_entity = builder + .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) + .expect("must have default entity"); + + let entity_hash = default_addressable_entity + .named_keys() + .get(PURSE_HOLDER_STORED_CONTRACT_NAME) + // We use hash addr as the migration hasn't occurred. + .map(|holder_key| holder_key.into_hash_addr().map(AddressableEntityHash::new)) + .unwrap() + .expect("must convert to hash"); + + let stored_package_hash = default_addressable_entity + .named_keys() + .get(HASH_KEY_NAME) + .expect("should have stored package hash") + .into_hash_addr() + .map(PackageHash::new) + .expect("should have hash"); + + let exec_request = ExecuteRequestBuilder::standard( + entity_1, + &format!("{}.wasm", PURSE_HOLDER_STORED_CALLER_CONTRACT_NAME), + runtime_args! { + ENTRY_POINT_NAME => VERSION, + HASH_KEY_NAME => entity_hash + }, + ) + .with_protocol_version(new_protocol_version) + .build(); + + builder.exec(exec_request).expect_success().commit(); + + let purse_holder_as_entity = builder + .get_addressable_entity(entity_hash) + .expect("must have purse holder entity hash"); + + let actual_associated_keys = purse_holder_as_entity.associated_keys(); + + assert!(actual_associated_keys.is_empty()); + + let upgrade_request = ExecuteRequestBuilder::standard( + *DEFAULT_ACCOUNT_ADDR, + &format!("{}.wasm", PURSE_HOLDER_STORED_UPGRADER_CONTRACT_NAME), + runtime_args! { + ARG_CONTRACT_PACKAGE => stored_package_hash + }, + ) + .with_protocol_version(new_protocol_version) + .build(); + + builder.exec(upgrade_request).expect_success().commit(); + + let new_entity_hash = builder + .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) + .expect("must have entity") + .named_keys() + .get(PURSE_HOLDER_STORED_CONTRACT_NAME) + .map(|key| key.into_entity_addr().map(AddressableEntityHash::new)) + .unwrap() + .expect("must get contract hash"); + + let updated_purse_entity = builder + .get_addressable_entity(new_entity_hash) + .expect("must have purse holder entity hash"); + + let actual_associated_keys = updated_purse_entity.associated_keys(); + + let expect_associated_keys = AssociatedKeys::new(*DEFAULT_ACCOUNT_ADDR, Weight::new(1)); + + assert_eq!(actual_associated_keys, &expect_associated_keys); +} + +#[allow(clippy::enum_variant_names)] +enum InvocationType { + ByContractHash, + ByContractName, + ByPackageHash(Option), + ByPackageName(Option), + ByUpgrader, +} + +fn call_and_migrate_purse_holder_contract(invocation_type: InvocationType) { + let (mut builder, new_protocol_version, _) = setup_upgrade_threshold_state(); + + let runtime_args = runtime_args! { + PURSE_NAME_ARG_NAME => PURSE_1 + }; + + let default_addressable_entity = builder + .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) + .expect("must have default entity"); + + let entity_hash = default_addressable_entity + .named_keys() + .get(PURSE_HOLDER_STORED_CONTRACT_NAME) + .map(|holder_key| holder_key.into_hash_addr().map(AddressableEntityHash::new)) + .unwrap() + .expect("must convert to hash"); + + let package_hash = default_addressable_entity + .named_keys() + .get(HASH_KEY_NAME) + .expect("must have package named key entry") + .into_hash_addr() + .map(PackageHash::new) + .unwrap(); + + let execute_request = match invocation_type { + InvocationType::ByPackageName(maybe_contract_version) => { + ExecuteRequestBuilder::versioned_contract_call_by_name( + *DEFAULT_ACCOUNT_ADDR, + HASH_KEY_NAME, + maybe_contract_version, + ENTRY_POINT_ADD, + runtime_args, + ) + .with_protocol_version(new_protocol_version) + .build() + } + InvocationType::ByPackageHash(maybe_contract_version) => { + ExecuteRequestBuilder::versioned_contract_call_by_hash( + *DEFAULT_ACCOUNT_ADDR, + package_hash, + maybe_contract_version, + ENTRY_POINT_ADD, + runtime_args, + ) + .with_protocol_version(new_protocol_version) + .build() + } + InvocationType::ByContractHash => ExecuteRequestBuilder::contract_call_by_hash( + *DEFAULT_ACCOUNT_ADDR, + entity_hash, + ENTRY_POINT_ADD, + runtime_args, + ) + .with_protocol_version(new_protocol_version) + .build(), + InvocationType::ByContractName => ExecuteRequestBuilder::contract_call_by_name( + *DEFAULT_ACCOUNT_ADDR, + PURSE_HOLDER_STORED_CONTRACT_NAME, + ENTRY_POINT_ADD, + runtime_args, + ) + .with_protocol_version(new_protocol_version) + .build(), + InvocationType::ByUpgrader => ExecuteRequestBuilder::standard( + *DEFAULT_ACCOUNT_ADDR, + &format!("{}.wasm", PURSE_HOLDER_STORED_UPGRADER_CONTRACT_NAME), + runtime_args! { + ARG_CONTRACT_PACKAGE => package_hash + }, + ) + .with_protocol_version(new_protocol_version) + .build(), + }; + + builder.exec(execute_request).expect_success().commit(); + + let updated_entity = builder + .get_entity_by_account_hash(*DEFAULT_ACCOUNT_ADDR) + .expect("must have default entity"); + + let updated_key = updated_entity + .named_keys() + .get(PURSE_HOLDER_STORED_CONTRACT_NAME) + .expect("must have updated entity"); + + let updated_hash = if let InvocationType::ByUpgrader = invocation_type { + updated_key.into_entity_hash() + } else { + updated_key.into_hash_addr().map(AddressableEntityHash::new) + } + .expect("must get entity hash"); + + let updated_purse_entity = builder + .get_addressable_entity(updated_hash) + .expect("must have purse holder entity hash"); + + let actual_associated_keys = updated_purse_entity.associated_keys(); + + let expect_associated_keys = AssociatedKeys::new(*DEFAULT_ACCOUNT_ADDR, Weight::new(1)); + + assert_eq!(actual_associated_keys, &expect_associated_keys); +} + +#[ignore] +#[test] +fn should_correct_migrate_contract_when_invoked_by_package_name() { + call_and_migrate_purse_holder_contract(InvocationType::ByPackageName(None)) +} + +#[ignore] +#[test] +fn should_correctly_migrate_contract_when_invoked_by_name_and_version() { + call_and_migrate_purse_holder_contract(InvocationType::ByPackageName(Some(INITIAL_VERSION))) +} + +#[ignore] +#[test] +fn should_correct_migrate_contract_when_invoked_by_package_hash() { + call_and_migrate_purse_holder_contract(InvocationType::ByPackageHash(None)) +} + +#[ignore] +#[test] +fn should_correct_migrate_contract_when_invoked_by_package_hash_and_specific_version() { + call_and_migrate_purse_holder_contract(InvocationType::ByPackageHash(Some(INITIAL_VERSION))) +} + +#[ignore] +#[test] +fn should_correctly_migrate_contract_when_invoked_by_contract_hash() { + call_and_migrate_purse_holder_contract(InvocationType::ByContractHash) +} + +#[ignore] +#[test] +fn should_correctly_migrate_contract_when_invoked_by_contract_name() { + call_and_migrate_purse_holder_contract(InvocationType::ByContractName) +} + +#[ignore] +#[test] +fn should_correctly_migrate_and_upgrade_with_upgrader() { + call_and_migrate_purse_holder_contract(InvocationType::ByUpgrader) +} diff --git a/execution_engine_testing/tests/src/test/wasmless_transfer.rs b/execution_engine_testing/tests/src/test/wasmless_transfer.rs index 2713ba1f43..ee5f786466 100644 --- a/execution_engine_testing/tests/src/test/wasmless_transfer.rs +++ b/execution_engine_testing/tests/src/test/wasmless_transfer.rs @@ -197,11 +197,10 @@ fn transfer_wasmless(wasmless_transfer: WasmlessTransfer) { ); // Make sure postconditions are met: payment purse has to be empty after finalization - let handle_payment = builder.get_handle_payment_contract_hash(); - let contract = builder - .get_addressable_entity(handle_payment) - .expect("should have contract"); - let key = contract + + let handle_payment_entity = builder.get_handle_payment_contract(); + + let key = handle_payment_entity .named_keys() .get(handle_payment::PAYMENT_PURSE_KEY) .cloned() @@ -520,7 +519,7 @@ fn invalid_transfer_wasmless(invalid_wasmless_transfer: InvalidWasmlessTransfer) builder.exec(no_wasm_transfer_request); let result = builder - .get_last_exec_results() + .get_last_exec_result() .expect("Expected to be called after run()") .get(0) .cloned() @@ -544,11 +543,8 @@ fn invalid_transfer_wasmless(invalid_wasmless_transfer: InvalidWasmlessTransfer) assert_eq!(account_1_starting_balance, account_1_closing_balance); // Make sure postconditions are met: payment purse has to be empty after finalization - let handle_payment = builder.get_handle_payment_contract_hash(); - let contract = builder - .get_addressable_entity(handle_payment) - .expect("should have contract"); - let key = contract + let handle_payment_entity = builder.get_handle_payment_contract(); + let key = handle_payment_entity .named_keys() .get(handle_payment::PAYMENT_PURSE_KEY) .cloned() @@ -786,7 +782,7 @@ fn transfer_wasmless_should_fail_without_main_purse_minimum_balance() { builder.exec(no_wasm_transfer_request_2).commit(); - let exec_result = &builder.get_last_exec_results().unwrap()[0]; + let exec_result = &builder.get_last_exec_result().unwrap()[0]; let error = exec_result .as_error() .unwrap_or_else(|| panic!("should have error {:?}", exec_result)); @@ -941,7 +937,7 @@ fn transfer_wasmless_should_fail_with_secondary_purse_insufficient_funds() { builder.exec(no_wasm_transfer_request_1).commit(); - let exec_result = &builder.get_last_exec_results().unwrap()[0]; + let exec_result = &builder.get_last_exec_result().unwrap()[0]; let error = exec_result.as_error().expect("should have error"); assert!( matches!(error, CoreError::InsufficientPayment), diff --git a/node/src/components/contract_runtime.rs b/node/src/components/contract_runtime.rs index fa153e981f..97f8361377 100644 --- a/node/src/components/contract_runtime.rs +++ b/node/src/components/contract_runtime.rs @@ -44,8 +44,9 @@ use casper_storage::{ }, }; use casper_types::{ - bytesrepr::Bytes, BlockHash, BlockHeaderV2, Chainspec, ChainspecRawBytes, ChainspecRegistry, - Digest, EraId, ProtocolVersion, Timestamp, Transaction, UpgradeConfig, U512, + bytesrepr::Bytes, package::PackageKindTag, BlockHash, BlockHeaderV2, Chainspec, + ChainspecRawBytes, ChainspecRegistry, Digest, EraId, Key, ProtocolVersion, Timestamp, + Transaction, UpgradeConfig, U512, }; use crate::{ @@ -1121,9 +1122,12 @@ fn query_total_supply( use engine_state::{Error, QueryResult::*}; let mint = engine_state.get_system_mint_hash(state_hash)?; + + let mint_key = Key::addressable_entity_key(PackageKindTag::System, mint); + let request = QueryRequest::new( state_hash, - mint.into(), + mint_key, vec![mint::TOTAL_SUPPLY_KEY.to_owned()], ); @@ -1151,9 +1155,11 @@ fn query_round_seigniorage_rate( use engine_state::{Error, QueryResult::*}; let mint = engine_state.get_system_mint_hash(state_hash)?; + let mint_key = Key::addressable_entity_key(PackageKindTag::System, mint); + let request = QueryRequest::new( state_hash, - mint.into(), + mint_key, vec![mint::ROUND_SEIGNIORAGE_RATE_KEY.to_owned()], ); diff --git a/node/src/components/transaction_acceptor.rs b/node/src/components/transaction_acceptor.rs index 2e0c42fc92..25f07ebf7e 100644 --- a/node/src/components/transaction_acceptor.rs +++ b/node/src/components/transaction_acceptor.rs @@ -12,9 +12,9 @@ use tracing::{debug, error, trace}; use casper_execution_engine::engine_state::{BalanceRequest, MAX_PAYMENT}; use casper_types::{ account::AccountHash, addressable_entity::AddressableEntity, package::Package, - system::auction::ARG_AMOUNT, BlockHeader, Chainspec, ContractHash, ContractIdentifier, - ContractPackageHash, ContractPackageIdentifier, ContractVersion, ContractVersionKey, - DirectCallV1, ExecutableDeployItem, ExecutableDeployItemIdentifier, Key, ProtocolVersion, + system::auction::ARG_AMOUNT, AddressableEntityHash, BlockHeader, Chainspec, DirectCallV1, + EntityIdentifier, EntityVersion, EntityVersionKey, ExecutableDeployItem, + ExecutableDeployItemIdentifier, Key, PackageHash, PackageIdentifier, ProtocolVersion, Transaction, TransactionConfig, TransactionV1Kind, UserlandTransactionV1, U512, }; @@ -127,6 +127,7 @@ impl TransactionAcceptor { ) .map_err(Error::from), }; + if let Err(error) = is_config_compliant { return self.reject_transaction(effect_builder, *event_metadata, error); } @@ -305,12 +306,14 @@ impl TransactionAcceptor { // validation). ExecutableDeployItemIdentifier::Module | ExecutableDeployItemIdentifier::Transfer - | ExecutableDeployItemIdentifier::Contract(ContractIdentifier::Name(_)) - | ExecutableDeployItemIdentifier::Package(ContractPackageIdentifier::Name { .. }) => { + | ExecutableDeployItemIdentifier::AddressableEntity(EntityIdentifier::Name(_)) + | ExecutableDeployItemIdentifier::Package(PackageIdentifier::Name { .. }) => { self.verify_body(effect_builder, event_metadata, block_header) } - ExecutableDeployItemIdentifier::Contract(ContractIdentifier::Hash(contract_hash)) => { - let query_key = Key::from(contract_hash); + ExecutableDeployItemIdentifier::AddressableEntity(EntityIdentifier::Hash( + contract_hash, + )) => { + let query_key = Key::contract_entity_key(contract_hash); effect_builder .get_addressable_entity(*block_header.state_root_hash(), query_key) .event(move |maybe_contract| Event::GetContractResult { @@ -322,12 +325,9 @@ impl TransactionAcceptor { }) } ExecutableDeployItemIdentifier::Package( - ref contract_package_identifier @ ContractPackageIdentifier::Hash { - contract_package_hash, - .. - }, + ref contract_package_identifier @ PackageIdentifier::Hash { package_hash, .. }, ) => { - let key = Key::from(contract_package_hash); + let key = Key::from(package_hash); let maybe_package_version = contract_package_identifier.version(); effect_builder .get_package(*block_header.state_root_hash(), key) @@ -335,8 +335,8 @@ impl TransactionAcceptor { event_metadata, block_header, is_payment: true, - package_hash: contract_package_hash, - maybe_contract_version: maybe_package_version, + package_hash, + maybe_package_version, maybe_package, }) } @@ -411,38 +411,37 @@ impl TransactionAcceptor { // validation). ExecutableDeployItemIdentifier::Module | ExecutableDeployItemIdentifier::Transfer - | ExecutableDeployItemIdentifier::Contract(ContractIdentifier::Name(_)) - | ExecutableDeployItemIdentifier::Package(ContractPackageIdentifier::Name { .. }) => { + | ExecutableDeployItemIdentifier::AddressableEntity(EntityIdentifier::Name(_)) + | ExecutableDeployItemIdentifier::Package(PackageIdentifier::Name { .. }) => { self.validate_transaction_cryptography(effect_builder, event_metadata) } - ExecutableDeployItemIdentifier::Contract(ContractIdentifier::Hash(contract_hash)) => { - let key = Key::from(contract_hash); + ExecutableDeployItemIdentifier::AddressableEntity(EntityIdentifier::Hash( + entity_hash, + )) => { + let key = Key::contract_entity_key(entity_hash); effect_builder .get_addressable_entity(*block_header.state_root_hash(), key) .event(move |maybe_contract| Event::GetContractResult { event_metadata, block_header, is_payment: false, - contract_hash, + contract_hash: entity_hash, maybe_contract, }) } ExecutableDeployItemIdentifier::Package( - ref package_identifier @ ContractPackageIdentifier::Hash { - contract_package_hash, - .. - }, + ref package_identifier @ PackageIdentifier::Hash { package_hash, .. }, ) => { - let key = Key::from(contract_package_hash); - let maybe_contract_version = package_identifier.version(); + let key = Key::from(package_hash); + let maybe_package_version = package_identifier.version(); effect_builder .get_package(*block_header.state_root_hash(), key) .event(move |maybe_package| Event::GetPackageResult { event_metadata, block_header, is_payment: false, - package_hash: contract_package_hash, - maybe_contract_version, + package_hash, + maybe_package_version, maybe_package, }) } @@ -456,8 +455,8 @@ impl TransactionAcceptor { block_header: Box, ) -> Effects { enum NextStep { - GetContract(ContractHash), - GetPackage(ContractPackageHash, Option), + GetContract(AddressableEntityHash), + GetPackage(PackageHash, Option), CryptoValidation, } @@ -498,7 +497,7 @@ impl TransactionAcceptor { match next_step { NextStep::GetContract(contract_hash) => { - let key = Key::from(contract_hash); + let key = Key::contract_entity_key(contract_hash); effect_builder .get_addressable_entity(*block_header.state_root_hash(), key) .event(move |maybe_contract| Event::GetContractResult { @@ -509,7 +508,7 @@ impl TransactionAcceptor { maybe_contract, }) } - NextStep::GetPackage(package_hash, maybe_contract_version) => { + NextStep::GetPackage(package_hash, maybe_package_version) => { let key = Key::from(package_hash); effect_builder .get_package(*block_header.state_root_hash(), key) @@ -518,7 +517,7 @@ impl TransactionAcceptor { block_header, is_payment: false, package_hash, - maybe_contract_version, + maybe_package_version, maybe_package, }) } @@ -534,7 +533,7 @@ impl TransactionAcceptor { event_metadata: Box, block_header: Box, is_payment: bool, - contract_hash: ContractHash, + contract_hash: AddressableEntityHash, maybe_contract: Option, ) -> Effects { let contract = match maybe_contract { @@ -583,9 +582,9 @@ impl TransactionAcceptor { event_metadata: Box, block_header: Box, is_payment: bool, - package_hash: ContractPackageHash, - maybe_contract_version: Option, - maybe_package: Option, + package_hash: PackageHash, + maybe_contract_version: Option, + maybe_package: Option>, ) -> Effects { let package = match maybe_package { Some(package) => package, @@ -611,10 +610,10 @@ impl TransactionAcceptor { }; let contract_version_key = - ContractVersionKey::new(self.protocol_version.value().major, contract_version); - match package.lookup_contract_hash(contract_version_key) { + EntityVersionKey::new(self.protocol_version.value().major, contract_version); + match package.lookup_entity_hash(contract_version_key) { Some(&contract_hash) => { - let key = Key::from(contract_hash); + let key = Key::contract_entity_key(contract_hash); effect_builder .get_addressable_entity(*block_header.state_root_hash(), key) .event(move |maybe_contract| Event::GetContractResult { @@ -837,7 +836,7 @@ impl Component for TransactionAcceptor { block_header, is_payment, package_hash, - maybe_contract_version, + maybe_package_version, maybe_package, } => self.handle_get_package_result( effect_builder, @@ -845,7 +844,7 @@ impl Component for TransactionAcceptor { block_header, is_payment, package_hash, - maybe_contract_version, + maybe_package_version, maybe_package, ), Event::PutToStorageResult { diff --git a/node/src/components/transaction_acceptor/error.rs b/node/src/components/transaction_acceptor/error.rs index 3f56541163..6ddf0e844a 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::{ - BlockHash, BlockHeader, ContractHash, ContractPackageHash, ContractVersion, - DeployConfigurationFailure, Digest, PublicKey, Timestamp, TransactionV1ConfigFailure, + AddressableEntityHash, BlockHash, BlockHeader, DeployConfigurationFailure, Digest, + EntityVersion, PackageHash, PublicKey, Timestamp, TransactionV1ConfigFailure, }; // `allow` can be removed once https://github.com/casper-network/casper-node/issues/3063 is fixed. @@ -76,16 +76,18 @@ pub(crate) enum ParameterFailure { NoSuchAddressableEntity { public_key: PublicKey }, /// No such contract at given hash. #[error("contract at {contract_hash} does not exist")] - NoSuchContractAtHash { contract_hash: ContractHash }, + NoSuchContractAtHash { + contract_hash: AddressableEntityHash, + }, /// No such contract entrypoint. #[error("contract does not have entry point '{entry_point_name}'")] NoSuchEntryPoint { entry_point_name: String }, /// No such package. #[error("package at {package_hash} does not exist")] - NoSuchPackageAtHash { package_hash: ContractPackageHash }, + NoSuchPackageAtHash { package_hash: PackageHash }, /// Invalid contract at given version. #[error("invalid contract at version: {contract_version}")] - InvalidContractAtVersion { contract_version: ContractVersion }, + InvalidContractAtVersion { contract_version: EntityVersion }, /// Invalid associated keys. #[error("account authorization invalid")] InvalidAssociatedKeys, diff --git a/node/src/components/transaction_acceptor/event.rs b/node/src/components/transaction_acceptor/event.rs index 187c938eb6..3805c33091 100644 --- a/node/src/components/transaction_acceptor/event.rs +++ b/node/src/components/transaction_acceptor/event.rs @@ -3,8 +3,8 @@ use std::fmt::{self, Display, Formatter}; use serde::Serialize; use casper_types::{ - addressable_entity::AddressableEntity, package::Package, BlockHeader, ContractHash, - ContractPackageHash, ContractVersion, Timestamp, Transaction, U512, + AddressableEntity, AddressableEntityHash, BlockHeader, EntityVersion, Package, PackageHash, + Timestamp, Transaction, U512, }; use super::{Error, Source}; @@ -79,7 +79,7 @@ pub(crate) enum Event { event_metadata: Box, block_header: Box, is_payment: bool, - contract_hash: ContractHash, + contract_hash: AddressableEntityHash, maybe_contract: Option, }, /// The result of querying global state for a `Package` to verify the executable logic. @@ -87,9 +87,9 @@ pub(crate) enum Event { event_metadata: Box, block_header: Box, is_payment: bool, - package_hash: ContractPackageHash, - maybe_contract_version: Option, - maybe_package: Option, + package_hash: PackageHash, + maybe_package_version: Option, + maybe_package: Option>, }, } diff --git a/node/src/components/transaction_acceptor/tests.rs b/node/src/components/transaction_acceptor/tests.rs index f19f645ab7..454adc674c 100644 --- a/node/src/components/transaction_acceptor/tests.rs +++ b/node/src/components/transaction_acceptor/tests.rs @@ -395,7 +395,7 @@ impl TestScenario { } ContractScenario::MissingContractAtHash => { let body = TransactionV1Kind::new_stored_contract_by_hash( - ContractHash::default(), + AddressableEntityHash::default(), "call".to_string(), RuntimeArgs::new(), ); @@ -408,7 +408,7 @@ impl TestScenario { } ContractScenario::MissingEntryPoint => { let body = TransactionV1Kind::new_stored_contract_by_hash( - ContractHash::default(), + AddressableEntityHash::default(), "non-existent-entry-point".to_string(), RuntimeArgs::new(), ); @@ -463,7 +463,7 @@ impl TestScenario { } ContractPackageScenario::MissingPackageAtHash => { let body = TransactionV1Kind::new_stored_versioned_contract_by_hash( - ContractPackageHash::default(), + PackageHash::default(), None, "call".to_string(), RuntimeArgs::new(), @@ -477,7 +477,7 @@ impl TestScenario { } ContractPackageScenario::MissingContractVersion => { let body = TransactionV1Kind::new_stored_versioned_contract_by_hash( - ContractPackageHash::default(), + PackageHash::default(), Some(6), "call".to_string(), RuntimeArgs::new(), @@ -669,7 +669,7 @@ impl reactor::Reactor for Reactor { query_request, responder, } => { - let query_result = if let Key::Hash(_) = query_request.key() { + let query_result = if let Key::Package(_) = query_request.key() { match self.test_scenario { TestScenario::FromPeerCustomPaymentContractPackage( ContractPackageScenario::MissingPackageAtHash, @@ -699,13 +699,13 @@ impl reactor::Reactor for Reactor { _, ContractPackageScenario::MissingContractVersion, ) => QueryResult::Success { - value: Box::new(StoredValue::ContractPackage(Package::default())), + value: Box::new(StoredValue::Package(Package::default())), proofs: vec![], }, _ => panic!("unexpected query: {:?}", query_request), } } else { - panic!("expect only queries using Key::Hash variant"); + panic!("expect only queries using Key::Package variant"); }; responder.respond(Ok(query_result)).ignore() } @@ -753,7 +753,7 @@ impl reactor::Reactor for Reactor { } else if let Key::Account(account_hash) = key { let account = create_account(account_hash, self.test_scenario); Some(AddressableEntity::from(account)) - } else if let Key::Hash(_) = key { + } else if let Key::AddressableEntity(_) = key { match self.test_scenario { TestScenario::FromPeerCustomPaymentContract( ContractScenario::MissingContractAtHash, diff --git a/node/src/effect.rs b/node/src/effect.rs index b0e39f9c66..c5e27bb1f3 100644 --- a/node/src/effect.rs +++ b/node/src/effect.rs @@ -1975,13 +1975,15 @@ impl EffectBuilder { } /// 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 + pub(crate) async fn get_package(self, state_root_hash: Digest, key: Key) -> Option> where REv: From, { let query_request = QueryRequest::new(state_root_hash, key, vec![]); match self.query_global_state(query_request).await { - Ok(QueryResult::Success { value, .. }) => value.into_contract_package(), + Ok(QueryResult::Success { value, .. }) => { + value.as_package().map(|pkg| Box::new(pkg.clone())) + } Ok(_) | Err(_) => None, } } diff --git a/node/src/reactor/main_reactor/tests.rs b/node/src/reactor/main_reactor/tests.rs index c87e8e1edd..16a9b26096 100644 --- a/node/src/reactor/main_reactor/tests.rs +++ b/node/src/reactor/main_reactor/tests.rs @@ -16,8 +16,8 @@ use casper_types::{ execution::{Effects, ExecutionResult, ExecutionResultV2, TransformKind}, system::auction::{BidAddr, BidKind, BidsExt, DelegationRate}, testing::TestRng, - AccountConfig, AccountsConfig, ActivationPoint, Block, BlockHash, BlockHeader, CLValue, - Chainspec, ChainspecRawBytes, ContractHash, Deploy, DeployHash, EraId, Key, Motes, + AccountConfig, AccountsConfig, ActivationPoint, AddressableEntityHash, Block, BlockHash, + BlockHeader, CLValue, Chainspec, ChainspecRawBytes, Deploy, DeployHash, EraId, Key, Motes, ProtocolVersion, PublicKey, SecretKey, StoredValue, TimeDiff, Timestamp, Transaction, TransactionHash, ValidatorConfig, U512, }; @@ -1278,7 +1278,7 @@ fn get_system_contract_hash_or_fail( net: &TestingNetwork>, public_key: &PublicKey, system_contract_name: String, -) -> ContractHash { +) -> AddressableEntityHash { let (_, runner) = net .nodes() .iter() diff --git a/node/src/utils/chain_specification.rs b/node/src/utils/chain_specification.rs index 80b3bcf837..8595e13f40 100644 --- a/node/src/utils/chain_specification.rs +++ b/node/src/utils/chain_specification.rs @@ -225,7 +225,7 @@ mod tests { read_host_buffer: HostFunction::new(126, [0, 1, 2]), create_contract_package_at_hash: HostFunction::new(106, [0, 1]), create_contract_user_group: HostFunction::new(107, [0, 1, 2, 3, 4, 5, 6, 7]), - add_contract_version: HostFunction::new(102, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), + add_contract_version: HostFunction::new(102, [0, 1, 2, 3, 4, 5, 6, 7, 8]), disable_contract_version: HostFunction::new(109, [0, 1, 2, 3]), call_contract: HostFunction::new(104, [0, 1, 2, 3, 4, 5, 6]), call_versioned_contract: HostFunction::new(105, [0, 1, 2, 3, 4, 5, 6, 7, 8]), @@ -238,6 +238,8 @@ mod tests { blake2b: HostFunction::new(133, [0, 1, 2, 3]), random_bytes: HostFunction::new(123, [0, 1]), enable_contract_version: HostFunction::new(142, [0, 1, 2, 3]), + // TODO: Update this cost. + add_session_version: HostFunction::default(), }); static EXPECTED_GENESIS_WASM_COSTS: Lazy = Lazy::new(|| { WasmConfig::new( diff --git a/node/src/utils/specimen.rs b/node/src/utils/specimen.rs index 0786bfb99b..87370c5816 100644 --- a/node/src/utils/specimen.rs +++ b/node/src/utils/specimen.rs @@ -22,13 +22,12 @@ use casper_types::{ bytesrepr::Bytes, crypto::{sign, PublicKey, Signature}, AccessRights, AsymmetricType, Block, BlockHash, BlockHeader, BlockHeaderV1, BlockHeaderV2, - BlockSignatures, BlockV2, ChunkWithProof, ContractPackageHash, Deploy, DeployApproval, - DeployApprovalsHash, DeployHash, DeployId, Digest, EraEndV1, EraEndV2, EraId, EraReport, - ExecutableDeployItem, FinalitySignature, FinalitySignatureId, ProtocolVersion, - RewardedSignatures, RuntimeArgs, SecretKey, SemVer, SignedBlockHeader, - SingleBlockRewardedSignatures, TimeDiff, Timestamp, Transaction, TransactionId, TransactionV1, - TransactionV1ApprovalsHash, TransactionV1Builder, TransactionV1Hash, TransactionV1Kind, URef, - KEY_HASH_LENGTH, U512, + BlockSignatures, BlockV2, ChunkWithProof, Deploy, DeployApproval, DeployApprovalsHash, + DeployHash, DeployId, Digest, EraEndV1, EraEndV2, EraId, EraReport, ExecutableDeployItem, + FinalitySignature, FinalitySignatureId, PackageHash, ProtocolVersion, RewardedSignatures, + RuntimeArgs, SecretKey, SemVer, SignedBlockHeader, SingleBlockRewardedSignatures, TimeDiff, + Timestamp, Transaction, TransactionId, TransactionV1, TransactionV1ApprovalsHash, + TransactionV1Builder, TransactionV1Hash, TransactionV1Kind, URef, KEY_HASH_LENGTH, U512, }; use crate::{ @@ -992,11 +991,9 @@ impl LargestSpecimen for U512 { } } -impl LargestSpecimen for ContractPackageHash { +impl LargestSpecimen for PackageHash { fn largest_specimen(estimator: &E, cache: &mut Cache) -> Self { - ContractPackageHash::new( - [LargestSpecimen::largest_specimen(estimator, cache); KEY_HASH_LENGTH], - ) + PackageHash::new([LargestSpecimen::largest_specimen(estimator, cache); KEY_HASH_LENGTH]) } } diff --git a/resources/local/chainspec.toml.in b/resources/local/chainspec.toml.in index b5450911cd..313ffb2674 100644 --- a/resources/local/chainspec.toml.in +++ b/resources/local/chainspec.toml.in @@ -211,7 +211,7 @@ size_multiplier = 100 [wasm.host_function_costs] add = { cost = 5_800, arguments = [0, 0, 0, 0] } add_associated_key = { cost = 9_000, arguments = [0, 0, 0] } -add_contract_version = { cost = 200, arguments = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] } +add_contract_version = { cost = 200, arguments = [0, 0, 0, 0, 0, 0, 0, 0, 0] } blake2b = { cost = 200, arguments = [0, 0, 0, 0] } call_contract = { cost = 4_500, arguments = [0, 0, 0, 0, 0, 420, 0] } call_versioned_contract = { cost = 4_500, arguments = [0, 0, 0, 0, 0, 0, 0, 420, 0] } @@ -253,6 +253,7 @@ transfer_to_account = { cost = 2_500_000_000, arguments = [0, 0, 0, 0, 0, 0, 0] update_associated_key = { cost = 4_200, arguments = [0, 0, 0] } write = { cost = 14_000, arguments = [0, 0, 0, 980] } write_local = { cost = 9_500, arguments = [0, 1_800, 0, 520] } +add_session_version = { cost = 200, arguments = [0, 0] } [system_costs] wasmless_transfer_cost = 100_000_000 diff --git a/resources/production/chainspec.toml b/resources/production/chainspec.toml index 6ce4ca7410..0f3e2e251f 100644 --- a/resources/production/chainspec.toml +++ b/resources/production/chainspec.toml @@ -222,18 +222,7 @@ size_multiplier = 100 [wasm.host_function_costs] add = { cost = 5_800, arguments = [0, 0, 0, 0] } add_associated_key = { cost = 9_000, arguments = [0, 0, 0] } -add_contract_version = { cost = 200, arguments = [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, -] } +add_contract_version = { cost = 200, arguments = [0, 0, 0, 0, 0, 0, 0, 0, 0] } blake2b = { cost = 200, arguments = [0, 0, 0, 0] } call_contract = { cost = 4_500, arguments = [0, 0, 0, 0, 0, 420, 0] } call_versioned_contract = { cost = 4_500, arguments = [ @@ -328,6 +317,7 @@ update_associated_key = { cost = 4_200, arguments = [0, 0, 0] } write = { cost = 14_000, arguments = [0, 0, 0, 980] } write_local = { cost = 9_500, arguments = [0, 1_800, 0, 520] } enable_contract_version = { cost = 200, arguments = [0, 0, 0, 0] } +add_session_version = { cost = 200, arguments = [0, 0] } [system_costs] wasmless_transfer_cost = 100_000_000 diff --git a/resources/test/rpc_schema.json b/resources/test/rpc_schema.json index a238a5c989..db270936ce 100644 --- a/resources/test/rpc_schema.json +++ b/resources/test/rpc_schema.json @@ -2167,7 +2167,7 @@ "additionalProperties": false }, { - "description": "Stored contract referenced by its [`ContractHash`], entry point and an instance of [`RuntimeArgs`].", + "description": "Stored contract referenced by its [`AddressableEntityHash`], entry point and an instance of [`RuntimeArgs`].", "type": "object", "required": [ "StoredContractByHash" @@ -2241,7 +2241,7 @@ "additionalProperties": false }, { - "description": "Stored versioned contract referenced by its [`ContractPackageHash`], entry point and an instance of [`RuntimeArgs`].", + "description": "Stored versioned contract referenced by its [`PackageHash`], entry point and an instance of [`RuntimeArgs`].", "type": "object", "required": [ "StoredVersionedContractByHash" @@ -3049,7 +3049,7 @@ "description": "If `Some`, this is an upgrade for the given contract, otherwise it is an installer.", "anyOf": [ { - "$ref": "#/components/schemas/ContractPackageIdentifier" + "$ref": "#/components/schemas/PackageIdentifier" }, { "type": "null" @@ -3169,8 +3169,8 @@ "description": "Hex-encoded bytes.", "type": "string" }, - "ContractPackageIdentifier": { - "description": "Identifier for a contract package.", + "PackageIdentifier": { + "description": "Identifier for a package.", "oneOf": [ { "description": "The stored contract package within the deploy item is identified by its hash.", @@ -3182,14 +3182,14 @@ "Hash": { "type": "object", "required": [ - "contract_package_hash" + "package_hash" ], "properties": { - "contract_package_hash": { + "package_hash": { "description": "Hash of the contract package.", "allOf": [ { - "$ref": "#/components/schemas/ContractPackageHash" + "$ref": "#/components/schemas/PackageHash" } ] }, @@ -3240,8 +3240,8 @@ } ] }, - "ContractPackageHash": { - "description": "The hex-encoded address of the contract package.", + "PackageHash": { + "description": "The hex-encoded address of the Package.", "type": "string" }, "DirectCallV1": { @@ -3266,7 +3266,7 @@ "description": "Contract hash.", "allOf": [ { - "$ref": "#/components/schemas/ContractHash" + "$ref": "#/components/schemas/AddressableEntityHash" } ] }, @@ -3344,7 +3344,7 @@ "description": "Contract package hash.", "allOf": [ { - "$ref": "#/components/schemas/ContractPackageHash" + "$ref": "#/components/schemas/PackageHash" } ] }, @@ -3423,7 +3423,7 @@ } ] }, - "ContractHash": { + "AddressableEntityHash": { "description": "The hex-encoded address of the addressable entity.", "type": "string" }, @@ -5078,7 +5078,7 @@ "additionalProperties": false }, { - "description": "A contract Wasm.", + "description": "Contract wasm.", "type": "object", "required": [ "ContractWasm" @@ -5104,14 +5104,14 @@ "additionalProperties": false }, { - "description": "A `Package`.", + "description": "A contract package.", "type": "object", "required": [ "ContractPackage" ], "properties": { "ContractPackage": { - "$ref": "#/components/schemas/Package" + "$ref": "#/components/schemas/ContractPackage" } }, "additionalProperties": false @@ -5225,6 +5225,32 @@ } }, "additionalProperties": false + }, + { + "description": "A `Package`.", + "type": "object", + "required": [ + "Package" + ], + "properties": { + "Package": { + "$ref": "#/components/schemas/Package" + } + }, + "additionalProperties": false + }, + { + "description": "A record of byte code.", + "type": "object", + "required": [ + "ByteCode" + ], + "properties": { + "ByteCode": { + "$ref": "#/components/schemas/ByteCode" + } + }, + "additionalProperties": false } ] }, @@ -5268,6 +5294,10 @@ } } }, + "ContractPackageHash": { + "description": "The hash address of the contract package", + "type": "string" + }, "ContractWasmHash": { "description": "The hash address of the contract wasm", "type": "string" @@ -5387,24 +5417,24 @@ "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", + "description": "Runs as session code (caller) Deprecated, retained to allow read back of legacy stored session.", "type": "string", "enum": [ "Session" ] }, { - "description": "Runs within contract's context", + "description": "Runs within called entity's context (called)", "type": "string", "enum": [ - "Contract" + "AddressableEntity" ] }, { - "description": "Installer entry point.", + "description": "This entry point is intended to extract a subset of bytecode. Runs within called entity's context (called)", "type": "string", "enum": [ - "Install" + "Factory" ] } ] @@ -5413,12 +5443,11 @@ "description": "Casper Platform protocol version", "type": "string" }, - "Package": { + "ContractPackage": { "description": "Contract definition, metadata, and security container.", "type": "object", "required": [ "access_key", - "contract_package_kind", "disabled_versions", "groups", "lock_status", @@ -5426,7 +5455,7 @@ ], "properties": { "access_key": { - "description": "Key used to add or disable versions.", + "description": "Key used to add or disable versions", "allOf": [ { "$ref": "#/components/schemas/URef" @@ -5434,15 +5463,14 @@ ] }, "versions": { - "description": "All versions (enabled & disabled).", - "allOf": [ - { - "$ref": "#/components/schemas/Array_of_ContractVersionAndHash" - } - ] + "description": "All versions (enabled & disabled)", + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/ContractHash" + } }, "disabled_versions": { - "description": "Collection of disabled contract versions. The runtime will not permit disabled contract versions to be executed.", + "description": "Disabled versions", "type": "array", "items": { "$ref": "#/components/schemas/ContractVersionKey" @@ -5464,67 +5492,30 @@ "$ref": "#/components/schemas/ContractPackageStatus" } ] - }, - "contract_package_kind": { - "description": "The kind of package.", - "allOf": [ - { - "$ref": "#/components/schemas/ContractPackageKind" - } - ] } } }, - "Array_of_ContractVersionAndHash": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ContractVersionAndHash" - } - }, - "ContractVersionAndHash": { - "type": "object", - "required": [ - "contract_hash", - "contract_version_key" - ], - "properties": { - "contract_version_key": { - "allOf": [ - { - "$ref": "#/components/schemas/ContractVersionKey" - } - ] - }, - "contract_hash": { - "allOf": [ - { - "$ref": "#/components/schemas/ContractHash" - } - ] - } - } + "ContractHash": { + "description": "The hash address of the contract", + "type": "string" }, "ContractVersionKey": { "description": "Major element of `ProtocolVersion` combined with `ContractVersion`.", - "type": "object", - "required": [ - "contract_version", - "protocol_version_major" - ], - "properties": { - "protocol_version_major": { - "description": "Major element of `ProtocolVersion` a `ContractVersion` is compatible with.", + "type": "array", + "items": [ + { "type": "integer", "format": "uint32", "minimum": 0.0 }, - "contract_version": { - "description": "Automatically incremented value for a contract version within a major `ProtocolVersion`.", + { "type": "integer", "format": "uint32", "minimum": 0.0 } - } + ], + "maxItems": 2, + "minItems": 2 }, "Array_of_NamedUserGroup": { "type": "array", @@ -5574,31 +5565,200 @@ } ] }, - "ContractPackageKind": { - "description": "The type of contract package.", + "AddressableEntity": { + "description": "Methods and type signatures supported by a contract.", + "type": "object", + "required": [ + "action_thresholds", + "associated_keys", + "byte_code_hash", + "entry_points", + "main_purse", + "named_keys", + "package_hash", + "protocol_version" + ], + "properties": { + "package_hash": { + "$ref": "#/components/schemas/PackageHash" + }, + "byte_code_hash": { + "$ref": "#/components/schemas/ByteCodeHash" + }, + "named_keys": { + "$ref": "#/components/schemas/NamedKeys" + }, + "entry_points": { + "$ref": "#/components/schemas/Array_of_NamedEntryPoint" + }, + "protocol_version": { + "$ref": "#/components/schemas/ProtocolVersion" + }, + "main_purse": { + "$ref": "#/components/schemas/URef" + }, + "associated_keys": { + "$ref": "#/components/schemas/AssociatedKeys" + }, + "action_thresholds": { + "$ref": "#/components/schemas/ActionThresholds" + } + } + }, + "ByteCodeHash": { + "description": "The hash address of the contract wasm", + "type": "string" + }, + "Package": { + "description": "Entity definition, metadata, and security container.", + "type": "object", + "required": [ + "access_key", + "disabled_versions", + "groups", + "lock_status", + "package_kind", + "versions" + ], + "properties": { + "access_key": { + "description": "Key used to add or disable versions.", + "allOf": [ + { + "$ref": "#/components/schemas/URef" + } + ] + }, + "versions": { + "description": "All versions (enabled & disabled).", + "allOf": [ + { + "$ref": "#/components/schemas/Array_of_EntityVersionAndHash" + } + ] + }, + "disabled_versions": { + "description": "Collection of disabled entity versions. The runtime will not permit disabled entity versions to be executed.", + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityVersionKey" + }, + "uniqueItems": true + }, + "groups": { + "description": "Mapping maintaining the set of URefs associated with each \"user group\". This can be used to control access to methods in a particular version of the entity. A method is callable by any context which \"knows\" any of the URefs associated with the method's user group.", + "allOf": [ + { + "$ref": "#/components/schemas/Array_of_NamedUserGroup" + } + ] + }, + "lock_status": { + "description": "A flag that determines whether a entity is locked", + "allOf": [ + { + "$ref": "#/components/schemas/PackageStatus" + } + ] + }, + "package_kind": { + "description": "The kind of package.", + "allOf": [ + { + "$ref": "#/components/schemas/PackageKind" + } + ] + } + } + }, + "Array_of_EntityVersionAndHash": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityVersionAndHash" + } + }, + "EntityVersionAndHash": { + "type": "object", + "required": [ + "addressable_entity_hash", + "entity_version_key" + ], + "properties": { + "entity_version_key": { + "allOf": [ + { + "$ref": "#/components/schemas/EntityVersionKey" + } + ] + }, + "addressable_entity_hash": { + "allOf": [ + { + "$ref": "#/components/schemas/AddressableEntityHash" + } + ] + } + } + }, + "EntityVersionKey": { + "description": "Major element of `ProtocolVersion` combined with `EntityVersion`.", + "type": "object", + "required": [ + "entity_version", + "protocol_version_major" + ], + "properties": { + "protocol_version_major": { + "description": "Major element of `ProtocolVersion` a `ContractVersion` is compatible with.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "entity_version": { + "description": "Automatically incremented value for a contract version within a major `ProtocolVersion`.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + } + }, + "PackageStatus": { + "description": "A enum to determine the lock status of the package.", "oneOf": [ { - "description": "Contract Packages associated with Wasm stored on chain.", + "description": "The package is locked and cannot be versioned.", "type": "string", "enum": [ - "Wasm" + "Locked" ] }, { - "description": "Contract Package associated with a native contract implementation.", + "description": "The package is unlocked and can be versioned.", + "type": "string", + "enum": [ + "Unlocked" + ] + } + ] + }, + "PackageKind": { + "description": "The type of Package.", + "oneOf": [ + { + "description": "Package associated with a native contract implementation.", "type": "object", "required": [ "System" ], "properties": { "System": { - "$ref": "#/components/schemas/SystemContractType" + "$ref": "#/components/schemas/SystemEntityType" } }, "additionalProperties": false }, { - "description": "Contract Package associated with an Account hash.", + "description": "Package associated with an Account hash.", "type": "object", "required": [ "Account" @@ -5611,15 +5771,15 @@ "additionalProperties": false }, { - "description": "Contract Packages from the previous format.", + "description": "Packages associated with Wasm stored on chain.", "type": "string", "enum": [ - "Legacy" + "SmartContract" ] } ] }, - "SystemContractType": { + "SystemEntityType": { "description": "System contract types.\n\nUsed by converting to a `u32` and passing as the `system_contract_index` argument of `ext_ffi::casper_get_system_contract()`.", "oneOf": [ { @@ -5652,46 +5812,41 @@ } ] }, - "AddressableEntity": { - "description": "Methods and type signatures supported by a contract.", + "ByteCode": { + "description": "A container for contract's WASM bytes.", "type": "object", "required": [ - "action_thresholds", - "associated_keys", - "contract_package_hash", - "contract_wasm_hash", - "entry_points", - "main_purse", - "named_keys", - "protocol_version" + "byte_code_kind", + "bytes" ], "properties": { - "contract_package_hash": { - "$ref": "#/components/schemas/ContractPackageHash" + "byte_code_kind": { + "$ref": "#/components/schemas/ByteCodeKind" }, - "contract_wasm_hash": { - "$ref": "#/components/schemas/ContractWasmHash" - }, - "named_keys": { - "$ref": "#/components/schemas/NamedKeys" - }, - "entry_points": { - "$ref": "#/components/schemas/Array_of_NamedEntryPoint" - }, - "protocol_version": { - "$ref": "#/components/schemas/ProtocolVersion" - }, - "main_purse": { - "$ref": "#/components/schemas/URef" - }, - "associated_keys": { - "$ref": "#/components/schemas/AssociatedKeys" - }, - "action_thresholds": { - "$ref": "#/components/schemas/ActionThresholds" + "bytes": { + "$ref": "#/components/schemas/Bytes" } } }, + "ByteCodeKind": { + "description": "The type of Byte code.", + "oneOf": [ + { + "description": "Empty byte code.", + "type": "string", + "enum": [ + "Empty" + ] + }, + { + "description": "Byte code to be executed with the V1 Casper execution engine.", + "type": "string", + "enum": [ + "V1CasperWasm" + ] + } + ] + }, "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 2a340bd420..e44920f31c 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -907,7 +907,7 @@ "additionalProperties": false }, { - "description": "Stored contract referenced by its [`ContractHash`], entry point and an instance of [`RuntimeArgs`].", + "description": "Stored contract referenced by its [`AddressableEntityHash`], entry point and an instance of [`RuntimeArgs`].", "type": "object", "required": [ "StoredContractByHash" @@ -981,7 +981,7 @@ "additionalProperties": false }, { - "description": "Stored versioned contract referenced by its [`ContractPackageHash`], entry point and an instance of [`RuntimeArgs`].", + "description": "Stored versioned contract referenced by its [`PackageHash`], entry point and an instance of [`RuntimeArgs`].", "type": "object", "required": [ "StoredVersionedContractByHash" diff --git a/smart_contracts/contract/src/contract_api/account.rs b/smart_contracts/contract/src/contract_api/account.rs index bc1f21d54f..4482dec819 100644 --- a/smart_contracts/contract/src/contract_api/account.rs +++ b/smart_contracts/contract/src/contract_api/account.rs @@ -8,11 +8,13 @@ use casper_types::{ addressable_entity::{ ActionType, AddKeyFailure, RemoveKeyFailure, SetThresholdFailure, UpdateKeyFailure, Weight, }, - bytesrepr, URef, UREF_SERIALIZED_LENGTH, + api_error, bytesrepr, EntryPoints, URef, UREF_SERIALIZED_LENGTH, }; use super::to_ptr; -use crate::{contract_api, ext_ffi, unwrap_or_revert::UnwrapOrRevert}; +use crate::{ + contract_api, contract_api::runtime::revert, ext_ffi, unwrap_or_revert::UnwrapOrRevert, +}; /// Retrieves the ID of the account's main purse. pub fn get_main_purse() -> URef { @@ -93,3 +95,15 @@ pub fn update_associated_key( Err(UpdateKeyFailure::try_from(result).unwrap_or_revert()) } } + +/// Add session code to an entity associated with an Account. +pub fn add_session_version(entry_points: EntryPoints) { + let (entry_points_ptr, entry_points_size, _entry_point_bytes) = to_ptr(entry_points); + + let result = unsafe { ext_ffi::casper_add_session_logic(entry_points_ptr, entry_points_size) }; + + match api_error::result_from(result) { + Ok(_) => {} + Err(e) => revert(e), + } +} diff --git a/smart_contracts/contract/src/contract_api/runtime.rs b/smart_contracts/contract/src/contract_api/runtime.rs index 155463039b..91a2ecc26e 100644 --- a/smart_contracts/contract/src/contract_api/runtime.rs +++ b/smart_contracts/contract/src/contract_api/runtime.rs @@ -8,9 +8,9 @@ use casper_types::{ addressable_entity::NamedKeys, api_error, bytesrepr::{self, FromBytes}, - package::ContractVersion, + package::EntityVersion, system::CallStackElement, - ApiError, BlockTime, CLTyped, CLValue, ContractHash, ContractPackageHash, Key, Phase, + AddressableEntityHash, ApiError, BlockTime, CLTyped, CLValue, Key, PackageHash, Phase, RuntimeArgs, URef, BLAKE2B_DIGEST_LENGTH, BLOCKTIME_SERIALIZED_LENGTH, PHASE_SERIALIZED_LENGTH, }; @@ -47,7 +47,7 @@ pub fn revert>(error: T) -> ! { /// stored contract calls [`revert`], then execution stops and `call_contract` doesn't return. /// Otherwise `call_contract` returns `()`. pub fn call_contract( - contract_hash: ContractHash, + contract_hash: AddressableEntityHash, entry_point_name: &str, runtime_args: RuntimeArgs, ) -> T { @@ -83,8 +83,8 @@ pub fn call_contract( /// `call_versioned_contract`. If the stored contract calls [`revert`], then execution stops and /// `call_versioned_contract` doesn't return. Otherwise `call_versioned_contract` returns `()`. pub fn call_versioned_contract( - contract_package_hash: ContractPackageHash, - contract_version: Option, + contract_package_hash: PackageHash, + contract_version: Option, entry_point_name: &str, runtime_args: RuntimeArgs, ) -> T { diff --git a/smart_contracts/contract/src/contract_api/storage.rs b/smart_contracts/contract/src/contract_api/storage.rs index 053b492eca..ca8f63bc57 100644 --- a/smart_contracts/contract/src/contract_api/storage.rs +++ b/smart_contracts/contract/src/contract_api/storage.rs @@ -7,8 +7,8 @@ use casper_types::{ addressable_entity::{EntryPoints, NamedKeys}, api_error, bytesrepr::{self, FromBytes, ToBytes}, - package::ContractVersion, - AccessRights, ApiError, CLTyped, CLValue, ContractHash, ContractPackageHash, HashAddr, Key, + package::EntityVersion, + AccessRights, AddressableEntityHash, ApiError, CLTyped, CLValue, HashAddr, Key, PackageHash, URef, DICTIONARY_ITEM_KEY_MAX_LENGTH, UREF_SERIALIZED_LENGTH, }; @@ -106,7 +106,7 @@ pub fn new_contract( named_keys: Option, hash_name: Option, uref_name: Option, -) -> (ContractHash, ContractVersion) { +) -> (AddressableEntityHash, EntityVersion) { create_contract(entry_points, named_keys, hash_name, uref_name, false) } @@ -123,17 +123,25 @@ pub fn new_locked_contract( named_keys: Option, hash_name: Option, uref_name: Option, -) -> (ContractHash, ContractVersion) { +) -> (AddressableEntityHash, EntityVersion) { create_contract(entry_points, named_keys, hash_name, uref_name, true) } +// fn foo(entry_points: EntryPoints) { +// let package_hash = my_package_hash; +// +// add_contract_version(package_hash, entry_points, NamedKeys::new()); +// +// disable_contract_version(package_hash, my_previous_entity_hash); +// } + fn create_contract( entry_points: EntryPoints, named_keys: Option, hash_name: Option, uref_name: Option, is_locked: bool, -) -> (ContractHash, ContractVersion) { +) -> (AddressableEntityHash, EntityVersion) { let (contract_package_hash, access_uref) = create_contract_package(is_locked); if let Some(hash_name) = hash_name { @@ -155,12 +163,12 @@ fn create_contract( /// Create a new (versioned) contract stored under a Key::Hash. Initially there /// are no versions; a version must be added via `add_contract_version` before /// the contract can be executed. -pub fn create_contract_package_at_hash() -> (ContractPackageHash, URef) { +pub fn create_contract_package_at_hash() -> (PackageHash, URef) { create_contract_package(false) } -fn create_contract_package(is_locked: bool) -> (ContractPackageHash, URef) { - let mut hash_addr: HashAddr = ContractPackageHash::default().value(); +fn create_contract_package(is_locked: bool) -> (PackageHash, URef) { + let mut hash_addr: HashAddr = PackageHash::default().value(); let mut access_addr = [0u8; 32]; unsafe { ext_ffi::casper_create_contract_package_at_hash( @@ -169,7 +177,7 @@ fn create_contract_package(is_locked: bool) -> (ContractPackageHash, URef) { is_locked, ); } - let contract_package_hash: ContractPackageHash = hash_addr.into(); + let contract_package_hash: PackageHash = hash_addr.into(); let access_uref = URef::new(access_addr, AccessRights::READ_ADD_WRITE); (contract_package_hash, access_uref) @@ -183,7 +191,7 @@ fn create_contract_package(is_locked: bool) -> (ContractPackageHash, URef) { /// function returns the list of new URefs created for the group (the list will /// contain `num_new_urefs` elements). pub fn create_contract_user_group( - contract_package_hash: ContractPackageHash, + contract_package_hash: PackageHash, group_label: &str, num_new_urefs: u8, // number of new urefs to populate the group with existing_urefs: BTreeSet, // also include these existing urefs in the group @@ -217,7 +225,7 @@ pub fn create_contract_user_group( /// Extends specified group with a new `URef`. pub fn provision_contract_user_group_uref( - package_hash: ContractPackageHash, + package_hash: PackageHash, label: &str, ) -> Result { let (contract_package_hash_ptr, contract_package_hash_size, _bytes1) = @@ -243,7 +251,7 @@ pub fn provision_contract_user_group_uref( /// Removes specified urefs from a named group. pub fn remove_contract_user_group_urefs( - package_hash: ContractPackageHash, + package_hash: PackageHash, label: &str, urefs: BTreeSet, ) -> Result<(), ApiError> { @@ -265,10 +273,7 @@ pub fn remove_contract_user_group_urefs( } /// Remove a named group from given contract. -pub fn remove_contract_user_group( - package_hash: ContractPackageHash, - label: &str, -) -> Result<(), ApiError> { +pub fn remove_contract_user_group(package_hash: PackageHash, label: &str) -> Result<(), ApiError> { let (contract_package_hash_ptr, contract_package_hash_size, _bytes1) = contract_api::to_ptr(package_hash); let (label_ptr, label_size, _bytes3) = contract_api::to_ptr(label); @@ -283,45 +288,45 @@ pub fn remove_contract_user_group( api_error::result_from(ret) } -/// Add a new version of a contract to the contract stored at the given -/// `Key`. Note that this contract must have been created by -/// `create_contract` or `create_contract_package_at_hash` first. +/// Add version to existing Package. pub fn add_contract_version( - contract_package_hash: ContractPackageHash, + package_hash: PackageHash, entry_points: EntryPoints, named_keys: NamedKeys, -) -> (ContractHash, ContractVersion) { - let (contract_package_hash_ptr, contract_package_hash_size, _bytes1) = - contract_api::to_ptr(contract_package_hash); - let (entry_points_ptr, entry_points_size, _bytes4) = contract_api::to_ptr(entry_points); - let (named_keys_ptr, named_keys_size, _bytes5) = contract_api::to_ptr(named_keys); +) -> (AddressableEntityHash, EntityVersion) { + // Retain the underscore as Wasm transpiliation requires it. + let (package_hash_ptr, package_hash_size, _package_hash_bytes) = + contract_api::to_ptr(package_hash); + let (entry_points_ptr, entry_points_size, _entry_point_bytes) = + contract_api::to_ptr(entry_points); + let (named_keys_ptr, named_keys_size, _named_keys_bytes) = contract_api::to_ptr(named_keys); - let mut output_ptr = vec![0u8; Key::max_serialized_length()]; - let mut total_bytes: usize = 0; + let mut output_ptr = vec![0u8; 32]; + // let mut total_bytes: usize = 0; - let mut contract_version: ContractVersion = 0; + let mut entity_version: EntityVersion = 0; let ret = unsafe { - ext_ffi::casper_add_contract_version( - contract_package_hash_ptr, - contract_package_hash_size, - &mut contract_version as *mut ContractVersion, + ext_ffi::casper_add_package_version( + package_hash_ptr, + package_hash_size, + &mut entity_version as *mut EntityVersion, // Fixed width entry_points_ptr, entry_points_size, named_keys_ptr, named_keys_size, output_ptr.as_mut_ptr(), output_ptr.len(), - &mut total_bytes as *mut usize, + // &mut total_bytes as *mut usize, ) }; match api_error::result_from(ret) { Ok(_) => {} Err(e) => revert(e), } - output_ptr.truncate(total_bytes); - let contract_hash = bytesrepr::deserialize(output_ptr).unwrap_or_revert(); - (contract_hash, contract_version) + // output_ptr.truncate(32usize); + let entity_hash = bytesrepr::deserialize(output_ptr).unwrap_or_revert(); + (entity_hash, entity_version) } /// Disable a version of a contract from the contract stored at the given @@ -329,8 +334,8 @@ pub fn add_contract_version( /// `call_versioned_contract`. Note that this contract must have been created by /// `create_contract` or `create_contract_package_at_hash` first. pub fn disable_contract_version( - contract_package_hash: ContractPackageHash, - contract_hash: ContractHash, + contract_package_hash: PackageHash, + contract_hash: AddressableEntityHash, ) -> Result<(), ApiError> { let (contract_package_hash_ptr, contract_package_hash_size, _bytes1) = contract_api::to_ptr(contract_package_hash); @@ -353,8 +358,8 @@ pub fn disable_contract_version( /// `call_versioned_contract`. Note that this contract must have been created by /// [`new_contract`] or [`create_contract_package_at_hash`] first. pub fn enable_contract_version( - contract_package_hash: ContractPackageHash, - contract_hash: ContractHash, + contract_package_hash: PackageHash, + contract_hash: AddressableEntityHash, ) -> Result<(), ApiError> { let (contract_package_hash_ptr, contract_package_hash_size, _bytes1) = contract_api::to_ptr(contract_package_hash); diff --git a/smart_contracts/contract/src/contract_api/system.rs b/smart_contracts/contract/src/contract_api/system.rs index b7b0dff86b..973f11ee28 100644 --- a/smart_contracts/contract/src/contract_api/system.rs +++ b/smart_contracts/contract/src/contract_api/system.rs @@ -6,12 +6,13 @@ use core::mem::MaybeUninit; use casper_types::{ account::AccountHash, api_error, bytesrepr, + package::PackageKindTag, system::{ auction::{self, EraInfo}, - SystemContractType, + SystemEntityType, }, - ApiError, ContractHash, EraId, HashAddr, PublicKey, TransferResult, TransferredTo, URef, U512, - UREF_SERIALIZED_LENGTH, + AddressableEntityHash, ApiError, EraId, HashAddr, Key, PublicKey, TransferResult, + TransferredTo, URef, U512, UREF_SERIALIZED_LENGTH, }; use crate::{ @@ -20,11 +21,11 @@ use crate::{ unwrap_or_revert::UnwrapOrRevert, }; -fn get_system_contract(system_contract: SystemContractType) -> ContractHash { +fn get_system_contract(system_contract: SystemEntityType) -> AddressableEntityHash { let system_contract_index = system_contract.into(); - let contract_hash: ContractHash = { + let contract_hash: AddressableEntityHash = { let result = { - let mut hash_data_raw: HashAddr = ContractHash::default().value(); + let mut hash_data_raw: HashAddr = AddressableEntityHash::default().value(); let value = unsafe { ext_ffi::casper_get_system_contract( system_contract_index, @@ -46,29 +47,57 @@ fn get_system_contract(system_contract: SystemContractType) -> ContractHash { /// Returns a read-only pointer to the Mint contract. /// /// Any failure will trigger [`revert`](runtime::revert) with an appropriate [`ApiError`]. -pub fn get_mint() -> ContractHash { - get_system_contract(SystemContractType::Mint) +pub fn get_mint() -> AddressableEntityHash { + get_system_contract(SystemEntityType::Mint) +} + +/// Returns a read-only pointer to the Mint contract as a Key. +/// +/// Any failure will trigger [`revert`](runtime::revert) with an appropriate [`ApiError`]. +pub fn get_mint_key() -> Key { + Key::addressable_entity_key(PackageKindTag::System, get_mint()) } /// Returns a read-only pointer to the Handle Payment contract. /// /// Any failure will trigger [`revert`](runtime::revert) with an appropriate [`ApiError`]. -pub fn get_handle_payment() -> ContractHash { - get_system_contract(SystemContractType::HandlePayment) +pub fn get_handle_payment() -> AddressableEntityHash { + get_system_contract(SystemEntityType::HandlePayment) +} + +/// Returns a read-only pointer to the Handle Payment contract as a Key. +/// +/// Any failure will trigger [`revert`](runtime::revert) with an appropriate [`ApiError`]. +pub fn get_handle_payment_key() -> Key { + Key::addressable_entity_key(PackageKindTag::System, get_handle_payment()) } /// Returns a read-only pointer to the Standard Payment contract. /// /// Any failure will trigger [`revert`](runtime::revert) with an appropriate [`ApiError`]. -pub fn get_standard_payment() -> ContractHash { - get_system_contract(SystemContractType::StandardPayment) +pub fn get_standard_payment() -> AddressableEntityHash { + get_system_contract(SystemEntityType::StandardPayment) +} + +/// Returns a read-only pointer to the Standard Payment contract as a Key. +/// +/// Any failure will trigger [`revert`](runtime::revert) with an appropriate [`ApiError`]. +pub fn get_standard_payment_key() -> Key { + Key::addressable_entity_key(PackageKindTag::System, get_standard_payment()) } /// Returns a read-only pointer to the Auction contract. /// /// Any failure will trigger [`revert`](runtime::revert) with appropriate [`ApiError`]. -pub fn get_auction() -> ContractHash { - get_system_contract(SystemContractType::Auction) +pub fn get_auction() -> AddressableEntityHash { + get_system_contract(SystemEntityType::Auction) +} + +/// Returns a read-only pointer to the Auction contract as a Key. +/// +/// Any failure will trigger [`revert`](runtime::revert) with an appropriate [`ApiError`]. +pub fn get_auction_key() -> Key { + Key::addressable_entity_key(PackageKindTag::System, get_auction()) } /// Creates a new empty purse and returns its [`URef`]. diff --git a/smart_contracts/contract/src/ext_ffi.rs b/smart_contracts/contract/src/ext_ffi.rs index 7bf2bce38b..36aec2f1d6 100644 --- a/smart_contracts/contract/src/ext_ffi.rs +++ b/smart_contracts/contract/src/ext_ffi.rs @@ -476,7 +476,7 @@ extern "C" { bytes_written: *mut usize, ) -> i32; /// Creates new contract package at hash. Returns both newly generated - /// [`casper_types::ContractPackageHash`] and a [`casper_types::URef`] for further + /// [`casper_types::PackageHash`] and a [`casper_types::URef`] for further /// modifying access. pub fn casper_create_contract_package_at_hash( hash_addr_ptr: *mut u8, @@ -506,24 +506,28 @@ extern "C" { existing_urefs_size: usize, output_size_ptr: *mut usize, ) -> i32; - /// Adds new contract version to a contract package. + /// Adds new session logic to an addressable entity of kind Account. /// /// # Arguments + /// * `entry_points_ptr` - pointer to serialized [`casper_types::EntryPoints`] + /// * `entry_points_size` - size of serialized [`casper_types::EntryPoints`] + pub fn casper_add_session_logic(entry_points_ptr: *const u8, entry_points_size: usize) -> i32; + /// Adds a new version to a package. /// - /// * `contract_package_hash_ptr` - pointer to serialized contract package hash. - /// * `contract_package_hash_size` - size of contract package hash in serialized form. + /// # Arguments + /// + /// * `package_hash_ptr` - pointer to serialized package hash. + /// * `package_hash_size` - size of package hash in serialized form. /// * `version_ptr` - output parameter where new version assigned by host is set /// * `entry_points_ptr` - pointer to serialized [`casper_types::EntryPoints`] /// * `entry_points_size` - size of serialized [`casper_types::EntryPoints`] /// * `named_keys_ptr` - pointer to serialized [`casper_types::addressable_entity::NamedKeys`] /// * `named_keys_size` - size of serialized [`casper_types::addressable_entity::NamedKeys`] /// * `output_ptr` - pointer to a memory where host assigned contract hash is set to - /// * `output_size` - size of memory area that host can write to - /// * `bytes_written_ptr` - pointer to a value where host will set a number of bytes written to - /// the `output_size` pointer - pub fn casper_add_contract_version( - contract_package_hash_ptr: *const u8, - contract_package_hash_size: usize, + /// * `output_size` - expected width of output (currently 32) + pub fn casper_add_package_version( + package_hash_ptr: *const u8, + package_hash_size: usize, version_ptr: *const u32, entry_points_ptr: *const u8, entry_points_size: usize, @@ -531,7 +535,6 @@ extern "C" { named_keys_size: usize, output_ptr: *mut u8, output_size: usize, - bytes_written_ptr: *mut usize, ) -> i32; /// Disables contract in a contract package. Returns non-zero standard error for a failure, /// otherwise a zero indicates success. diff --git a/smart_contracts/contracts/admin/disable-contract/src/main.rs b/smart_contracts/contracts/admin/disable-contract/src/main.rs index c64cab8830..444ab513ee 100644 --- a/smart_contracts/contracts/admin/disable-contract/src/main.rs +++ b/smart_contracts/contracts/admin/disable-contract/src/main.rs @@ -5,7 +5,7 @@ use casper_contract::{ contract_api::{runtime, storage}, unwrap_or_revert::UnwrapOrRevert, }; -use casper_types::{ContractHash, ContractPackageHash}; +use casper_types::{AddressableEntityHash, PackageHash}; const ARG_CONTRACT_PACKAGE_HASH: &str = "contract_package_hash"; const ARG_CONTRACT_HASH: &str = "contract_hash"; @@ -13,9 +13,8 @@ const ARG_CONTRACT_HASH: &str = "contract_hash"; #[no_mangle] pub extern "C" fn call() { // This contract can be run only by an administrator account. - let contract_package_hash: ContractPackageHash = - runtime::get_named_arg(ARG_CONTRACT_PACKAGE_HASH); - let contract_hash: ContractHash = runtime::get_named_arg(ARG_CONTRACT_HASH); + let contract_package_hash: PackageHash = runtime::get_named_arg(ARG_CONTRACT_PACKAGE_HASH); + let contract_hash: AddressableEntityHash = runtime::get_named_arg(ARG_CONTRACT_HASH); storage::disable_contract_version(contract_package_hash, contract_hash).unwrap_or_revert(); } diff --git a/smart_contracts/contracts/admin/enable-contract/src/main.rs b/smart_contracts/contracts/admin/enable-contract/src/main.rs index 53cc4c4cdd..8700bf2554 100644 --- a/smart_contracts/contracts/admin/enable-contract/src/main.rs +++ b/smart_contracts/contracts/admin/enable-contract/src/main.rs @@ -5,7 +5,7 @@ use casper_contract::{ contract_api::{runtime, storage}, unwrap_or_revert::UnwrapOrRevert, }; -use casper_types::{ContractHash, ContractPackageHash}; +use casper_types::{AddressableEntityHash, PackageHash}; const ARG_CONTRACT_PACKAGE_HASH: &str = "contract_package_hash"; const ARG_CONTRACT_HASH: &str = "contract_hash"; @@ -13,9 +13,8 @@ const ARG_CONTRACT_HASH: &str = "contract_hash"; #[no_mangle] pub extern "C" fn call() { // This contract can be run only by an administrator account. - let contract_package_hash: ContractPackageHash = - runtime::get_named_arg(ARG_CONTRACT_PACKAGE_HASH); - let contract_hash: ContractHash = runtime::get_named_arg(ARG_CONTRACT_HASH); + let contract_package_hash: PackageHash = runtime::get_named_arg(ARG_CONTRACT_PACKAGE_HASH); + let contract_hash: AddressableEntityHash = runtime::get_named_arg(ARG_CONTRACT_HASH); storage::enable_contract_version(contract_package_hash, contract_hash).unwrap_or_revert(); } diff --git a/smart_contracts/contracts/client/call-contract/src/main.rs b/smart_contracts/contracts/client/call-contract/src/main.rs index b4d9fd6d62..238ead3694 100644 --- a/smart_contracts/contracts/client/call-contract/src/main.rs +++ b/smart_contracts/contracts/client/call-contract/src/main.rs @@ -11,7 +11,7 @@ use casper_contract::{contract_api::runtime, ext_ffi, unwrap_or_revert::UnwrapOr use casper_types::{ api_error, bytesrepr::{self, Bytes, ToBytes}, - ApiError, ContractHash, RuntimeArgs, + AddressableEntityHash, ApiError, RuntimeArgs, }; const ARG_CONTRACT_HASH: &str = "contract_hash"; @@ -23,7 +23,7 @@ const ARG_ARGUMENTS: &str = "arguments"; // Accepts entrypoint name, and saves possible return value into URef stored in named keys. #[no_mangle] pub extern "C" fn call() { - let contract_hash: ContractHash = runtime::get_named_arg(ARG_CONTRACT_HASH); + let contract_hash: AddressableEntityHash = runtime::get_named_arg(ARG_CONTRACT_HASH); let entrypoint: String = runtime::get_named_arg(ARG_ENTRYPOINT); let arguments: RuntimeArgs = runtime::get_named_arg(ARG_ARGUMENTS); @@ -59,7 +59,7 @@ fn read_host_buffer_into(dest: &mut [u8]) -> Result { /// Calls a contract and returns unwrapped [`CLValue`]. fn call_contract_forward( entrypoint: String, - contract_hash: ContractHash, + contract_hash: AddressableEntityHash, arguments: RuntimeArgs, ) -> Option { let entry_point_name: &str = &entrypoint; diff --git a/smart_contracts/contracts/explorer/faucet-stored/src/main.rs b/smart_contracts/contracts/explorer/faucet-stored/src/main.rs index 1354eddbac..8ea428c1a6 100644 --- a/smart_contracts/contracts/explorer/faucet-stored/src/main.rs +++ b/smart_contracts/contracts/explorer/faucet-stored/src/main.rs @@ -10,8 +10,8 @@ use casper_contract::{ unwrap_or_revert::UnwrapOrRevert, }; use casper_types::{ - addressable_entity::NamedKeys, ApiError, CLType, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Parameter, PublicKey, URef, U512, + addressable_entity::NamedKeys, package::PackageKindTag, ApiError, CLType, EntryPoint, + EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, PublicKey, URef, U512, }; #[repr(u16)] @@ -114,7 +114,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let set_variables = EntryPoint::new( @@ -135,7 +135,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let authorize_to = EntryPoint::new( @@ -146,7 +146,7 @@ pub extern "C" fn call() { )], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(faucet); @@ -223,7 +223,7 @@ pub extern "C" fn call() { ); runtime::put_key( &format!("{}_{}", faucet::CONTRACT_NAME, id), - contract_hash.into(), + Key::addressable_entity_key(PackageKindTag::SmartContract, contract_hash), ); // This is specifically for this installing account, which would allow one installing account diff --git a/smart_contracts/contracts/explorer/faucet/README.md b/smart_contracts/contracts/explorer/faucet/README.md index 696b63ee91..43a708c7f5 100644 --- a/smart_contracts/contracts/explorer/faucet/README.md +++ b/smart_contracts/contracts/explorer/faucet/README.md @@ -35,7 +35,7 @@ If you try to invoke the contract before these variables are set, then you'll ge | feature | cost | |--------------------------|------------------| -| faucet install | `83_594_845_660` | +| faucet install | `84_007_229_270` | | faucet set variables | `648_705_070` | -| faucet call by installer | `3_244_975_770` | +| faucet call by installer | `3_245_605_770` | | faucet call by user | `3_364_807_470` | 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 2de5870449..c3cd3c6476 100644 --- a/smart_contracts/contracts/profiling/host-function-metrics/src/lib.rs +++ b/smart_contracts/contracts/profiling/host-function-metrics/src/lib.rs @@ -15,8 +15,8 @@ use casper_types::{ account::AccountHash, addressable_entity::{ActionType, NamedKeys, Weight}, bytesrepr::Bytes, - runtime_args, ApiError, BlockTime, CLType, CLValue, ContractHash, ContractVersion, EntryPoint, - EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, Phase, U512, + runtime_args, AddressableEntityHash, ApiError, BlockTime, CLType, CLValue, EntityVersion, + EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, Phase, U512, }; const MIN_FUNCTION_NAME_LENGTH: usize = 1; @@ -216,7 +216,7 @@ pub extern "C" fn call() { fn store_function( entry_point_name: &str, named_keys: Option, -) -> (ContractHash, ContractVersion) { +) -> (AddressableEntityHash, EntityVersion) { let entry_points = { let mut entry_points = EntryPoints::new(); @@ -228,7 +228,7 @@ fn store_function( ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); 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 179e201ce2..2b30823286 100644 --- a/smart_contracts/contracts/test/add-gas-subcall/src/main.rs +++ b/smart_contracts/contracts/test/add-gas-subcall/src/main.rs @@ -9,8 +9,8 @@ use alloc::string::String; use casper_contract::contract_api::{runtime, storage}; use casper_types::{ - runtime_args, ApiError, CLType, ContractHash, ContractVersion, EntryPoint, EntryPointAccess, - EntryPointType, EntryPoints, Key, Parameter, + runtime_args, AddressableEntityHash, ApiError, CLType, EntityVersion, EntryPoint, + EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, }; const SUBCALL_NAME: &str = "add_gas"; @@ -47,7 +47,7 @@ pub extern "C" fn add_gas() { consume_at_least_gas_amount(amount as usize); } -fn store() -> (ContractHash, ContractVersion) { +fn store() -> (AddressableEntityHash, EntityVersion) { let entry_points = { let mut entry_points = EntryPoints::new(); let entry_point = EntryPoint::new( @@ -55,7 +55,7 @@ fn store() -> (ContractHash, ContractVersion) { vec![Parameter::new(ARG_GAS_AMOUNT, CLType::I32)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/auction-bidding/src/main.rs b/smart_contracts/contracts/test/auction-bidding/src/main.rs index 8778d53cd5..5bfd014264 100644 --- a/smart_contracts/contracts/test/auction-bidding/src/main.rs +++ b/smart_contracts/contracts/test/auction-bidding/src/main.rs @@ -12,7 +12,8 @@ use casper_contract::{ }; use casper_types::{ - account::AccountHash, runtime_args, system::auction, ApiError, ContractHash, PublicKey, U512, + account::AccountHash, runtime_args, system::auction, AddressableEntityHash, ApiError, + PublicKey, U512, }; const ARG_AMOUNT: &str = "amount"; @@ -47,7 +48,7 @@ fn bond() { call_bond(auction_contract_hash, public_key, amount); } -fn call_bond(auction: ContractHash, public_key: PublicKey, bond_amount: U512) { +fn call_bond(auction: AddressableEntityHash, public_key: PublicKey, bond_amount: U512) { let args = runtime_args! { auction::ARG_PUBLIC_KEY => public_key, auction::ARG_DELEGATION_RATE => DELEGATION_RATE, diff --git a/smart_contracts/contracts/test/contract-context/src/main.rs b/smart_contracts/contracts/test/contract-context/src/main.rs index 6a63fb90a6..6672ddda04 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::CONTRACT_INITIAL_VERSION, - runtime_args, CLType, ContractHash, ContractPackageHash, ContractVersion, Key, + package::ENTITY_INITIAL_VERSION, + runtime_args, AddressableEntityHash, CLType, EntityVersion, Key, PackageHash, }; const PACKAGE_HASH_KEY: &str = "package_hash_key"; @@ -42,12 +42,12 @@ pub extern "C" fn contract_code_test() { pub extern "C" fn session_code_caller_as_session() { let contract_package_hash = runtime::get_key(PACKAGE_HASH_KEY) .expect("should have contract package key") - .into_hash() + .into_entity_addr() .unwrap_or_revert(); runtime::call_versioned_contract::<()>( contract_package_hash.into(), - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), SESSION_CODE, runtime_args! {}, ); @@ -63,14 +63,14 @@ pub extern "C" fn add_new_key() { pub extern "C" fn add_new_key_as_session() { let contract_package_hash = runtime::get_key(PACKAGE_HASH_KEY) .expect("should have package hash") - .into_hash() + .into_entity_addr() .unwrap_or_revert() .into(); assert!(runtime::get_key(NEW_KEY).is_none()); runtime::call_versioned_contract::<()>( contract_package_hash, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), "add_new_key", runtime_args! {}, ); @@ -80,10 +80,10 @@ pub extern "C" fn add_new_key_as_session() { #[no_mangle] pub extern "C" fn session_code_caller_as_contract() { let contract_package_key: Key = runtime::get_named_arg(PACKAGE_HASH_KEY); - let contract_package_hash = contract_package_key.into_hash().unwrap_or_revert().into(); + let contract_package_hash = contract_package_key.into_package_hash().unwrap_or_revert(); runtime::call_versioned_contract::<()>( contract_package_hash, - Some(CONTRACT_INITIAL_VERSION), + Some(ENTITY_INITIAL_VERSION), SESSION_CODE, runtime_args! {}, ); @@ -91,63 +91,29 @@ pub extern "C" fn session_code_caller_as_contract() { fn create_entrypoints_1() -> EntryPoints { let mut entry_points = EntryPoints::new(); - let session_code_test = EntryPoint::new( - SESSION_CODE.to_string(), - Vec::new(), - CLType::I32, - EntryPointAccess::Public, - EntryPointType::Session, - ); - entry_points.add_entry_point(session_code_test); let contract_code_test = EntryPoint::new( CONTRACT_CODE.to_string(), Vec::new(), CLType::I32, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(contract_code_test); - let session_code_caller_as_session = EntryPoint::new( - "session_code_caller_as_session".to_string(), - Vec::new(), - CLType::I32, - EntryPointAccess::Public, - EntryPointType::Session, - ); - entry_points.add_entry_point(session_code_caller_as_session); - let session_code_caller_as_contract = EntryPoint::new( "session_code_caller_as_contract".to_string(), Vec::new(), CLType::I32, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(session_code_caller_as_contract); - let add_new_key = EntryPoint::new( - "add_new_key".to_string(), - Vec::new(), - CLType::I32, - EntryPointAccess::Public, - EntryPointType::Session, - ); - entry_points.add_entry_point(add_new_key); - let add_new_key_as_session = EntryPoint::new( - "add_new_key_as_session".to_string(), - Vec::new(), - CLType::I32, - EntryPointAccess::Public, - EntryPointType::Session, - ); - entry_points.add_entry_point(add_new_key_as_session); - entry_points } -fn install_version_1(package_hash: ContractPackageHash) -> (ContractHash, ContractVersion) { +fn install_version_1(package_hash: PackageHash) -> (AddressableEntityHash, EntityVersion) { let contract_named_keys = { let contract_variable = storage::new_uref(0); @@ -169,5 +135,5 @@ pub extern "C" fn call() { runtime::put_key(PACKAGE_ACCESS_KEY, access_uref.into()); let (contract_hash, contract_version) = install_version_1(contract_package_hash); runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into()); - runtime::put_key(CONTRACT_HASH_KEY, Key::Hash(contract_hash.value())); + runtime::put_key(CONTRACT_HASH_KEY, Key::contract_entity_key(contract_hash)); } diff --git a/smart_contracts/contracts/test/contract-funds-call/src/main.rs b/smart_contracts/contracts/test/contract-funds-call/src/main.rs index a0ca8bb71e..a3381160bb 100644 --- a/smart_contracts/contracts/test/contract-funds-call/src/main.rs +++ b/smart_contracts/contracts/test/contract-funds-call/src/main.rs @@ -8,14 +8,14 @@ use casper_contract::{ unwrap_or_revert::UnwrapOrRevert, }; -use casper_types::{ContractHash, Key, RuntimeArgs, URef, U512}; +use casper_types::{AddressableEntityHash, Key, RuntimeArgs, URef, U512}; const GET_PAYMENT_PURSE_NAME: &str = "get_payment_purse"; const HASH_KEY_NAME: &str = "contract_own_funds_hash"; const ARG_AMOUNT: &str = "amount"; fn get_payment_purse() -> URef { - let contract_hash = get_contract_hash_name(); + let contract_hash = get_entity_hash_name(); runtime::call_contract( contract_hash, GET_PAYMENT_PURSE_NAME, @@ -23,10 +23,10 @@ fn get_payment_purse() -> URef { ) } -fn get_contract_hash_name() -> ContractHash { +fn get_entity_hash_name() -> AddressableEntityHash { runtime::get_key(HASH_KEY_NAME) - .and_then(Key::into_hash) - .map(ContractHash::new) + .and_then(Key::into_entity_addr) + .map(AddressableEntityHash::new) .unwrap_or_revert() } diff --git a/smart_contracts/contracts/test/contract-funds/src/main.rs b/smart_contracts/contracts/test/contract-funds/src/main.rs index 4292d4408e..619754b464 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(faucet_entrypoint); @@ -67,5 +67,5 @@ pub extern "C" fn call() { Some(ACCESS_KEY_NAME.to_string()), ); runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into()); - runtime::put_key(HASH_KEY_NAME, contract_hash.into()); + runtime::put_key(HASH_KEY_NAME, Key::contract_entity_key(contract_hash)); } diff --git a/smart_contracts/contracts/test/counter-factory/src/main.rs b/smart_contracts/contracts/test/counter-factory/src/main.rs index dc14dea846..d5c4632710 100644 --- a/smart_contracts/contracts/test/counter-factory/src/main.rs +++ b/smart_contracts/contracts/test/counter-factory/src/main.rs @@ -12,7 +12,7 @@ use casper_contract::{ use casper_types::{ addressable_entity::{EntryPoint, EntryPoints, NamedKeys, Parameters}, bytesrepr::FromBytes, - ApiError, CLType, CLTyped, EntryPointAccess, EntryPointType, URef, U512, + ApiError, CLType, CLTyped, EntryPointAccess, EntryPointType, Key, URef, U512, }; const ACCESS_KEY_NAME: &str = "factory_access"; @@ -85,7 +85,7 @@ fn installer(name: String, initial_value: U512) { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -108,7 +108,7 @@ fn installer(name: String, initial_value: U512) { ); runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into()); - runtime::put_key(&name, contract_hash.into()); + runtime::put_key(&name, Key::contract_entity_key(contract_hash)); } #[no_mangle] @@ -121,7 +121,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Install, + EntryPointType::Factory, ); entry_points.add_entry_point(entry_point); let entry_point: EntryPoint = EntryPoint::new( @@ -129,7 +129,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Install, + EntryPointType::Factory, ); entry_points.add_entry_point(entry_point); let entry_point: EntryPoint = EntryPoint::new( @@ -137,7 +137,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Template, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); let entry_point: EntryPoint = EntryPoint::new( @@ -145,7 +145,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Template, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -160,5 +160,5 @@ pub extern "C" fn call() { ); runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into()); - runtime::put_key(HASH_KEY_NAME, contract_hash.into()); + runtime::put_key(HASH_KEY_NAME, Key::contract_entity_key(contract_hash)); } diff --git a/smart_contracts/contracts/test/deserialize-error/src/main.rs b/smart_contracts/contracts/test/deserialize-error/src/main.rs index e45c49be40..cc11598980 100644 --- a/smart_contracts/contracts/test/deserialize-error/src/main.rs +++ b/smart_contracts/contracts/test/deserialize-error/src/main.rs @@ -7,7 +7,7 @@ use alloc::{vec, vec::Vec}; use casper_contract::{self, contract_api::storage, unwrap_or_revert::UnwrapOrRevert}; use casper_types::{ - addressable_entity::Parameters, api_error, bytesrepr::ToBytes, CLType, ContractHash, + addressable_entity::Parameters, api_error, bytesrepr::ToBytes, AddressableEntityHash, CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, RuntimeArgs, }; @@ -43,7 +43,7 @@ mod malicious_ffi { // This is half-baked runtime::call_contract with changed `extra_urefs` // parameter with a desired payload that's supposed to bring the node down. pub fn my_call_contract( - contract_hash: ContractHash, + contract_hash: AddressableEntityHash, _entry_point_name: &str, runtime_args: RuntimeArgs, ) -> usize { @@ -81,7 +81,7 @@ pub extern "C" fn call() { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/dictionary-call/src/bin/main.rs b/smart_contracts/contracts/test/dictionary-call/src/bin/main.rs index 73d349ec10..daa22eb9b5 100644 --- a/smart_contracts/contracts/test/dictionary-call/src/bin/main.rs +++ b/smart_contracts/contracts/test/dictionary-call/src/bin/main.rs @@ -10,7 +10,7 @@ use casper_contract::{ contract_api::{runtime, storage}, unwrap_or_revert::UnwrapOrRevert, }; -use casper_types::{bytesrepr::FromBytes, CLTyped, ContractHash, RuntimeArgs, URef}; +use casper_types::{bytesrepr::FromBytes, AddressableEntityHash, CLTyped, RuntimeArgs, URef}; use dictionary::{ DEFAULT_DICTIONARY_NAME, DEFAULT_DICTIONARY_VALUE, INVALID_GET_DICTIONARY_ITEM_KEY_ENTRYPOINT, @@ -24,7 +24,7 @@ use dictionary_call::{ /// Calls dictionary contract by hash as passed by `ARG_CONTRACT_HASH` argument and returns a /// single value. fn call_dictionary_contract(entrypoint: &str) -> T { - let contract_hash: ContractHash = runtime::get_named_arg(ARG_CONTRACT_HASH); + let contract_hash: AddressableEntityHash = runtime::get_named_arg(ARG_CONTRACT_HASH); runtime::call_contract(contract_hash, entrypoint, RuntimeArgs::default()) } @@ -58,7 +58,7 @@ pub extern "C" fn call() { storage::dictionary_put(uref, NEW_DICTIONARY_ITEM_KEY, value); } Operation::InvalidPutDictionaryItemKey => { - let contract_hash: ContractHash = runtime::get_named_arg(ARG_CONTRACT_HASH); + let contract_hash: AddressableEntityHash = runtime::get_named_arg(ARG_CONTRACT_HASH); runtime::call_contract( contract_hash, INVALID_PUT_DICTIONARY_ITEM_KEY_ENTRYPOINT, @@ -66,7 +66,7 @@ pub extern "C" fn call() { ) } Operation::InvalidGetDictionaryItemKey => { - let contract_hash: ContractHash = runtime::get_named_arg(ARG_CONTRACT_HASH); + let contract_hash: AddressableEntityHash = runtime::get_named_arg(ARG_CONTRACT_HASH); runtime::call_contract( contract_hash, INVALID_GET_DICTIONARY_ITEM_KEY_ENTRYPOINT, diff --git a/smart_contracts/contracts/test/dictionary/src/lib.rs b/smart_contracts/contracts/test/dictionary/src/lib.rs index 0fba39c4cc..cff0e6f8b2 100644 --- a/smart_contracts/contracts/test/dictionary/src/lib.rs +++ b/smart_contracts/contracts/test/dictionary/src/lib.rs @@ -13,8 +13,9 @@ use casper_contract::{ unwrap_or_revert::UnwrapOrRevert, }; use casper_types::{ - addressable_entity::NamedKeys, api_error, bytesrepr::ToBytes, AccessRights, ApiError, CLType, - CLValue, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, URef, + addressable_entity::NamedKeys, api_error, bytesrepr::ToBytes, package::PackageKindTag, + AccessRights, ApiError, CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointType, + EntryPoints, Key, URef, }; pub const DICTIONARY_NAME: &str = "local"; @@ -180,35 +181,35 @@ pub fn delegate() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); entry_points.add_entry_point(EntryPoint::new( SHARE_RO_ENTRYPOINT, Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); entry_points.add_entry_point(EntryPoint::new( SHARE_W_ENTRYPOINT, Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); entry_points.add_entry_point(EntryPoint::new( INVALID_PUT_DICTIONARY_ITEM_KEY_ENTRYPOINT, Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); entry_points.add_entry_point(EntryPoint::new( INVALID_GET_DICTIONARY_ITEM_KEY_ENTRYPOINT, Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); let named_keys = { let uref = { @@ -230,11 +231,14 @@ pub fn delegate() { named_keys }; - let (contract_hash, _version) = storage::new_contract( + let (entity_hash, _version) = storage::new_contract( entry_points, Some(named_keys), Some(CONTRACT_PACKAGE_HASH_NAME.to_string()), None, ); - runtime::put_key(CONTRACT_HASH_NAME, contract_hash.into()); + + let entity_key = Key::addressable_entity_key(PackageKindTag::SmartContract, entity_hash); + + runtime::put_key(CONTRACT_HASH_NAME, entity_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 47970e0000..98a775116e 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::ContractVersion, runtime_args, ContractPackageHash}; +use casper_types::{package::EntityVersion, runtime_args, PackageHash}; const ENTRY_FUNCTION_NAME: &str = "delegate"; const PURSE_NAME_ARG_NAME: &str = "purse_name"; @@ -16,9 +16,9 @@ const ARG_VERSION: &str = "version"; #[no_mangle] pub extern "C" fn call() { - let contract_package_hash: ContractPackageHash = runtime::get_named_arg(ARG_CONTRACT_PACKAGE); + let contract_package_hash: PackageHash = runtime::get_named_arg(ARG_CONTRACT_PACKAGE); let new_purse_name: String = runtime::get_named_arg(ARG_NEW_PURSE_NAME); - let version_number: ContractVersion = runtime::get_named_arg(ARG_VERSION); + let version_number: EntityVersion = runtime::get_named_arg(ARG_VERSION); let contract_version = Some(version_number); let runtime_args = runtime_args! { 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 8691bd5f88..fbf5ba30f3 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 @@ -13,7 +13,8 @@ use core::convert::TryInto; use casper_types::{ addressable_entity::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys}, - CLType, CLTyped, ContractPackageHash, Key, Parameter, URef, + package::PackageKindTag, + CLType, CLTyped, Key, PackageHash, Parameter, URef, }; const ENTRY_FUNCTION_NAME: &str = "delegate"; @@ -39,19 +40,18 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_PURSE_NAME, String::cl_type())], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(delegate); entry_points }; - let do_nothing_package_hash: ContractPackageHash = - runtime::get_key(DO_NOTHING_PACKAGE_HASH_KEY_NAME) - .unwrap_or_revert() - .into_hash() - .unwrap() - .into(); + let do_nothing_package_hash: PackageHash = runtime::get_key(DO_NOTHING_PACKAGE_HASH_KEY_NAME) + .unwrap_or_revert() + .into_package_addr() + .unwrap_or_revert() + .into(); let _do_nothing_uref: URef = runtime::get_key(DO_NOTHING_ACCESS_KEY_NAME) .unwrap_or_revert() @@ -61,5 +61,8 @@ pub extern "C" fn call() { let (contract_hash, contract_version) = storage::add_contract_version(do_nothing_package_hash, entry_points, NamedKeys::new()); runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into()); - runtime::put_key("end of upgrade", contract_hash.into()); + runtime::put_key( + "end of upgrade", + Key::addressable_entity_key(PackageKindTag::SmartContract, contract_hash), + ); } 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 83099c33f9..333a4fc5f9 100644 --- a/smart_contracts/contracts/test/do-nothing-stored/src/main.rs +++ b/smart_contracts/contracts/test/do-nothing-stored/src/main.rs @@ -4,7 +4,7 @@ use casper_contract::contract_api::{runtime, storage}; use casper_types::{ addressable_entity::{EntryPoint, EntryPoints, Parameters}, - CLType, EntryPointAccess, EntryPointType, + CLType, EntryPointAccess, EntryPointType, Key, }; const ENTRY_FUNCTION_NAME: &str = "delegate"; @@ -27,7 +27,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); entry_points @@ -41,5 +41,5 @@ pub extern "C" fn call() { ); runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into()); - runtime::put_key(HASH_KEY_NAME, contract_hash.into()); + runtime::put_key(HASH_KEY_NAME, Key::contract_entity_key(contract_hash)); } 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 dc6785c5af..6ecfea074a 100644 --- a/smart_contracts/contracts/test/ee-1071-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-1071-regression/src/main.rs @@ -3,8 +3,8 @@ use casper_contract::contract_api::{runtime, storage}; use casper_types::{ - addressable_entity::Parameters, CLType, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, + addressable_entity::Parameters, package::PackageKindTag, CLType, EntryPoint, EntryPointAccess, + EntryPointType, EntryPoints, Key, }; const CONTRACT_HASH_NAME: &str = "contract"; @@ -26,7 +26,7 @@ pub extern "C" fn call() { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -35,5 +35,8 @@ pub extern "C" fn call() { }; let (contract_hash, _contract_version) = storage::new_contract(entry_points, None, None, None); - runtime::put_key(CONTRACT_HASH_NAME, contract_hash.into()); + runtime::put_key( + CONTRACT_HASH_NAME, + Key::addressable_entity_key(PackageKindTag::SmartContract, contract_hash), + ); } 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 f8ad69bc87..00ec03bfdb 100644 --- a/smart_contracts/contracts/test/ee-1129-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-1129-regression/src/main.rs @@ -8,7 +8,7 @@ use alloc::string::ToString; use casper_contract::contract_api::{runtime, storage, system}; use casper_types::{ addressable_entity::Parameters, CLType, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, + EntryPoints, Key, }; const ENTRY_POINT_NAME: &str = "create_purse"; @@ -33,7 +33,7 @@ pub extern "C" fn call() { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -48,5 +48,5 @@ pub extern "C" fn call() { Some(ACCESS_KEY.to_string()), ); - runtime::put_key(CONTRACT_KEY, contract_hash.into()); + runtime::put_key(CONTRACT_KEY, Key::contract_entity_key(contract_hash)); } 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 92031aa6bd..ffef252c0a 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::Session, + EntryPointType::AddressableEntity, ); let add_bid_contract_entry_point = EntryPoint::new( METHOD_ADD_BID_CONTRACT_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let withdraw_bid_session_entry_point = EntryPoint::new( METHOD_WITHDRAW_BID_SESSION_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::AddressableEntity, ); let withdraw_bid_contract_entry_point = EntryPoint::new( METHOD_WITHDRAW_BID_CONTRACT_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let delegate_session_entry_point = EntryPoint::new( METHOD_DELEGATE_SESSION_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::AddressableEntity, ); let delegate_contract_entry_point = EntryPoint::new( METHOD_DELEGATE_CONTRACT_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let undelegate_session_entry_point = EntryPoint::new( METHOD_UNDELEGATE_SESSION_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::AddressableEntity, ); let undelegate_contract_entry_point = EntryPoint::new( METHOD_UNDELEGATE_CONTRACT_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let activate_bid_session_entry_point = EntryPoint::new( METHOD_ACTIVATE_BID_SESSION_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::AddressableEntity, ); let activate_bid_contract_entry_point = EntryPoint::new( METHOD_ACTIVATE_BID_CONTRACT_NAME.to_string(), vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); 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-call/src/main.rs b/smart_contracts/contracts/test/ee-401-regression-call/src/main.rs index 1179b5bb54..98419a6ccf 100644 --- a/smart_contracts/contracts/test/ee-401-regression-call/src/main.rs +++ b/smart_contracts/contracts/test/ee-401-regression-call/src/main.rs @@ -9,13 +9,13 @@ use casper_contract::{ contract_api::{runtime, storage}, unwrap_or_revert::UnwrapOrRevert, }; -use casper_types::{ApiError, ContractHash, RuntimeArgs, URef}; +use casper_types::{AddressableEntityHash, ApiError, RuntimeArgs, URef}; #[no_mangle] pub extern "C" fn call() { - let contract_hash: ContractHash = runtime::get_key("hello_ext") + let contract_hash: AddressableEntityHash = runtime::get_key("hello_ext") .unwrap_or_revert_with(ApiError::GetKey) - .into_hash() + .into_entity_addr() .unwrap_or_revert() .into(); 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 06873bfb5a..7c2c83a7a1 100644 --- a/smart_contracts/contracts/test/ee-401-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-401-regression/src/main.rs @@ -11,7 +11,7 @@ use casper_contract::{ }; use casper_types::{ addressable_entity::Parameters, CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, URef, + EntryPoints, Key, URef, }; const HELLO_EXT: &str = "hello_ext"; @@ -35,7 +35,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::URef, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -45,5 +45,5 @@ pub extern "C" fn call() { let (contract_hash, contract_version) = storage::new_contract(entry_points, None, None, None); runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into()); - runtime::put_key(HELLO_EXT, contract_hash.into()); + runtime::put_key(HELLO_EXT, Key::contract_entity_key(contract_hash)); } 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 578578956d..ec05b7df08 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::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); 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 d6be533ead..07d76ca0d4 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 @@ -9,7 +9,7 @@ use casper_contract::{ }; use casper_types::{ addressable_entity::Parameters, AccessRights, CLType, CLValue, EntryPoint, EntryPointAccess, - EntryPointType, EntryPoints, URef, + EntryPointType, EntryPoints, Key, URef, }; const DATA: &str = "data"; @@ -34,7 +34,7 @@ pub extern "C" fn call() { Parameters::default(), CLType::URef, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -43,5 +43,5 @@ pub extern "C" fn call() { }; let (contract_hash, contract_version) = storage::new_contract(entry_points, None, None, None); runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into()); - runtime::put_key(CONTRACT_NAME, contract_hash.into()); + runtime::put_key(CONTRACT_NAME, Key::contract_entity_key(contract_hash)); } diff --git a/smart_contracts/contracts/test/ee-572-regression-escalate/src/main.rs b/smart_contracts/contracts/test/ee-572-regression-escalate/src/main.rs index ba446a9dd4..12e70860be 100644 --- a/smart_contracts/contracts/test/ee-572-regression-escalate/src/main.rs +++ b/smart_contracts/contracts/test/ee-572-regression-escalate/src/main.rs @@ -2,14 +2,14 @@ #![no_main] use casper_contract::contract_api::{runtime, storage}; -use casper_types::{AccessRights, ContractHash, RuntimeArgs, URef}; +use casper_types::{AccessRights, AddressableEntityHash, RuntimeArgs, URef}; const REPLACEMENT_DATA: &str = "bawitdaba"; const ARG_CONTRACT_HASH: &str = "contract_hash"; #[no_mangle] pub extern "C" fn call() { - let contract_hash: ContractHash = runtime::get_named_arg(ARG_CONTRACT_HASH); + let contract_hash: AddressableEntityHash = runtime::get_named_arg(ARG_CONTRACT_HASH); let reference: URef = runtime::call_contract(contract_hash, "create", RuntimeArgs::default()); let forged_reference: URef = URef::new(reference.addr(), AccessRights::READ_ADD_WRITE); diff --git a/smart_contracts/contracts/test/ee-597-regression/src/main.rs b/smart_contracts/contracts/test/ee-597-regression/src/main.rs index e76d174d7b..c561d38a86 100644 --- a/smart_contracts/contracts/test/ee-597-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-597-regression/src/main.rs @@ -7,12 +7,12 @@ use casper_contract::contract_api::{runtime, system}; use casper_types::{ runtime_args, system::auction::{self, DelegationRate}, - ContractHash, PublicKey, SecretKey, U512, + AddressableEntityHash, PublicKey, SecretKey, U512, }; const DELEGATION_RATE: DelegationRate = 42; -fn bond(contract_hash: ContractHash, bond_amount: U512) { +fn bond(contract_hash: AddressableEntityHash, bond_amount: U512) { let valid_secret_key = SecretKey::ed25519_from_bytes([42; SecretKey::ED25519_LENGTH]).unwrap(); let valid_public_key = PublicKey::from(&valid_secret_key); diff --git a/smart_contracts/contracts/test/ee-598-regression/src/main.rs b/smart_contracts/contracts/test/ee-598-regression/src/main.rs index 46410f1db2..f176d8dbbf 100644 --- a/smart_contracts/contracts/test/ee-598-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-598-regression/src/main.rs @@ -3,13 +3,13 @@ use auction::DelegationRate; use casper_contract::contract_api::{runtime, system}; -use casper_types::{runtime_args, system::auction, ContractHash, PublicKey, U512}; +use casper_types::{runtime_args, system::auction, AddressableEntityHash, PublicKey, U512}; const ARG_AMOUNT: &str = "amount"; const ARG_PUBLIC_KEY: &str = "public_key"; const DELEGATION_RATE: DelegationRate = 42; -fn add_bid(contract_hash: ContractHash, public_key: PublicKey, bond_amount: U512) { +fn add_bid(contract_hash: AddressableEntityHash, public_key: PublicKey, bond_amount: U512) { let runtime_args = runtime_args! { auction::ARG_PUBLIC_KEY => public_key, auction::ARG_DELEGATION_RATE => DELEGATION_RATE, @@ -18,7 +18,11 @@ fn add_bid(contract_hash: ContractHash, public_key: PublicKey, bond_amount: U512 runtime::call_contract::(contract_hash, auction::METHOD_ADD_BID, runtime_args); } -fn withdraw_bid(contract_hash: ContractHash, public_key: PublicKey, unbond_amount: U512) -> U512 { +fn withdraw_bid( + contract_hash: AddressableEntityHash, + public_key: PublicKey, + unbond_amount: U512, +) -> U512 { let args = runtime_args! { auction::ARG_AMOUNT => unbond_amount, auction::ARG_PUBLIC_KEY => public_key, 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 06ab04845d..13e3003071 100644 --- a/smart_contracts/contracts/test/ee-599-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-599-regression/src/main.rs @@ -13,8 +13,8 @@ use casper_contract::{ use casper_types::{ account::AccountHash, addressable_entity::{NamedKeys, Parameters}, - ApiError, CLType, ContractHash, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, - RuntimeArgs, URef, U512, + AddressableEntityHash, ApiError, CLType, EntryPoint, EntryPointAccess, EntryPointType, + EntryPoints, Key, RuntimeArgs, URef, U512, }; const DONATION_AMOUNT: u64 = 1; @@ -132,7 +132,7 @@ fn delegate() -> Result<(), ApiError> { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point_1); @@ -142,7 +142,7 @@ fn delegate() -> Result<(), ApiError> { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point_2); @@ -152,7 +152,7 @@ fn delegate() -> Result<(), ApiError> { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point_3); @@ -162,7 +162,7 @@ fn delegate() -> Result<(), ApiError> { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point_4); @@ -172,7 +172,7 @@ fn delegate() -> Result<(), ApiError> { let (contract_hash, _contract_version) = storage::new_contract(entry_points, Some(known_keys), None, None); - runtime::put_key(TRANSFER_FUNDS_KEY, contract_hash.into()); + runtime::put_key(TRANSFER_FUNDS_KEY, Key::contract_entity_key(contract_hash)); // For easy access in outside world here `donation` purse is also attached // to the account runtime::put_key(DONATION_PURSE_COPY, purse.into()); @@ -180,7 +180,7 @@ fn delegate() -> Result<(), ApiError> { METHOD_CALL => { // This comes from outside i.e. after deploying the contract, this key is queried, // and then passed into the call - let contract_key: ContractHash = runtime::get_named_arg(ARG_CONTRACTKEY); + let contract_key: AddressableEntityHash = runtime::get_named_arg(ARG_CONTRACTKEY); // This is a method that's gets forwarded into the sub contract let subcontract_method: String = runtime::get_named_arg(ARG_SUBCONTRACTMETHODFWD); 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 adaa7d19df..ff5a19aa3b 100644 --- a/smart_contracts/contracts/test/ee-771-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-771-regression/src/main.rs @@ -8,8 +8,8 @@ use alloc::string::ToString; use casper_contract::contract_api::{runtime, storage}; use casper_types::{ addressable_entity::{NamedKeys, Parameters}, - CLType, ContractHash, ContractVersion, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, RuntimeArgs, + AddressableEntityHash, CLType, EntityVersion, EntryPoint, EntryPointAccess, EntryPointType, + EntryPoints, Key, RuntimeArgs, }; const ENTRY_POINT_NAME: &str = "contract_ext"; @@ -21,7 +21,10 @@ pub extern "C" fn contract_ext() { Some(contract_key) => { // Calls a stored contract if exists. runtime::call_contract( - contract_key.into_hash().expect("should be a hash").into(), + contract_key + .into_entity_addr() + .expect("should be a hash") + .into(), "contract_ext", RuntimeArgs::default(), ) @@ -36,7 +39,7 @@ pub extern "C" fn contract_ext() { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -48,7 +51,7 @@ pub extern "C" fn contract_ext() { } } -fn store(named_keys: NamedKeys) -> (ContractHash, ContractVersion) { +fn store(named_keys: NamedKeys) -> (AddressableEntityHash, EntityVersion) { // extern "C" fn call(named_keys: NamedKeys) { let entry_points = { let mut entry_points = EntryPoints::new(); @@ -58,7 +61,7 @@ fn store(named_keys: NamedKeys) -> (ContractHash, ContractVersion) { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -68,23 +71,29 @@ fn store(named_keys: NamedKeys) -> (ContractHash, ContractVersion) { storage::new_contract(entry_points, Some(named_keys), None, None) } -fn install() -> ContractHash { +fn install() -> AddressableEntityHash { let (contract_hash, _contract_version) = store(NamedKeys::new()); let mut keys = NamedKeys::new(); - keys.insert(CONTRACT_KEY.to_string(), contract_hash.into()); + keys.insert( + CONTRACT_KEY.to_string(), + Key::contract_entity_key(contract_hash), + ); let (contract_hash, _contract_version) = store(keys); let mut keys_2 = NamedKeys::new(); - keys_2.insert(CONTRACT_KEY.to_string(), contract_hash.into()); + keys_2.insert( + CONTRACT_KEY.to_string(), + Key::contract_entity_key(contract_hash), + ); let (contract_hash, _contract_version) = store(keys_2); - runtime::put_key(CONTRACT_KEY, contract_hash.into()); + runtime::put_key(CONTRACT_KEY, Key::contract_entity_key(contract_hash)); contract_hash } -fn dispatch(contract_hash: ContractHash) { +fn dispatch(contract_hash: AddressableEntityHash) { runtime::call_contract(contract_hash, "contract_ext", RuntimeArgs::default()) } diff --git a/smart_contracts/contracts/test/expensive-calculation/src/main.rs b/smart_contracts/contracts/test/expensive-calculation/src/main.rs index 343e8216d5..0c3d6ed1b6 100644 --- a/smart_contracts/contracts/test/expensive-calculation/src/main.rs +++ b/smart_contracts/contracts/test/expensive-calculation/src/main.rs @@ -6,7 +6,7 @@ extern crate alloc; use casper_contract::contract_api::{runtime, storage}; use casper_types::{ addressable_entity::Parameters, CLType, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, + EntryPoints, Key, }; const ENTRY_FUNCTION_NAME: &str = "calculate"; @@ -34,7 +34,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); entry_points @@ -45,5 +45,8 @@ pub extern "C" fn call() { "contract_version", storage::new_uref(contract_version).into(), ); - runtime::put_key("expensive-calculation", contract_hash.into()); + runtime::put_key( + "expensive-calculation", + Key::contract_entity_key(contract_hash), + ); } diff --git a/smart_contracts/contracts/test/finalize-payment/src/main.rs b/smart_contracts/contracts/test/finalize-payment/src/main.rs index fba8e5496f..fd418158e9 100644 --- a/smart_contracts/contracts/test/finalize-payment/src/main.rs +++ b/smart_contracts/contracts/test/finalize-payment/src/main.rs @@ -9,7 +9,7 @@ use casper_contract::{ contract_api::{account, runtime, system}, unwrap_or_revert::UnwrapOrRevert, }; -use casper_types::{account::AccountHash, runtime_args, ContractHash, URef, U512}; +use casper_types::{account::AccountHash, runtime_args, AddressableEntityHash, URef, U512}; pub const ARG_AMOUNT: &str = "amount"; pub const ARG_AMOUNT_SPENT: &str = "amount_spent"; @@ -18,7 +18,7 @@ pub const ARG_PURSE: &str = "purse"; pub const ARG_ACCOUNT_KEY: &str = "account"; pub const ARG_PURSE_NAME: &str = "purse_name"; -fn set_refund_purse(contract_hash: ContractHash, purse: URef) { +fn set_refund_purse(contract_hash: AddressableEntityHash, purse: URef) { runtime::call_contract( contract_hash, "set_refund_purse", @@ -28,17 +28,21 @@ fn set_refund_purse(contract_hash: ContractHash, purse: URef) { ) } -fn get_payment_purse(contract_hash: ContractHash) -> URef { +fn get_payment_purse(contract_hash: AddressableEntityHash) -> URef { runtime::call_contract(contract_hash, "get_payment_purse", runtime_args! {}) } -fn submit_payment(contract_hash: ContractHash, amount: U512) { +fn submit_payment(contract_hash: AddressableEntityHash, amount: U512) { let payment_purse = get_payment_purse(contract_hash); let main_purse = account::get_main_purse(); system::transfer_from_purse_to_purse(main_purse, payment_purse, amount, None).unwrap_or_revert() } -fn finalize_payment(contract_hash: ContractHash, amount_spent: U512, account: AccountHash) { +fn finalize_payment( + contract_hash: AddressableEntityHash, + amount_spent: U512, + account: AccountHash, +) { runtime::call_contract( contract_hash, "finalize_payment", diff --git a/smart_contracts/contracts/test/get-call-stack-recursive-subcall/src/lib.rs b/smart_contracts/contracts/test/get-call-stack-recursive-subcall/src/lib.rs index 28a45de040..e57afc1303 100644 --- a/smart_contracts/contracts/test/get-call-stack-recursive-subcall/src/lib.rs +++ b/smart_contracts/contracts/test/get-call-stack-recursive-subcall/src/lib.rs @@ -11,8 +11,8 @@ use casper_contract::{ use casper_types::{ bytesrepr, bytesrepr::{Error, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, - runtime_args, ApiError, CLType, CLTyped, ContractHash, ContractPackageHash, EntryPointType, - Key, Phase, RuntimeArgs, Tagged, URef, U512, + runtime_args, AddressableEntityHash, ApiError, CLType, CLTyped, EntryPointType, Key, + PackageHash, Phase, RuntimeArgs, Tagged, URef, U512, }; pub const CONTRACT_PACKAGE_NAME: &str = "forwarder"; @@ -35,8 +35,8 @@ enum ContractAddressTag { #[derive(Debug, Copy, Clone)] pub enum ContractAddress { - ContractHash(ContractHash), - ContractPackageHash(ContractPackageHash), + ContractHash(AddressableEntityHash), + ContractPackageHash(PackageHash), } impl Tagged for ContractAddress { @@ -81,12 +81,11 @@ impl FromBytes for ContractAddress { let (tag, remainder): (u8, &[u8]) = FromBytes::from_bytes(bytes)?; match tag { tag if tag == ContractAddressTag::ContractHash as u8 => { - let (contract_hash, remainder) = ContractHash::from_bytes(remainder)?; + let (contract_hash, remainder) = AddressableEntityHash::from_bytes(remainder)?; Ok((ContractAddress::ContractHash(contract_hash), remainder)) } tag if tag == ContractAddressTag::ContractPackageHash as u8 => { - let (contract_package_hash, remainder) = - ContractPackageHash::from_bytes(remainder)?; + let (contract_package_hash, remainder) = PackageHash::from_bytes(remainder)?; Ok(( ContractAddress::ContractPackageHash(contract_package_hash), remainder, 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 2fc62c751b..c72716b939 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 @@ -6,7 +6,10 @@ extern crate alloc; use alloc::{boxed::Box, string::ToString, vec}; use casper_contract::contract_api::{runtime, storage}; -use casper_types::{CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Parameter}; +use casper_types::{ + package::PackageKindTag, CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, + Key, Parameter, +}; use get_call_stack_recursive_subcall::{ ARG_CALLS, ARG_CURRENT_DEPTH, CONTRACT_NAME, CONTRACT_PACKAGE_NAME, @@ -35,7 +38,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let forwarder_session_entry_point = EntryPoint::new( METHOD_FORWARDER_SESSION_NAME.to_string(), @@ -59,5 +62,8 @@ pub extern "C" fn call() { Some(PACKAGE_ACCESS_KEY_NAME.to_string()), ); - runtime::put_key(CONTRACT_NAME, contract_hash.into()); + runtime::put_key( + CONTRACT_NAME, + Key::addressable_entity_key(PackageKindTag::SmartContract, contract_hash), + ); } 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 137672a33e..f11ee8d4f0 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); entry_points diff --git a/smart_contracts/contracts/test/gh-1470-regression-call/src/bin/main.rs b/smart_contracts/contracts/test/gh-1470-regression-call/src/bin/main.rs index f73ba20377..5913c26050 100644 --- a/smart_contracts/contracts/test/gh-1470-regression-call/src/bin/main.rs +++ b/smart_contracts/contracts/test/gh-1470-regression-call/src/bin/main.rs @@ -8,7 +8,7 @@ use core::str::FromStr; use gh_1470_regression_call::{ARG_CONTRACT_HASH, ARG_CONTRACT_PACKAGE_HASH, ARG_TEST_METHOD}; use casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert}; -use casper_types::{runtime_args, ContractHash, ContractPackageHash}; +use casper_types::{runtime_args, AddressableEntityHash, PackageHash}; use gh_1470_regression_call::TestMethod; @@ -56,7 +56,7 @@ pub extern "C" fn call() { match test_method { TestMethod::CallDoNothing => { - let contract_hash: ContractHash = runtime::get_named_arg(ARG_CONTRACT_HASH); + let contract_hash: AddressableEntityHash = runtime::get_named_arg(ARG_CONTRACT_HASH); runtime::call_contract::<()>( contract_hash, @@ -65,7 +65,7 @@ pub extern "C" fn call() { ); } TestMethod::CallVersionedDoNothing => { - let contract_package_hash: ContractPackageHash = + let contract_package_hash: PackageHash = runtime::get_named_arg(ARG_CONTRACT_PACKAGE_HASH); runtime::call_versioned_contract::<()>( @@ -76,7 +76,7 @@ pub extern "C" fn call() { ); } TestMethod::CallDoNothingNoArgs => { - let contract_hash: ContractHash = runtime::get_named_arg(ARG_CONTRACT_HASH); + let contract_hash: AddressableEntityHash = runtime::get_named_arg(ARG_CONTRACT_HASH); runtime::call_contract::<()>( contract_hash, @@ -85,7 +85,7 @@ pub extern "C" fn call() { ); } TestMethod::CallVersionedDoNothingNoArgs => { - let contract_package_hash: ContractPackageHash = + let contract_package_hash: PackageHash = runtime::get_named_arg(ARG_CONTRACT_PACKAGE_HASH); runtime::call_versioned_contract::<()>( @@ -96,7 +96,7 @@ pub extern "C" fn call() { ); } TestMethod::CallDoNothingTypeMismatch => { - let contract_hash: ContractHash = runtime::get_named_arg(ARG_CONTRACT_HASH); + let contract_hash: AddressableEntityHash = runtime::get_named_arg(ARG_CONTRACT_HASH); runtime::call_contract::<()>( contract_hash, @@ -106,7 +106,7 @@ pub extern "C" fn call() { } TestMethod::CallVersionedDoNothingTypeMismatch => { - let contract_package_hash: ContractPackageHash = + let contract_package_hash: PackageHash = runtime::get_named_arg(ARG_CONTRACT_PACKAGE_HASH); runtime::call_versioned_contract::<()>( @@ -117,7 +117,7 @@ pub extern "C" fn call() { ); } TestMethod::CallDoNothingNoOptionals => { - let contract_hash: ContractHash = runtime::get_named_arg(ARG_CONTRACT_HASH); + let contract_hash: AddressableEntityHash = runtime::get_named_arg(ARG_CONTRACT_HASH); runtime::call_contract::<()>( contract_hash, @@ -126,7 +126,7 @@ pub extern "C" fn call() { ); } TestMethod::CallVersionedDoNothingNoOptionals => { - let contract_package_hash: ContractPackageHash = + let contract_package_hash: PackageHash = runtime::get_named_arg(ARG_CONTRACT_PACKAGE_HASH); runtime::call_versioned_contract::<()>( @@ -137,7 +137,7 @@ pub extern "C" fn call() { ); } TestMethod::CallDoNothingExtra => { - let contract_hash: ContractHash = runtime::get_named_arg(ARG_CONTRACT_HASH); + let contract_hash: AddressableEntityHash = runtime::get_named_arg(ARG_CONTRACT_HASH); runtime::call_contract::<()>( contract_hash, @@ -146,7 +146,7 @@ pub extern "C" fn call() { ); } TestMethod::CallVersionedDoNothingExtra => { - let contract_package_hash: ContractPackageHash = + let contract_package_hash: PackageHash = runtime::get_named_arg(ARG_CONTRACT_PACKAGE_HASH); runtime::call_versioned_contract::<()>( @@ -157,7 +157,7 @@ pub extern "C" fn call() { ); } TestMethod::CallDoNothingOptionalTypeMismatch => { - let contract_hash: ContractHash = runtime::get_named_arg(ARG_CONTRACT_HASH); + let contract_hash: AddressableEntityHash = runtime::get_named_arg(ARG_CONTRACT_HASH); runtime::call_contract::<()>( contract_hash, @@ -166,7 +166,7 @@ pub extern "C" fn call() { ); } TestMethod::CallVersionedDoNothingOptionalTypeMismatch => { - let contract_package_hash: ContractPackageHash = + let contract_package_hash: PackageHash = runtime::get_named_arg(ARG_CONTRACT_PACKAGE_HASH); runtime::call_versioned_contract::<()>( 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 3cb80e8bb7..8c86ab6e3e 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 @@ -7,12 +7,12 @@ extern crate alloc; use casper_contract::contract_api::{runtime, storage}; use casper_types::{ - addressable_entity::NamedKeys, CLType, CLTyped, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Group, Parameter, + addressable_entity::NamedKeys, package::PackageKindTag, CLType, CLTyped, EntryPoint, + EntryPointAccess, EntryPointType, EntryPoints, Group, Key, Parameter, }; use gh_1470_regression::{ Arg1Type, Arg2Type, Arg3Type, Arg4Type, Arg5Type, ARG1, ARG2, ARG3, ARG4, ARG5, - CONTRACT_HASH_NAME, CONTRACT_PACKAGE_HASH_NAME, GROUP_LABEL, GROUP_UREF_NAME, + CONTRACT_HASH_NAME, GROUP_LABEL, GROUP_UREF_NAME, PACKAGE_HASH_NAME, RESTRICTED_DO_NOTHING_ENTRYPOINT, RESTRICTED_WITH_EXTRA_ARG_ENTRYPOINT, }; @@ -60,7 +60,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Groups(vec![Group::new(GROUP_LABEL)]), - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); entry_points.add_entry_point(EntryPoint::new( @@ -72,7 +72,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Groups(vec![Group::new(GROUP_LABEL)]), - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); let named_keys = NamedKeys::new(); @@ -80,6 +80,9 @@ pub extern "C" fn call() { let (contract_hash, _) = storage::add_contract_version(contract_package_hash, entry_points, named_keys); - runtime::put_key(CONTRACT_HASH_NAME, contract_hash.into()); - runtime::put_key(CONTRACT_PACKAGE_HASH_NAME, contract_package_hash.into()); + runtime::put_key( + CONTRACT_HASH_NAME, + Key::addressable_entity_key(PackageKindTag::SmartContract, contract_hash), + ); + runtime::put_key(PACKAGE_HASH_NAME, contract_package_hash.into()); } diff --git a/smart_contracts/contracts/test/gh-1470-regression/src/lib.rs b/smart_contracts/contracts/test/gh-1470-regression/src/lib.rs index 56489c7263..e449a51e6a 100644 --- a/smart_contracts/contracts/test/gh-1470-regression/src/lib.rs +++ b/smart_contracts/contracts/test/gh-1470-regression/src/lib.rs @@ -9,7 +9,7 @@ use casper_types::U512; pub const GROUP_LABEL: &str = "group_label"; pub const GROUP_UREF_NAME: &str = "group_uref"; pub const CONTRACT_HASH_NAME: &str = "contract_hash"; -pub const CONTRACT_PACKAGE_HASH_NAME: &str = "contract_package_hash"; +pub const PACKAGE_HASH_NAME: &str = "contract_package_hash"; pub const RESTRICTED_DO_NOTHING_ENTRYPOINT: &str = "restricted_do_nothing_contract"; pub const RESTRICTED_WITH_EXTRA_ARG_ENTRYPOINT: &str = "restricted_with_extra_arg"; 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 09484b731a..0088c17b67 100644 --- a/smart_contracts/contracts/test/gh-1688-regression/src/main.rs +++ b/smart_contracts/contracts/test/gh-1688-regression/src/main.rs @@ -7,7 +7,7 @@ use alloc::string::ToString; use casper_contract::contract_api::{runtime, storage}; use casper_types::{ addressable_entity::Parameters, CLType, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, + EntryPoints, Key, }; const METHOD_PUT_KEY: &str = "put_key"; @@ -30,7 +30,7 @@ fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); let (contract_hash, _version) = storage::new_contract( @@ -39,5 +39,5 @@ fn call() { Some(CONTRACT_PACKAGE_KEY.to_string()), None, ); - runtime::put_key(CONTRACT_HASH_KEY, contract_hash.into()); + runtime::put_key(CONTRACT_HASH_KEY, Key::contract_entity_key(contract_hash)); } diff --git a/smart_contracts/contracts/test/gh-2280-regression-call/src/main.rs b/smart_contracts/contracts/test/gh-2280-regression-call/src/main.rs index 33fb71c587..7ef404deb8 100644 --- a/smart_contracts/contracts/test/gh-2280-regression-call/src/main.rs +++ b/smart_contracts/contracts/test/gh-2280-regression-call/src/main.rs @@ -3,13 +3,13 @@ use casper_contract::contract_api::runtime; -use casper_types::{account::AccountHash, runtime_args, ContractHash}; +use casper_types::{account::AccountHash, runtime_args, AddressableEntityHash}; const FAUCET_NAME: &str = "faucet"; const ARG_TARGET: &str = "target"; const ARG_CONTRACT_HASH: &str = "contract_hash"; -fn call_faucet(contract_hash: ContractHash, target: AccountHash) { +fn call_faucet(contract_hash: AddressableEntityHash, target: AccountHash) { let faucet_args = runtime_args! { ARG_TARGET => target, }; @@ -18,7 +18,7 @@ fn call_faucet(contract_hash: ContractHash, target: AccountHash) { #[no_mangle] pub extern "C" fn call() { - let contract_hash: ContractHash = runtime::get_named_arg(ARG_CONTRACT_HASH); + let contract_hash: AddressableEntityHash = runtime::get_named_arg(ARG_CONTRACT_HASH); let target: AccountHash = runtime::get_named_arg(ARG_TARGET); call_faucet(contract_hash, target); 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 7e84e40936..b2300d38e6 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(faucet_entrypoint); @@ -87,5 +87,5 @@ pub extern "C" fn call() { Some(ACCESS_KEY_NAME.to_string()), ); runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into()); - runtime::put_key(HASH_KEY_NAME, contract_hash.into()); + runtime::put_key(HASH_KEY_NAME, Key::contract_entity_key(contract_hash)); } diff --git a/smart_contracts/contracts/test/gh-3097-regression-call/src/main.rs b/smart_contracts/contracts/test/gh-3097-regression-call/src/main.rs index 32332565eb..df6cc72a30 100644 --- a/smart_contracts/contracts/test/gh-3097-regression-call/src/main.rs +++ b/smart_contracts/contracts/test/gh-3097-regression-call/src/main.rs @@ -5,7 +5,7 @@ extern crate alloc; use alloc::string::String; use casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert}; -use casper_types::{ApiError, ContractHash, ContractPackageHash, RuntimeArgs}; +use casper_types::{AddressableEntityHash, ApiError, PackageHash, RuntimeArgs}; const CONTRACT_PACKAGE_HASH_KEY: &str = "contract_package_hash"; const DO_SOMETHING_ENTRYPOINT: &str = "do_something"; @@ -23,9 +23,9 @@ pub extern "C" fn call() { let contract_hash = runtime::get_key(&contract_hash_key_name) .ok_or(ApiError::MissingKey) .unwrap_or_revert() - .into_hash() + .into_entity_addr() .ok_or(ApiError::UnexpectedKeyVariant) - .map(ContractHash::new) + .map(AddressableEntityHash::new) .unwrap_or_revert(); runtime::call_contract::<()>( contract_hash, @@ -36,9 +36,9 @@ pub extern "C" fn call() { let contract_package_hash = runtime::get_key(CONTRACT_PACKAGE_HASH_KEY) .ok_or(ApiError::MissingKey) .unwrap_or_revert() - .into_hash() + .into_package_addr() .ok_or(ApiError::UnexpectedKeyVariant) - .map(ContractPackageHash::new) + .map(PackageHash::new) .unwrap_or_revert(); let contract_version = runtime::get_named_arg(ARG_CONTRACT_VERSION); 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 b8ce248b61..dc2e48552b 100644 --- a/smart_contracts/contracts/test/gh-3097-regression/src/main.rs +++ b/smart_contracts/contracts/test/gh-3097-regression/src/main.rs @@ -9,7 +9,7 @@ use casper_contract::{ }; use casper_types::{ addressable_entity::{NamedKeys, Parameters}, - CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, + CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, }; const CONTRACT_PACKAGE_HASH_KEY: &str = "contract_package_hash"; @@ -31,7 +31,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(do_something); @@ -52,8 +52,14 @@ pub extern "C" fn call() { runtime::put_key(CONTRACT_PACKAGE_HASH_KEY, contract_package_hash.into()); - runtime::put_key(DISABLED_CONTRACT_HASH_KEY, disabled_contract_hash.into()); - runtime::put_key(ENABLED_CONTRACT_HASH_KEY, enabled_contract_hash.into()); + runtime::put_key( + DISABLED_CONTRACT_HASH_KEY, + Key::contract_entity_key(disabled_contract_hash), + ); + runtime::put_key( + ENABLED_CONTRACT_HASH_KEY, + Key::contract_entity_key(enabled_contract_hash), + ); storage::disable_contract_version(contract_package_hash, disabled_contract_hash) .unwrap_or_revert(); diff --git a/smart_contracts/contracts/test/groups/src/main.rs b/smart_contracts/contracts/test/groups/src/main.rs index c04441e96b..0d9937ec87 100644 --- a/smart_contracts/contracts/test/groups/src/main.rs +++ b/smart_contracts/contracts/test/groups/src/main.rs @@ -12,10 +12,10 @@ use casper_contract::{ }; use casper_types::{ addressable_entity::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys}, - package::CONTRACT_INITIAL_VERSION, + package::ENTITY_INITIAL_VERSION, runtime_args, system::{handle_payment, standard_payment}, - CLType, CLTyped, ContractPackageHash, Key, Parameter, RuntimeArgs, URef, U512, + CLType, CLTyped, Key, PackageHash, Parameter, RuntimeArgs, URef, U512, }; const PACKAGE_HASH_KEY: &str = "package_hash_key"; @@ -40,8 +40,8 @@ pub extern "C" fn restricted_contract() {} #[no_mangle] pub extern "C" fn restricted_session_caller() { let package_hash: Key = runtime::get_named_arg(ARG_PACKAGE_HASH); - let contract_version = Some(CONTRACT_INITIAL_VERSION); - let contract_package_hash = package_hash.into_hash().unwrap_or_revert().into(); + let contract_version = Some(ENTITY_INITIAL_VERSION); + let contract_package_hash = package_hash.into_entity_addr().unwrap_or_revert().into(); runtime::call_versioned_contract( contract_package_hash, contract_version, @@ -52,8 +52,8 @@ pub extern "C" fn restricted_session_caller() { fn contract_caller() { let package_hash: Key = runtime::get_named_arg(ARG_PACKAGE_HASH); - let contract_version = Some(CONTRACT_INITIAL_VERSION); - let contract_package_hash = package_hash.into_hash().unwrap_or_revert().into(); + let contract_version = Some(ENTITY_INITIAL_VERSION); + let contract_package_hash = package_hash.into_package_hash().unwrap_or_revert(); let runtime_args = runtime_args! {}; runtime::call_versioned_contract( contract_package_hash, @@ -104,7 +104,7 @@ pub extern "C" fn call_restricted_entry_points() { uncallable_contract(); } -fn create_group(package_hash: ContractPackageHash) -> URef { +fn create_group(package_hash: PackageHash) -> URef { let new_uref_1 = storage::new_uref(()); runtime::put_key("saved_uref", new_uref_1.into()); @@ -134,7 +134,7 @@ fn create_entry_points_1() -> EntryPoints { Vec::new(), CLType::I32, EntryPointAccess::groups(&["Group 1"]), - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(restricted_contract); @@ -152,7 +152,7 @@ fn create_entry_points_1() -> EntryPoints { Vec::new(), CLType::I32, EntryPointAccess::groups(&["Group 1"]), - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(restricted_contract); @@ -165,7 +165,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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(unrestricted_contract_caller); @@ -238,7 +238,7 @@ fn create_entry_points_1() -> EntryPoints { entry_points } -fn install_version_1(contract_package_hash: ContractPackageHash, restricted_uref: URef) { +fn install_version_1(contract_package_hash: PackageHash, restricted_uref: URef) { let contract_named_keys = { let contract_variable = storage::new_uref(0); 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 0402dcba57..f080c28682 100644 --- a/smart_contracts/contracts/test/host-function-costs/src/main.rs +++ b/smart_contracts/contracts/test/host-function-costs/src/main.rs @@ -219,7 +219,7 @@ pub extern "C" fn account_function() { #[no_mangle] pub extern "C" fn calls_do_nothing_level1() { let contract_package_hash = runtime::get_key(HASH_KEY_NAME) - .and_then(Key::into_hash) + .and_then(Key::into_package_addr) .expect("should have key") .into(); runtime::call_versioned_contract( @@ -233,7 +233,7 @@ pub extern "C" fn calls_do_nothing_level1() { #[no_mangle] pub extern "C" fn calls_do_nothing_level2() { let contract_package_hash = runtime::get_key(HASH_KEY_NAME) - .and_then(Key::into_hash) + .and_then(Key::into_package_addr) .expect("should have key") .into(); runtime::call_versioned_contract( @@ -246,7 +246,7 @@ pub extern "C" fn calls_do_nothing_level2() { fn measure_arg_size(bytes: usize) { let contract_package_hash = runtime::get_key(HASH_KEY_NAME) - .and_then(Key::into_hash) + .and_then(Key::into_package_addr) .expect("should have key") .into(); @@ -281,7 +281,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -290,7 +290,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -299,7 +299,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -316,7 +316,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -333,7 +333,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -359,7 +359,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -368,7 +368,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -377,7 +377,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -386,7 +386,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -402,5 +402,5 @@ pub extern "C" fn call() { let (contract_hash, _version) = storage::add_contract_version(contract_package_hash, entry_points, named_keys); - runtime::put_key(CONTRACT_KEY_NAME, contract_hash.into()); + runtime::put_key(CONTRACT_KEY_NAME, Key::contract_entity_key(contract_hash)); } diff --git a/smart_contracts/contracts/test/manage-groups/src/main.rs b/smart_contracts/contracts/test/manage-groups/src/main.rs index 10574567ca..050ac7233b 100644 --- a/smart_contracts/contracts/test/manage-groups/src/main.rs +++ b/smart_contracts/contracts/test/manage-groups/src/main.rs @@ -22,7 +22,7 @@ use casper_types::{ addressable_entity::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys}, api_error, bytesrepr::{self, ToBytes}, - ApiError, CLType, ContractPackageHash, Group, Key, Package, Parameter, URef, + ApiError, CLType, Group, Key, Package, PackageHash, Parameter, URef, }; const PACKAGE_HASH_KEY: &str = "package_hash_key"; @@ -39,8 +39,8 @@ const UREF_INDICES_ARG: &str = "uref_indices"; #[no_mangle] pub extern "C" fn create_group() { - let package_hash_key: ContractPackageHash = runtime::get_key(PACKAGE_HASH_KEY) - .and_then(Key::into_hash) + let package_hash_key: PackageHash = runtime::get_key(PACKAGE_HASH_KEY) + .and_then(Key::into_package_addr) .unwrap_or_revert() .into(); let group_name: String = runtime::get_named_arg(GROUP_NAME_ARG); @@ -59,8 +59,8 @@ pub extern "C" fn create_group() { #[no_mangle] pub extern "C" fn remove_group() { - let package_hash_key: ContractPackageHash = runtime::get_key(PACKAGE_HASH_KEY) - .and_then(Key::into_hash) + let package_hash_key: PackageHash = runtime::get_key(PACKAGE_HASH_KEY) + .and_then(Key::into_package_addr) .unwrap_or_revert() .into(); let group_name: String = runtime::get_named_arg(GROUP_NAME_ARG); @@ -69,8 +69,8 @@ pub extern "C" fn remove_group() { #[no_mangle] pub extern "C" fn extend_group_urefs() { - let package_hash_key: ContractPackageHash = runtime::get_key(PACKAGE_HASH_KEY) - .and_then(Key::into_hash) + let package_hash_key: PackageHash = runtime::get_key(PACKAGE_HASH_KEY) + .and_then(Key::into_package_addr) .unwrap_or_revert() .into(); let group_name: String = runtime::get_named_arg(GROUP_NAME_ARG); @@ -95,7 +95,7 @@ fn read_host_buffer_into(dest: &mut [u8]) -> Result { Ok(unsafe { bytes_written.assume_init() }) } -fn read_contract_package(package_hash: ContractPackageHash) -> Result, ApiError> { +fn read_contract_package(package_hash: PackageHash) -> Result, ApiError> { let key = Key::from(package_hash); let (key_ptr, key_size, _bytes) = { let bytes = key.into_bytes().unwrap_or_revert(); @@ -130,8 +130,8 @@ fn read_contract_package(package_hash: ContractPackageHash) -> Result EntryPoints { entry_points } -fn install_version_1(package_hash: ContractPackageHash) { +fn install_version_1(package_hash: PackageHash) { let contract_named_keys = NamedKeys::new(); let entry_points = create_entry_points_1(); 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 c73852245f..0504b20e4f 100644 --- a/smart_contracts/contracts/test/measure-gas-subcall/src/main.rs +++ b/smart_contracts/contracts/test/measure-gas-subcall/src/main.rs @@ -10,8 +10,8 @@ use casper_contract::{ unwrap_or_revert::UnwrapOrRevert, }; use casper_types::{ - addressable_entity::Parameters, ApiError, CLType, CLValue, ContractHash, ContractVersion, - EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Phase, RuntimeArgs, + addressable_entity::Parameters, AddressableEntityHash, ApiError, CLType, CLValue, + EntityVersion, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Phase, RuntimeArgs, }; const ARG_TARGET: &str = "target_contract"; @@ -35,7 +35,7 @@ pub extern "C" fn noop_ext() { runtime::ret(CLValue::from_t(()).unwrap_or_revert()) } -fn store() -> (ContractHash, ContractVersion) { +fn store() -> (AddressableEntityHash, EntityVersion) { let entry_points = { let mut entry_points = EntryPoints::new(); @@ -44,7 +44,7 @@ fn store() -> (ContractHash, ContractVersion) { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point_1); @@ -54,7 +54,7 @@ fn store() -> (ContractHash, ContractVersion) { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); 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 26d26dc79a..709299d949 100644 --- a/smart_contracts/contracts/test/multisig-authorization/src/main.rs +++ b/smart_contracts/contracts/test/multisig-authorization/src/main.rs @@ -7,7 +7,7 @@ use alloc::{collections::BTreeSet, string::ToString}; use casper_contract::contract_api::{runtime, storage}; use casper_types::{ account::AccountHash, addressable_entity::Parameters, ApiError, CLType, EntryPoint, - EntryPointAccess, EntryPointType, EntryPoints, + EntryPointAccess, EntryPointType, EntryPoints, Key, }; const ROLE_A_KEYS: [AccountHash; 3] = [ @@ -77,7 +77,7 @@ pub extern "C" fn call() { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let entrypoint_b = EntryPoint::new( @@ -85,7 +85,7 @@ pub extern "C" fn call() { Parameters::default(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entrypoint_a); @@ -101,5 +101,5 @@ pub extern "C" fn call() { Some(ACCESS_KEY.to_string()), ); - runtime::put_key(CONTRACT_KEY, contract_hash.into()); + runtime::put_key(CONTRACT_KEY, Key::contract_entity_key(contract_hash)); } diff --git a/smart_contracts/contracts/test/named-keys-stored-call/src/main.rs b/smart_contracts/contracts/test/named-keys-stored-call/src/main.rs index b72a6c8c9d..bbaccf58e5 100644 --- a/smart_contracts/contracts/test/named-keys-stored-call/src/main.rs +++ b/smart_contracts/contracts/test/named-keys-stored-call/src/main.rs @@ -6,15 +6,14 @@ extern crate alloc; use alloc::string::String; use casper_contract::{self, contract_api::runtime, unwrap_or_revert::UnwrapOrRevert}; -use casper_types::{ContractHash, Key, RuntimeArgs}; +use casper_types::{Key, RuntimeArgs}; const CONTRACT_HASH_NAME: &str = "contract_stored"; #[no_mangle] pub extern "C" fn call() { let contract_hash = runtime::get_key(CONTRACT_HASH_NAME) - .and_then(Key::into_hash) - .map(ContractHash::new) + .and_then(Key::into_entity_hash) .unwrap_or_revert(); let entry_point: String = runtime::get_named_arg("entry_point"); 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 22d3f3e8e1..fd618a073b 100644 --- a/smart_contracts/contracts/test/named-keys-stored/src/main.rs +++ b/smart_contracts/contracts/test/named-keys-stored/src/main.rs @@ -12,8 +12,9 @@ use casper_contract::{ }; use casper_types::{ addressable_entity::{NamedKeys, Parameters}, - ApiError, CLType, ContractPackageHash, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Key, RuntimeArgs, + package::PackageKindTag, + ApiError, CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, PackageHash, + RuntimeArgs, }; const ENTRY_POINT_CONTRACT: &str = "named_keys_contract"; @@ -99,13 +100,13 @@ pub extern "C" fn named_keys_session() { #[no_mangle] pub extern "C" fn named_keys_contract_to_contract() { - let contract_hash = runtime::get_key(CONTRACT_PACKAGE_HASH_NAME) - .and_then(Key::into_hash) - .map(ContractPackageHash::new) + let package_hash = runtime::get_key(CONTRACT_PACKAGE_HASH_NAME) + .and_then(Key::into_package_addr) + .map(PackageHash::new) .unwrap_or_revert(); runtime::call_versioned_contract::<()>( - contract_hash, + package_hash, None, ENTRY_POINT_CONTRACT, RuntimeArgs::default(), @@ -114,13 +115,13 @@ pub extern "C" fn named_keys_contract_to_contract() { #[no_mangle] pub extern "C" fn named_keys_session_to_session() { - let contract_hash = runtime::get_key(CONTRACT_PACKAGE_HASH_NAME) - .and_then(Key::into_hash) - .map(ContractPackageHash::new) + let package_hash = runtime::get_key(CONTRACT_PACKAGE_HASH_NAME) + .and_then(Key::into_package_addr) + .map(PackageHash::new) .unwrap_or_revert(); runtime::call_versioned_contract::<()>( - contract_hash, + package_hash, None, ENTRY_POINT_SESSION, RuntimeArgs::default(), @@ -142,7 +143,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(contract_entrypoint); let session_entrypoint = EntryPoint::new( @@ -150,7 +151,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(session_entrypoint); let contract_to_contract_entrypoint = EntryPoint::new( @@ -158,7 +159,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(contract_to_contract_entrypoint); let contract_to_contract_entrypoint = EntryPoint::new( @@ -166,7 +167,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(contract_to_contract_entrypoint); entry_points @@ -193,5 +194,8 @@ pub extern "C" fn call() { runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into()); runtime::put_key(CONTRACT_PACKAGE_HASH_NAME, contract_package_hash.into()); - runtime::put_key(CONTRACT_HASH_NAME, contract_hash.into()); + runtime::put_key( + CONTRACT_HASH_NAME, + Key::addressable_entity_key(PackageKindTag::SmartContract, contract_hash), + ); } diff --git a/smart_contracts/contracts/test/ordered-transforms/src/main.rs b/smart_contracts/contracts/test/ordered-transforms/src/main.rs index ae5eb1b187..b1f4f9b428 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::Contract, + EntryPointType::AddressableEntity, )); let n: u32 = runtime::get_named_arg("n"); @@ -37,7 +37,10 @@ pub extern "C" fn call() { let (contract_hash, _contract_version) = storage::new_locked_contract(entry_points, Some(named_keys), None, None); - runtime::put_key("ordered-transforms-contract-hash", contract_hash.into()); + runtime::put_key( + "ordered-transforms-contract-hash", + Key::contract_entity_key(contract_hash), + ); } #[no_mangle] diff --git a/smart_contracts/contracts/test/purse-holder-stored-caller/src/main.rs b/smart_contracts/contracts/test/purse-holder-stored-caller/src/main.rs index 2074d774a0..02a8ea1516 100644 --- a/smart_contracts/contracts/test/purse-holder-stored-caller/src/main.rs +++ b/smart_contracts/contracts/test/purse-holder-stored-caller/src/main.rs @@ -6,7 +6,7 @@ extern crate alloc; use alloc::string::String; use casper_contract::contract_api::{runtime, storage}; -use casper_types::{runtime_args, ContractHash, RuntimeArgs}; +use casper_types::{runtime_args, AddressableEntityHash, RuntimeArgs}; const METHOD_VERSION: &str = "version"; const HASH_KEY_NAME: &str = "purse_holder"; @@ -19,14 +19,14 @@ pub extern "C" fn call() { match entry_point_name.as_str() { METHOD_VERSION => { - let contract_hash: ContractHash = runtime::get_named_arg(HASH_KEY_NAME); + let contract_hash: AddressableEntityHash = runtime::get_named_arg(HASH_KEY_NAME); let version: String = runtime::call_contract(contract_hash, &entry_point_name, RuntimeArgs::default()); let version_key = storage::new_uref(version).into(); runtime::put_key(METHOD_VERSION, version_key); } _ => { - let contract_hash: ContractHash = runtime::get_named_arg(HASH_KEY_NAME); + let contract_hash: AddressableEntityHash = runtime::get_named_arg(HASH_KEY_NAME); let purse_name: String = runtime::get_named_arg(PURSE_NAME); let args = runtime_args! { 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 f544852451..0403f6f838 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 @@ -11,8 +11,8 @@ use casper_contract::{ unwrap_or_revert::UnwrapOrRevert, }; use casper_types::{ - addressable_entity::NamedKeys, CLType, CLValue, ContractPackageHash, EntryPoint, - EntryPointAccess, EntryPointType, EntryPoints, Parameter, URef, + addressable_entity::NamedKeys, CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointType, + EntryPoints, Key, PackageHash, Parameter, URef, }; pub const METHOD_ADD: &str = "add"; @@ -50,7 +50,7 @@ pub extern "C" fn version() { #[no_mangle] pub extern "C" fn call() { - let contract_package: ContractPackageHash = runtime::get_named_arg(ARG_CONTRACT_PACKAGE); + let contract_package: PackageHash = runtime::get_named_arg(ARG_CONTRACT_PACKAGE); let _access_key: URef = runtime::get_key(ACCESS_KEY_NAME) .expect("should have access key") .into_uref() @@ -63,7 +63,7 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_PURSE_NAME, CLType::String)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(remove); entry_points @@ -88,7 +88,10 @@ pub extern "C" fn call() { // this should overwrite the previous contract obj with the new contract obj at the same uref let (new_contract_hash, new_contract_version) = storage::add_contract_version(contract_package, entry_points, NamedKeys::new()); - runtime::put_key(PURSE_HOLDER_STORED_CONTRACT_NAME, new_contract_hash.into()); + runtime::put_key( + PURSE_HOLDER_STORED_CONTRACT_NAME, + Key::contract_entity_key(new_contract_hash), + ); runtime::put_key( CONTRACT_VERSION, storage::new_uref(new_contract_version).into(), 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 f47ca96558..1a31f5c587 100644 --- a/smart_contracts/contracts/test/purse-holder-stored/src/main.rs +++ b/smart_contracts/contracts/test/purse-holder-stored/src/main.rs @@ -12,7 +12,8 @@ use casper_contract::{ unwrap_or_revert::UnwrapOrRevert, }; use casper_types::{ - CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Parameter, + package::PackageKindTag, CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointType, + EntryPoints, Key, Parameter, }; pub const METHOD_ADD: &str = "add"; @@ -52,7 +53,7 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_PURSE, CLType::String)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(add); let version = EntryPoint::new( @@ -60,7 +61,7 @@ pub extern "C" fn call() { vec![], CLType::String, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(version); entry_points @@ -83,6 +84,9 @@ pub extern "C" fn call() { }; runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into()); - runtime::put_key(PURSE_HOLDER_STORED_CONTRACT_NAME, contract_hash.into()); + runtime::put_key( + PURSE_HOLDER_STORED_CONTRACT_NAME, + Key::addressable_entity_key(PackageKindTag::SmartContract, contract_hash), + ); runtime::put_key(ENTRY_POINT_VERSION, storage::new_uref(VERSION).into()); } diff --git a/smart_contracts/contracts/test/refund-purse/src/main.rs b/smart_contracts/contracts/test/refund-purse/src/main.rs index e7b2561f86..46ae8dd844 100644 --- a/smart_contracts/contracts/test/refund-purse/src/main.rs +++ b/smart_contracts/contracts/test/refund-purse/src/main.rs @@ -9,7 +9,7 @@ use casper_contract::{ contract_api::{account, runtime, system}, unwrap_or_revert::UnwrapOrRevert, }; -use casper_types::{runtime_args, ApiError, ContractHash, URef, U512}; +use casper_types::{runtime_args, AddressableEntityHash, ApiError, URef, U512}; #[repr(u16)] enum Error { @@ -27,7 +27,7 @@ const GET_PAYMENT_PURSE: &str = "get_payment_purse"; const ARG_PURSE_NAME_1: &str = "purse_name_1"; const ARG_PURSE_NAME_2: &str = "purse_name_2"; -fn set_refund_purse(contract_hash: ContractHash, p: &URef) { +fn set_refund_purse(contract_hash: AddressableEntityHash, p: &URef) { runtime::call_contract( contract_hash, SET_REFUND_PURSE, @@ -37,15 +37,15 @@ fn set_refund_purse(contract_hash: ContractHash, p: &URef) { ) } -fn get_refund_purse(handle_payment: ContractHash) -> Option { +fn get_refund_purse(handle_payment: AddressableEntityHash) -> Option { runtime::call_contract(handle_payment, GET_REFUND_PURSE, runtime_args! {}) } -fn get_payment_purse(handle_payment: ContractHash) -> URef { +fn get_payment_purse(handle_payment: AddressableEntityHash) -> URef { runtime::call_contract(handle_payment, GET_PAYMENT_PURSE, runtime_args! {}) } -fn submit_payment(handle_payment: ContractHash, amount: U512) { +fn submit_payment(handle_payment: AddressableEntityHash, amount: U512) { let payment_purse = get_payment_purse(handle_payment); let main_purse = account::get_main_purse(); system::transfer_from_purse_to_purse(main_purse, payment_purse, amount, None).unwrap_or_revert() diff --git a/smart_contracts/contracts/test/regression-20210707/src/main.rs b/smart_contracts/contracts/test/regression-20210707/src/main.rs index 9547411377..ec83bf33a3 100644 --- a/smart_contracts/contracts/test/regression-20210707/src/main.rs +++ b/smart_contracts/contracts/test/regression-20210707/src/main.rs @@ -15,7 +15,7 @@ use casper_types::{ addressable_entity::NamedKeys, runtime_args, system::{handle_payment, mint}, - AccessRights, CLType, CLTyped, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, + AccessRights, CLType, CLTyped, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, RuntimeArgs, URef, U512, }; @@ -149,7 +149,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let send_to_purse = EntryPoint::new( METHOD_SEND_TO_PURSE, @@ -160,7 +160,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let hardcoded_src = EntryPoint::new( METHOD_HARDCODED_PURSE_SRC, @@ -170,7 +170,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let stored_payment = EntryPoint::new( METHOD_STORED_PAYMENT, @@ -180,14 +180,14 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let hardcoded_payment = EntryPoint::new( METHOD_HARDCODED_PAYMENT, vec![Parameter::new(ARG_AMOUNT, CLType::U512)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(send_to_account); @@ -214,5 +214,5 @@ pub extern "C" fn call() { Some(PACKAGE_HASH_NAME.to_string()), Some(ACCESS_UREF_NAME.to_string()), ); - runtime::put_key(CONTRACT_HASH_NAME, contract_hash.into()); + runtime::put_key(CONTRACT_HASH_NAME, Key::contract_entity_key(contract_hash)); } diff --git a/smart_contracts/contracts/test/regression-20210831/src/main.rs b/smart_contracts/contracts/test/regression-20210831/src/main.rs index 9e3b008bfe..6d13b3eb11 100644 --- a/smart_contracts/contracts/test/regression-20210831/src/main.rs +++ b/smart_contracts/contracts/test/regression-20210831/src/main.rs @@ -15,8 +15,8 @@ use casper_types::{ bytesrepr::FromBytes, runtime_args, system::auction::{self, DelegationRate}, - CLType, CLTyped, CLValue, ContractPackageHash, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Key, Parameter, PublicKey, RuntimeArgs, U512, + CLType, CLTyped, CLValue, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, + PackageHash, Parameter, PublicKey, RuntimeArgs, U512, }; const METHOD_ADD_BID_PROXY_CALL_1: &str = "add_bid_proxy_call_1"; @@ -109,8 +109,8 @@ pub extern "C" fn withdraw_proxy_call_1() { fn forward_call_to_this(entry_point: &str, runtime_args: RuntimeArgs) -> T { let this = runtime::get_key(PACKAGE_HASH_NAME) - .and_then(Key::into_hash) - .map(ContractPackageHash::new) + .and_then(Key::into_package_addr) + .map(PackageHash::new) .unwrap_or_revert(); runtime::call_versioned_contract(this, None, entry_point, runtime_args) } @@ -182,7 +182,7 @@ pub extern "C" fn call() { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(add_bid_proxy_call); @@ -207,7 +207,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let withdraw_proxy_call = EntryPoint::new( @@ -218,7 +218,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let delegate_proxy_call = EntryPoint::new( @@ -230,7 +230,7 @@ pub extern "C" fn call() { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let delegate_proxy_call_1 = EntryPoint::new( @@ -242,7 +242,7 @@ pub extern "C" fn call() { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let undelegate_proxy_call = EntryPoint::new( @@ -254,7 +254,7 @@ pub extern "C" fn call() { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let undelegate_proxy_call_1 = EntryPoint::new( @@ -266,7 +266,7 @@ pub extern "C" fn call() { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); let activate_bid_proxy_call = EntryPoint::new( @@ -277,7 +277,7 @@ pub extern "C" fn call() { )], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(withdraw_proxy_call); @@ -312,5 +312,5 @@ pub extern "C" fn call() { let (contract_hash, _version) = storage::add_contract_version(contract_package_hash, entry_points, named_keys); - runtime::put_key(CONTRACT_HASH_NAME, contract_hash.into()); + runtime::put_key(CONTRACT_HASH_NAME, Key::contract_entity_key(contract_hash)); } diff --git a/smart_contracts/contracts/test/regression-20220204-call/src/main.rs b/smart_contracts/contracts/test/regression-20220204-call/src/main.rs index 1ed274a97e..ab23219d6e 100644 --- a/smart_contracts/contracts/test/regression-20220204-call/src/main.rs +++ b/smart_contracts/contracts/test/regression-20220204-call/src/main.rs @@ -9,7 +9,7 @@ use casper_contract::{ contract_api::{account, runtime}, unwrap_or_revert::UnwrapOrRevert, }; -use casper_types::{runtime_args, AccessRights, ContractHash}; +use casper_types::{runtime_args, AccessRights, AddressableEntityHash}; const ARG_PURSE: &str = "purse"; const CONTRACT_HASH_NAME: &str = "regression-contract-hash"; @@ -22,9 +22,10 @@ pub extern "C" fn call() { let entrypoint: String = runtime::get_named_arg(ARG_ENTRYPOINT); let contract_hash_key = runtime::get_key(CONTRACT_HASH_NAME).unwrap_or_revert(); + let contract_hash = contract_hash_key - .into_hash() - .map(ContractHash::new) + .into_entity_addr() + .map(AddressableEntityHash::new) .unwrap_or_revert(); let main_purse_modified = account::get_main_purse().with_access_rights(new_access_rights); diff --git a/smart_contracts/contracts/test/regression-20220204-nontrivial/src/main.rs b/smart_contracts/contracts/test/regression-20220204-nontrivial/src/main.rs index 195310c6be..8dc3db466f 100644 --- a/smart_contracts/contracts/test/regression-20220204-nontrivial/src/main.rs +++ b/smart_contracts/contracts/test/regression-20220204-nontrivial/src/main.rs @@ -12,7 +12,7 @@ use casper_contract::{ contract_api::{account, runtime}, unwrap_or_revert::UnwrapOrRevert, }; -use casper_types::{runtime_args, AccessRights, ContractHash, Key}; +use casper_types::{runtime_args, AccessRights, AddressableEntityHash, Key}; const ARG_PURSE: &str = "purse"; const CONTRACT_HASH_NAME: &str = "regression-contract-hash"; @@ -28,8 +28,8 @@ pub extern "C" fn call() { let contract_hash_key = runtime::get_key(CONTRACT_HASH_NAME).unwrap_or_revert(); let contract_hash = contract_hash_key - .into_hash() - .map(ContractHash::new) + .into_entity_addr() + .map(AddressableEntityHash::new) .unwrap_or_revert(); let main_purse_modified = account::get_main_purse().with_access_rights(new_access_rights); diff --git a/smart_contracts/contracts/test/regression-20220204/src/main.rs b/smart_contracts/contracts/test/regression-20220204/src/main.rs index 8e7668cf7e..8bc1704f98 100644 --- a/smart_contracts/contracts/test/regression-20220204/src/main.rs +++ b/smart_contracts/contracts/test/regression-20220204/src/main.rs @@ -10,15 +10,11 @@ use casper_contract::{ unwrap_or_revert::UnwrapOrRevert, }; use casper_types::{ - account::AccountHash, - addressable_entity::{NamedKeys, Parameters}, - CLType, CLTyped, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, - URef, U512, + account::AccountHash, addressable_entity::NamedKeys, CLType, CLTyped, EntryPoint, + EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, URef, U512, }; const TRANSFER_AS_CONTRACT: &str = "transfer_as_contract"; -const TRANSFER_AS_SESSION: &str = "transfer_as_session"; -const TRANSFER_MAIN_PURSE_AS_SESSION: &str = "transfer_main_purse_as_session"; const NONTRIVIAL_ARG_AS_CONTRACT: &str = "nontrivial_arg_as_contract"; const ARG_PURSE: &str = "purse"; const PURSE_KEY: &str = "purse"; @@ -38,15 +34,7 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_PURSE, URef::cl_type())], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, - )); - - entry_points.add_entry_point(EntryPoint::new( - TRANSFER_AS_SESSION, - vec![Parameter::new(ARG_PURSE, URef::cl_type())], - CLType::Unit, - EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::AddressableEntity, )); type NonTrivialArg = BTreeMap; @@ -56,23 +44,7 @@ pub extern "C" fn call() { vec![Parameter::new(ARG_PURSE, NonTrivialArg::cl_type())], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, - )); - - entry_points.add_entry_point(EntryPoint::new( - TRANSFER_MAIN_PURSE_AS_SESSION, - Parameters::new(), - CLType::Unit, - EntryPointAccess::Public, - EntryPointType::Session, - )); - - entry_points.add_entry_point(EntryPoint::new( - TRANSFER_MAIN_PURSE_AS_SESSION, - Parameters::new(), - CLType::Unit, - EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::AddressableEntity, )); let named_keys = { @@ -85,7 +57,7 @@ pub extern "C" fn call() { let (contract_hash, _contract_version) = storage::add_contract_version(contract_package_hash, entry_points, named_keys); - runtime::put_key(CONTRACT_HASH_NAME, contract_hash.into()); + runtime::put_key(CONTRACT_HASH_NAME, Key::contract_entity_key(contract_hash)); } #[no_mangle] diff --git a/smart_contracts/contracts/test/regression-20220211-call/src/main.rs b/smart_contracts/contracts/test/regression-20220211-call/src/main.rs index ce0aeac048..35cd539c24 100644 --- a/smart_contracts/contracts/test/regression-20220211-call/src/main.rs +++ b/smart_contracts/contracts/test/regression-20220211-call/src/main.rs @@ -5,7 +5,7 @@ extern crate alloc; use alloc::string::String; use casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert}; -use casper_types::{ContractHash, RuntimeArgs, URef}; +use casper_types::{AddressableEntityHash, RuntimeArgs, URef}; const CONTRACT_HASH_NAME: &str = "regression-contract-hash"; const ARG_ENTRYPOINT: &str = "entrypoint"; @@ -15,8 +15,8 @@ pub extern "C" fn call() { let entrypoint: String = runtime::get_named_arg(ARG_ENTRYPOINT); let contract_hash_key = runtime::get_key(CONTRACT_HASH_NAME).unwrap_or_revert(); let contract_hash = contract_hash_key - .into_hash() - .map(ContractHash::new) + .into_entity_addr() + .map(AddressableEntityHash::new) .unwrap_or_revert(); let hardcoded_uref: URef = diff --git a/smart_contracts/contracts/test/regression-20220211/src/main.rs b/smart_contracts/contracts/test/regression-20220211/src/main.rs index 31cd972944..25773f7667 100644 --- a/smart_contracts/contracts/test/regression-20220211/src/main.rs +++ b/smart_contracts/contracts/test/regression-20220211/src/main.rs @@ -7,7 +7,7 @@ use casper_contract::{ }; use casper_types::{ addressable_entity::Parameters, AccessRights, CLType, CLValue, EntryPoint, EntryPointAccess, - EntryPointType, EntryPoints, URef, + EntryPointType, EntryPoints, Key, URef, }; const RET_AS_CONTRACT: &str = "ret_as_contract"; @@ -30,7 +30,7 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); entry_points.add_entry_point(EntryPoint::new( @@ -38,68 +38,68 @@ pub extern "C" fn call() { Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::AddressableEntity, )); entry_points.add_entry_point(EntryPoint::new( PUT_KEY_AS_SESSION, Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); entry_points.add_entry_point(EntryPoint::new( PUT_KEY_AS_CONTRACT, Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); entry_points.add_entry_point(EntryPoint::new( READ_AS_SESSION, Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); entry_points.add_entry_point(EntryPoint::new( READ_AS_CONTRACT, Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); entry_points.add_entry_point(EntryPoint::new( WRITE_AS_SESSION, Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); entry_points.add_entry_point(EntryPoint::new( WRITE_AS_CONTRACT, Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); entry_points.add_entry_point(EntryPoint::new( ADD_AS_SESSION, Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); entry_points.add_entry_point(EntryPoint::new( ADD_AS_CONTRACT, Parameters::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); let (contract_hash, _contract_version) = storage::new_locked_contract(entry_points, None, None, None); - runtime::put_key(CONTRACT_HASH_NAME, contract_hash.into()); + runtime::put_key(CONTRACT_HASH_NAME, Key::contract_entity_key(contract_hash)); } #[no_mangle] diff --git a/smart_contracts/contracts/test/regression_20211110/src/main.rs b/smart_contracts/contracts/test/regression_20211110/src/main.rs index 675f8628eb..147c2f6396 100644 --- a/smart_contracts/contracts/test/regression_20211110/src/main.rs +++ b/smart_contracts/contracts/test/regression_20211110/src/main.rs @@ -6,8 +6,8 @@ extern crate alloc; use casper_contract::contract_api::{runtime, storage}; use casper_types::{ - runtime_args, CLType, CLTyped, ContractHash, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Parameter, + runtime_args, AddressableEntityHash, CLType, CLTyped, EntryPoint, EntryPointAccess, + EntryPointType, EntryPoints, Key, Parameter, }; const RECURSE_ENTRYPOINT: &str = "recurse"; @@ -19,21 +19,21 @@ pub extern "C" fn call() { let mut entry_points = EntryPoints::new(); entry_points.add_entry_point(EntryPoint::new( RECURSE_ENTRYPOINT, - vec![Parameter::new(ARG_TARGET, ContractHash::cl_type())], + vec![Parameter::new(ARG_TARGET, AddressableEntityHash::cl_type())], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); let (contract_hash, _contract_version) = storage::new_locked_contract(entry_points, None, None, None); - runtime::put_key(CONTRACT_HASH_NAME, contract_hash.into()); + runtime::put_key(CONTRACT_HASH_NAME, Key::contract_entity_key(contract_hash)); } #[no_mangle] pub extern "C" fn recurse() { - let target: ContractHash = runtime::get_named_arg(ARG_TARGET); + let target: AddressableEntityHash = runtime::get_named_arg(ARG_TARGET); runtime::call_contract( target, RECURSE_ENTRYPOINT, diff --git a/smart_contracts/contracts/test/ret-uref/Cargo.toml b/smart_contracts/contracts/test/ret-uref/Cargo.toml new file mode 100644 index 0000000000..58495ac2f2 --- /dev/null +++ b/smart_contracts/contracts/test/ret-uref/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "ret-uref" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[bin]] +name = "ret_uref" +path = "src/main.rs" +bench = false +doctest = false +test = false + +[dependencies] +casper-contract = { path = "../../../contract" } +casper-types = { path = "../../../../types" } diff --git a/smart_contracts/contracts/test/ret-uref/src/main.rs b/smart_contracts/contracts/test/ret-uref/src/main.rs new file mode 100644 index 0000000000..c577ca57c0 --- /dev/null +++ b/smart_contracts/contracts/test/ret-uref/src/main.rs @@ -0,0 +1,80 @@ +#![no_std] +#![no_main] + +extern crate alloc; + +use alloc::{ + string::{String, ToString}, + vec, +}; +use casper_contract::{ + contract_api::{runtime, storage}, + unwrap_or_revert::UnwrapOrRevert, +}; +use casper_types::{ + runtime_args, CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, + Parameter, URef, +}; + +const ACCESS_UREF: &str = "access_uref"; +const PUT_UREF: &str = "put_uref"; +const GET_UREF: &str = "get_uref"; +const INSERT_UREF: &str = "insert_uref"; +const HASH_KEY_NAME: &str = "ret_uref_contract_hash"; + +#[no_mangle] +pub extern "C" fn put_uref() { + let access_uref: URef = runtime::get_named_arg(ACCESS_UREF); + runtime::put_key(ACCESS_UREF, access_uref.into()); +} + +#[no_mangle] +pub extern "C" fn get_uref() { + let uref = runtime::get_key(ACCESS_UREF) + .unwrap_or_revert() + .into_uref() + .unwrap_or_revert(); + runtime::ret(CLValue::from_t(uref).unwrap_or_revert()) +} + +#[no_mangle] +pub extern "C" fn insert_uref() { + let contract_hash = runtime::get_named_arg("contract_hash"); + let uref_name: String = runtime::get_named_arg("name"); + let access_uref: URef = runtime::call_contract(contract_hash, GET_UREF, runtime_args! {}); + runtime::put_key(&uref_name, access_uref.into()); +} + +#[no_mangle] +pub extern "C" fn call() { + let entry_points = { + let mut entry_points = EntryPoints::new(); + let put_uref_entrypoint = EntryPoint::new( + PUT_UREF.to_string(), + vec![Parameter::new(ACCESS_UREF, CLType::URef)], + CLType::Unit, + EntryPointAccess::Public, + EntryPointType::AddressableEntity, + ); + entry_points.add_entry_point(put_uref_entrypoint); + let get_uref_entrypoint = EntryPoint::new( + GET_UREF.to_string(), + vec![], + CLType::URef, + EntryPointAccess::Public, + EntryPointType::AddressableEntity, + ); + entry_points.add_entry_point(get_uref_entrypoint); + let insert_uref_entrypoint = EntryPoint::new( + INSERT_UREF.to_string(), + vec![Parameter::new("contract_hash", CLType::ByteArray(32))], + CLType::Unit, + EntryPointAccess::Public, + EntryPointType::Session, + ); + entry_points.add_entry_point(insert_uref_entrypoint); + entry_points + }; + let (contract_hash, _) = storage::new_contract(entry_points, None, None, None); + runtime::put_key(HASH_KEY_NAME, Key::contract_entity_key(contract_hash)); +} diff --git a/smart_contracts/contracts/test/storage-costs/src/main.rs b/smart_contracts/contracts/test/storage-costs/src/main.rs index 94fbd8bc37..aec618f897 100644 --- a/smart_contracts/contracts/test/storage-costs/src/main.rs +++ b/smart_contracts/contracts/test/storage-costs/src/main.rs @@ -93,9 +93,8 @@ pub extern "C" fn create_contract_package_at_hash_function() { #[no_mangle] pub extern "C" fn create_contract_user_group_function() { let contract_package_hash = runtime::get_key(CONTRACT_KEY_NAME) - .and_then(Key::into_hash) - .expect("should have package hash") - .into(); + .and_then(Key::into_package_hash) + .expect("should have package hash"); let _result = storage::create_contract_user_group( contract_package_hash, LABEL_NAME, @@ -108,9 +107,8 @@ pub extern "C" fn create_contract_user_group_function() { #[no_mangle] pub extern "C" fn provision_urefs_function() { let contract_package_hash = runtime::get_key(CONTRACT_KEY_NAME) - .and_then(Key::into_hash) - .expect("should have package hash") - .into(); + .and_then(Key::into_package_hash) + .expect("should have package hash"); let _result = storage::provision_contract_user_group_uref(contract_package_hash, LABEL_NAME) .unwrap_or_revert(); } @@ -118,18 +116,16 @@ pub extern "C" fn provision_urefs_function() { #[no_mangle] pub extern "C" fn remove_contract_user_group_function() { let contract_package_hash = runtime::get_key(CONTRACT_KEY_NAME) - .and_then(Key::into_hash) - .expect("should have package hash") - .into(); + .and_then(Key::into_package_hash) + .expect("should have package hash"); storage::remove_contract_user_group(contract_package_hash, LABEL_NAME).unwrap_or_revert(); } #[no_mangle] pub extern "C" fn new_uref_subcall() { let contract_package_hash = runtime::get_key(CONTRACT_KEY_NAME) - .and_then(Key::into_hash) - .expect("should have package hash") - .into(); + .and_then(Key::into_package_hash) + .expect("should have package hash"); runtime::call_versioned_contract( contract_package_hash, None, @@ -147,7 +143,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); let entry_point = EntryPoint::new( @@ -155,7 +151,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); let entry_point = EntryPoint::new( @@ -163,7 +159,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); let entry_point = EntryPoint::new( @@ -171,7 +167,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -180,7 +176,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -189,7 +185,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -198,7 +194,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -207,7 +203,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -216,7 +212,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -225,7 +221,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -234,7 +230,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -243,7 +239,7 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -264,7 +260,7 @@ pub extern "C" fn call() { named_keys.insert( CONTRACT_KEY_NAME.to_string(), - Key::Hash(contract_package_hash.value()), + Key::Package(contract_package_hash.value()), ); named_keys.insert(ACCESS_KEY_NAME.to_string(), access_uref.into()); @@ -273,6 +269,6 @@ pub extern "C" fn call() { let (contract_hash, _version) = storage::add_contract_version(contract_package_hash, entry_points, named_keys); - runtime::put_key(CONTRACT_KEY_NAME, contract_hash.into()); + runtime::put_key(CONTRACT_KEY_NAME, Key::contract_entity_key(contract_hash)); runtime::put_key(ACCESS_KEY_NAME, access_uref.into()); } diff --git a/smart_contracts/contracts/test/system-contract-hashes/src/main.rs b/smart_contracts/contracts/test/system-contract-hashes/src/main.rs index 86e6631871..059806aeb0 100644 --- a/smart_contracts/contracts/test/system-contract-hashes/src/main.rs +++ b/smart_contracts/contracts/test/system-contract-hashes/src/main.rs @@ -6,7 +6,7 @@ use casper_types::system::{AUCTION, HANDLE_PAYMENT, MINT}; #[no_mangle] pub extern "C" fn call() { - runtime::put_key(MINT, system::get_mint().into()); - runtime::put_key(HANDLE_PAYMENT, system::get_handle_payment().into()); - runtime::put_key(AUCTION, system::get_auction().into()); + runtime::put_key(MINT, system::get_mint_key()); + runtime::put_key(HANDLE_PAYMENT, system::get_handle_payment_key()); + runtime::put_key(AUCTION, system::get_auction_key()); } 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 5a7fc8d11b..45cb6147dc 100644 --- a/smart_contracts/contracts/test/test-payment-stored/src/main.rs +++ b/smart_contracts/contracts/test/test-payment-stored/src/main.rs @@ -12,7 +12,7 @@ use casper_contract::{ use casper_types::{ addressable_entity::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Parameter}, system::standard_payment, - CLType, RuntimeArgs, URef, U512, + CLType, Key, RuntimeArgs, URef, U512, }; const ENTRY_FUNCTION_NAME: &str = "pay"; @@ -53,7 +53,7 @@ pub extern "C" fn call() { vec![Parameter::new(standard_payment::ARG_AMOUNT, CLType::U512)], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Session, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); entry_points @@ -65,5 +65,5 @@ pub extern "C" fn call() { Some(ACCESS_KEY_NAME.to_string()), ); runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into()); - runtime::put_key(HASH_KEY_NAME, contract_hash.into()); + runtime::put_key(HASH_KEY_NAME, Key::contract_entity_key(contract_hash)); } 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 61dfd47079..11cb5093e6 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 @@ -9,7 +9,8 @@ use casper_contract::contract_api::{runtime, storage}; use casper_types::{ addressable_entity::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Parameter}, - CLType, + package::PackageKindTag, + CLType, Key, }; const ENTRY_FUNCTION_NAME: &str = "transfer"; @@ -51,5 +52,8 @@ pub extern "C" fn call() { Some(ACCESS_KEY_NAME.to_string()), ); runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into()); - runtime::put_key(HASH_KEY_NAME, contract_hash.into()); + runtime::put_key( + HASH_KEY_NAME, + Key::addressable_entity_key(PackageKindTag::SmartContract, contract_hash), + ); } 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 b5607c74ae..5b1a83f39d 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 @@ -15,7 +15,8 @@ use casper_types::{ addressable_entity::{ EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys, Parameter, }, - CLType, CLTyped, U512, + package::PackageKindTag, + CLType, CLTyped, Key, U512, }; const ENTRY_FUNCTION_NAME: &str = "transfer"; @@ -56,7 +57,7 @@ pub extern "C" fn call() { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); tmp.add_entry_point(entry_point); tmp @@ -82,5 +83,8 @@ pub extern "C" fn call() { ); runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into()); - runtime::put_key(HASH_KEY_NAME, contract_hash.into()); + runtime::put_key( + HASH_KEY_NAME, + Key::addressable_entity_key(PackageKindTag::SmartContract, contract_hash), + ); } diff --git a/smart_contracts/contracts/test/transfer-purse-to-accounts-subcall/src/lib.rs b/smart_contracts/contracts/test/transfer-purse-to-accounts-subcall/src/lib.rs index 9d9e8deb96..7263dc4205 100644 --- a/smart_contracts/contracts/test/transfer-purse-to-accounts-subcall/src/lib.rs +++ b/smart_contracts/contracts/test/transfer-purse-to-accounts-subcall/src/lib.rs @@ -25,11 +25,11 @@ pub fn delegate() { } let contract_hash = runtime::get_key(HASH_KEY_NAME) - .and_then(Key::into_hash) + .and_then(Key::into_entity_hash) .unwrap_or_revert(); runtime::call_contract( - contract_hash.into(), + contract_hash, ENTRYPOINT, runtime_args! { ARG_SOURCE => source, diff --git a/smart_contracts/contracts/test/upgrade-threshold-upgrader/Cargo.toml b/smart_contracts/contracts/test/upgrade-threshold-upgrader/Cargo.toml new file mode 100644 index 0000000000..3fb05b3c1c --- /dev/null +++ b/smart_contracts/contracts/test/upgrade-threshold-upgrader/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "upgrade-threshold-upgrader" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[[bin]] +name = "upgrade_threshold_upgrader" +path = "src/main.rs" +bench = false +doctest = false +test = false + +[dependencies] +casper-contract = { path = "../../../contract" } +casper-types = { path = "../../../../types" } \ No newline at end of file diff --git a/smart_contracts/contracts/test/upgrade-threshold-upgrader/src/main.rs b/smart_contracts/contracts/test/upgrade-threshold-upgrader/src/main.rs new file mode 100644 index 0000000000..faf85779d9 --- /dev/null +++ b/smart_contracts/contracts/test/upgrade-threshold-upgrader/src/main.rs @@ -0,0 +1,91 @@ +#![no_std] +#![no_main] + +extern crate alloc; + +use alloc::vec; +use casper_contract::{ + contract_api::{account, runtime, storage}, + unwrap_or_revert::UnwrapOrRevert, +}; +use casper_types::{ + account::AccountHash, + addressable_entity::{ActionType, NamedKeys, Weight}, + CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, PackageHash, Parameter, +}; + +const ARG_ENTITY_ACCOUNT_HASH: &str = "entity_account_hash"; +const ARG_KEY_WEIGHT: &str = "key_weight"; +const ARG_NEW_UPGRADE_THRESHOLD: &str = "new_threshold"; +const ARG_CONTRACT_PACKAGE: &str = "contract_package_hash"; + +const ENTRYPOINT_ADD_ASSOCIATED_KEY: &str = "add_associated_key"; +const ENTRYPOINT_MANAGE_ACTION_THRESHOLD: &str = "manage_action_threshold"; +const ENTRYPOINT_REMOVE_ASSOCIATED_KEY: &str = "remove_associated_key"; + +const CONTRACT_HASH_NAME: &str = "contract_hash_name"; + +#[no_mangle] +pub extern "C" fn add_associated_key() { + let entity_account_hash: AccountHash = runtime::get_named_arg(ARG_ENTITY_ACCOUNT_HASH); + let weight: u8 = runtime::get_named_arg(ARG_KEY_WEIGHT); + account::add_associated_key(entity_account_hash, Weight::new(weight)).unwrap_or_revert(); +} + +#[no_mangle] +pub extern "C" fn manage_action_threshold() { + let new_threshold = runtime::get_named_arg(ARG_NEW_UPGRADE_THRESHOLD); + account::set_action_threshold(ActionType::UpgradeManagement, new_threshold).unwrap_or_revert() +} + +#[no_mangle] +pub extern "C" fn remove_associated_key() { + let entity_account_hash: AccountHash = runtime::get_named_arg(ARG_ENTITY_ACCOUNT_HASH); + account::remove_associated_key(entity_account_hash).unwrap_or_revert(); +} + +#[no_mangle] +pub extern "C" fn call() { + let contract_package: PackageHash = runtime::get_named_arg(ARG_CONTRACT_PACKAGE); + let entry_points = { + let mut entrypoints = EntryPoints::new(); + let add_associated_key_entry_point = EntryPoint::new( + ENTRYPOINT_ADD_ASSOCIATED_KEY, + vec![ + Parameter::new(ARG_ENTITY_ACCOUNT_HASH, CLType::ByteArray(32)), + Parameter::new(ARG_KEY_WEIGHT, CLType::U8), + ], + CLType::Unit, + EntryPointAccess::Public, + EntryPointType::AddressableEntity, + ); + entrypoints.add_entry_point(add_associated_key_entry_point); + let manage_action_threshold_entrypoint = EntryPoint::new( + ENTRYPOINT_MANAGE_ACTION_THRESHOLD, + vec![Parameter::new(ARG_NEW_UPGRADE_THRESHOLD, CLType::U8)], + CLType::Unit, + EntryPointAccess::Public, + EntryPointType::AddressableEntity, + ); + entrypoints.add_entry_point(manage_action_threshold_entrypoint); + let remove_associated_key_entry_point = EntryPoint::new( + ENTRYPOINT_REMOVE_ASSOCIATED_KEY, + vec![Parameter::new( + ARG_ENTITY_ACCOUNT_HASH, + CLType::ByteArray(32), + )], + CLType::Unit, + EntryPointAccess::Public, + EntryPointType::AddressableEntity, + ); + entrypoints.add_entry_point(remove_associated_key_entry_point); + entrypoints + }; + // this should overwrite the previous contract obj with the new contract obj at the same uref + let (new_contract_hash, _new_contract_version) = + storage::add_contract_version(contract_package, entry_points, NamedKeys::new()); + runtime::put_key( + CONTRACT_HASH_NAME, + Key::contract_entity_key(new_contract_hash), + ); +} diff --git a/smart_contracts/contracts/test/upgrade-threshold/Cargo.toml b/smart_contracts/contracts/test/upgrade-threshold/Cargo.toml new file mode 100644 index 0000000000..54a603306d --- /dev/null +++ b/smart_contracts/contracts/test/upgrade-threshold/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "upgrade-threshold" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[bin]] +name = "upgrade_threshold" +path = "src/main.rs" +bench = false +doctest = false +test = false + +[dependencies] +casper-contract = { path = "../../../contract" } +casper-types = { path = "../../../../types" } \ No newline at end of file diff --git a/smart_contracts/contracts/test/upgrade-threshold/src/main.rs b/smart_contracts/contracts/test/upgrade-threshold/src/main.rs new file mode 100644 index 0000000000..b7e4f89a0f --- /dev/null +++ b/smart_contracts/contracts/test/upgrade-threshold/src/main.rs @@ -0,0 +1,74 @@ +#![no_std] +#![no_main] + +extern crate alloc; + +use alloc::{string::ToString, vec}; +use casper_contract::{ + contract_api::{account, runtime, storage}, + unwrap_or_revert::UnwrapOrRevert, +}; +use casper_types::{ + account::AccountHash, + addressable_entity::{ActionType, Weight}, + CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, +}; + +const ARG_ENTITY_ACCOUNT_HASH: &str = "entity_account_hash"; +const ARG_KEY_WEIGHT: &str = "key_weight"; +const ARG_NEW_UPGRADE_THRESHOLD: &str = "new_threshold"; + +const ENTRYPOINT_ADD_ASSOCIATED_KEY: &str = "add_associated_key"; +const ENTRYPOINT_MANAGE_ACTION_THRESHOLD: &str = "manage_action_threshold"; + +const PACKAGE_HASH_KEY_NAME: &str = "contract_package_hash"; +const ACCESS_UREF_NAME: &str = "access_uref"; +const CONTRACT_HASH_NAME: &str = "contract_hash_name"; + +#[no_mangle] +pub extern "C" fn add_associated_key() { + let entity_account_hash: AccountHash = runtime::get_named_arg(ARG_ENTITY_ACCOUNT_HASH); + let weight: u8 = runtime::get_named_arg(ARG_KEY_WEIGHT); + account::add_associated_key(entity_account_hash, Weight::new(weight)).unwrap_or_revert(); +} + +#[no_mangle] +pub extern "C" fn manage_action_threshold() { + let new_threshold = runtime::get_named_arg::(ARG_NEW_UPGRADE_THRESHOLD); + account::set_action_threshold(ActionType::UpgradeManagement, Weight::new(new_threshold)) + .unwrap_or_revert() +} + +#[no_mangle] +pub extern "C" fn call() { + let entrypoints = { + let mut entrypoints = EntryPoints::new(); + let add_associated_key_entry_point = EntryPoint::new( + ENTRYPOINT_ADD_ASSOCIATED_KEY, + vec![ + Parameter::new(ARG_ENTITY_ACCOUNT_HASH, CLType::ByteArray(32)), + Parameter::new(ARG_KEY_WEIGHT, CLType::U8), + ], + CLType::Unit, + EntryPointAccess::Public, + EntryPointType::AddressableEntity, + ); + entrypoints.add_entry_point(add_associated_key_entry_point); + let manage_action_threshold_entrypoint = EntryPoint::new( + ENTRYPOINT_MANAGE_ACTION_THRESHOLD, + vec![Parameter::new(ARG_NEW_UPGRADE_THRESHOLD, CLType::U8)], + CLType::Unit, + EntryPointAccess::Public, + EntryPointType::AddressableEntity, + ); + entrypoints.add_entry_point(manage_action_threshold_entrypoint); + entrypoints + }; + let (contract_hash, _) = storage::new_contract( + entrypoints, + None, + Some(PACKAGE_HASH_KEY_NAME.to_string()), + Some(ACCESS_UREF_NAME.to_string()), + ); + runtime::put_key(CONTRACT_HASH_NAME, Key::contract_entity_key(contract_hash)); +} diff --git a/smart_contracts/contracts/tutorial/counter-installer/src/main.rs b/smart_contracts/contracts/tutorial/counter-installer/src/main.rs index 4023a94ac9..c08e5c6335 100644 --- a/smart_contracts/contracts/tutorial/counter-installer/src/main.rs +++ b/smart_contracts/contracts/tutorial/counter-installer/src/main.rs @@ -17,7 +17,7 @@ use casper_contract::{ use casper_types::{ addressable_entity::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys}, api_error::ApiError, - CLType, CLValue, URef, + CLType, CLValue, Key, URef, }; const COUNT_KEY: &str = "count"; @@ -65,14 +65,14 @@ pub extern "C" fn call() { Vec::new(), CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); counter_entry_points.add_entry_point(EntryPoint::new( COUNTER_GET, Vec::new(), CLType::I32, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, )); let (stored_contract_hash, contract_version) = storage::new_contract( @@ -92,5 +92,5 @@ pub extern "C" fn call() { runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into()); // Hash of the installed contract will be reachable through named keys - runtime::put_key(COUNTER_KEY, stored_contract_hash.into()); + runtime::put_key(COUNTER_KEY, Key::contract_entity_key(stored_contract_hash)); } diff --git a/smart_contracts/contracts/tutorial/increment-counter/src/main.rs b/smart_contracts/contracts/tutorial/increment-counter/src/main.rs index 558b49e435..08fe8abeab 100644 --- a/smart_contracts/contracts/tutorial/increment-counter/src/main.rs +++ b/smart_contracts/contracts/tutorial/increment-counter/src/main.rs @@ -6,7 +6,7 @@ compile_error!("target arch should be wasm32: compile with '--target wasm32-unkn extern crate alloc; -use casper_types::{runtime_args::RuntimeArgs, ApiError, ContractHash, Key}; +use casper_types::{runtime_args::RuntimeArgs, AddressableEntityHash, ApiError, Key}; use casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert}; @@ -19,8 +19,8 @@ pub extern "C" fn call() { // Read the Counter smart contract's ContractHash. let contract_hash = { let counter_uref = runtime::get_key(COUNTER_KEY).unwrap_or_revert_with(ApiError::GetKey); - if let Key::Hash(hash) = counter_uref { - ContractHash::new(hash) + if let Key::AddressableEntity((_, hash)) = counter_uref { + AddressableEntityHash::new(hash) } else { runtime::revert(ApiError::User(66)); } diff --git a/types/benches/bytesrepr_bench.rs b/types/benches/bytesrepr_bench.rs index 5648e984fe..dff857cefd 100644 --- a/types/benches/bytesrepr_bench.rs +++ b/types/benches/bytesrepr_bench.rs @@ -9,13 +9,13 @@ use casper_types::{ account::AccountHash, addressable_entity::{ActionThresholds, AddressableEntity, AssociatedKeys, NamedKeys}, bytesrepr::{self, Bytes, FromBytes, ToBytes}, - package::{ContractPackageKind, ContractPackageStatus}, + package::{PackageKind, PackageStatus}, system::auction::{Bid, Delegator, EraInfo, SeigniorageAllocation}, - AccessRights, CLType, CLTyped, CLValue, ContractHash, ContractPackageHash, ContractVersionKey, - ContractVersions, ContractWasmHash, DeployHash, DeployInfo, EntryPoint, EntryPointAccess, - EntryPointType, EntryPoints, Group, Groups, Key, Package, Parameter, ProtocolVersion, - PublicKey, SecretKey, Transfer, TransferAddr, URef, KEY_HASH_LENGTH, TRANSFER_ADDR_LENGTH, - U128, U256, U512, UREF_ADDR_LENGTH, + 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, }; static KB: usize = 1024; @@ -486,7 +486,7 @@ fn sample_contract(named_keys_len: u8, entry_points_len: u8) -> AddressableEntit args, casper_types::CLType::U512, EntryPointAccess::groups(&["Group 2"]), - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); tmp.add_entry_point(entry_point); }); @@ -494,8 +494,8 @@ fn sample_contract(named_keys_len: u8, entry_points_len: u8) -> AddressableEntit }; casper_types::addressable_entity::AddressableEntity::new( - ContractPackageHash::default(), - ContractWasmHash::default(), + PackageHash::default(), + ByteCodeHash::default(), named_keys, entry_points, ProtocolVersion::default(), @@ -505,12 +505,12 @@ fn sample_contract(named_keys_len: u8, entry_points_len: u8) -> AddressableEntit ) } -fn contract_version_key_fn(i: u8) -> ContractVersionKey { - ContractVersionKey::new(i as u32, i as u32) +fn contract_version_key_fn(i: u8) -> EntityVersionKey { + EntityVersionKey::new(i as u32, i as u32) } -fn contract_hash_fn(i: u8) -> ContractHash { - ContractHash::new([i; KEY_HASH_LENGTH]) +fn contract_hash_fn(i: u8) -> AddressableEntityHash { + AddressableEntityHash::new([i; KEY_HASH_LENGTH]) } fn sample_map(key_fn: FK, value_fn: FV, count: u8) -> BTreeMap @@ -548,7 +548,7 @@ fn sample_contract_package( groups_len: u8, ) -> Package { let access_key = URef::default(); - let versions = ContractVersions::from(sample_map( + let versions = EntityVersions::from(sample_map( contract_version_key_fn, contract_hash_fn, contract_versions_len, @@ -565,8 +565,8 @@ fn sample_contract_package( versions, disabled_versions, groups, - ContractPackageStatus::Locked, - ContractPackageKind::Wasm, + PackageStatus::Locked, + PackageKind::SmartContract, ) } diff --git a/types/src/access_rights.rs b/types/src/access_rights.rs index 029e7adbf6..818ae3aa80 100644 --- a/types/src/access_rights.rs +++ b/types/src/access_rights.rs @@ -13,7 +13,7 @@ use rand::{ }; use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer}; -use crate::{bytesrepr, ContractHash, URef, URefAddr}; +use crate::{bytesrepr, AddressableEntityHash, URef, URefAddr}; /// The number of bytes in a serialized [`AccessRights`]. pub const ACCESS_RIGHTS_SERIALIZED_LENGTH: usize = 1; @@ -157,7 +157,7 @@ pub enum GrantedAccess { /// Access rights for a given runtime context. #[derive(Debug, PartialEq, Eq)] pub struct ContextAccessRights { - context_contract_hash: ContractHash, + context_entity_hash: AddressableEntityHash, access_rights: BTreeMap, } @@ -165,11 +165,11 @@ impl ContextAccessRights { /// Creates a new instance of access rights from an iterator of URefs merging any duplicates, /// taking the union of their rights. pub fn new>( - context_contract_hash: ContractHash, + context_entity_hash: AddressableEntityHash, uref_iter: T, ) -> Self { let mut context_access_rights = ContextAccessRights { - context_contract_hash, + context_entity_hash, access_rights: BTreeMap::new(), }; context_access_rights.do_extend(uref_iter); @@ -177,8 +177,8 @@ impl ContextAccessRights { } /// Returns the current context key. - pub fn context_key(&self) -> ContractHash { - self.context_contract_hash + pub fn context_key(&self) -> AddressableEntityHash { + self.context_entity_hash } /// Extends the current access rights from a given set of URefs. @@ -250,7 +250,7 @@ mod tests { use super::*; use crate::UREF_ADDR_LENGTH; - const CONTRACT_HASH: ContractHash = ContractHash::new([1u8; 32]); + const ENTITY_HASH: AddressableEntityHash = AddressableEntityHash::new([1u8; 32]); const UREF_ADDRESS: [u8; UREF_ADDR_LENGTH] = [1; UREF_ADDR_LENGTH]; const UREF_NO_PERMISSIONS: URef = URef::new(UREF_ADDRESS, AccessRights::empty()); const UREF_READ: URef = URef::new(UREF_ADDRESS, AccessRights::READ); @@ -306,7 +306,7 @@ mod tests { #[test] fn should_check_has_access_rights_to_uref() { - let context_rights = ContextAccessRights::new(CONTRACT_HASH, vec![UREF_READ_ADD]); + let context_rights = ContextAccessRights::new(ENTITY_HASH, vec![UREF_READ_ADD]); assert!(context_rights.has_access_rights_to_uref(&UREF_READ_ADD)); assert!(context_rights.has_access_rights_to_uref(&UREF_READ)); assert!(context_rights.has_access_rights_to_uref(&UREF_ADD)); @@ -315,7 +315,7 @@ mod tests { #[test] fn should_check_does_not_have_access_rights_to_uref() { - let context_rights = ContextAccessRights::new(CONTRACT_HASH, vec![UREF_READ_ADD]); + let context_rights = ContextAccessRights::new(ENTITY_HASH, vec![UREF_READ_ADD]); assert!(!context_rights.has_access_rights_to_uref(&UREF_READ_ADD_WRITE)); assert!(!context_rights .has_access_rights_to_uref(&URef::new([2; UREF_ADDR_LENGTH], AccessRights::empty()))); @@ -324,7 +324,7 @@ mod tests { #[test] fn should_extend_access_rights() { // Start with uref with no permissions. - let mut context_rights = ContextAccessRights::new(CONTRACT_HASH, vec![UREF_NO_PERMISSIONS]); + let mut context_rights = ContextAccessRights::new(ENTITY_HASH, vec![UREF_NO_PERMISSIONS]); let mut expected_rights = BTreeMap::new(); expected_rights.insert(UREF_ADDRESS, AccessRights::empty()); assert_eq!(context_rights.access_rights, expected_rights); @@ -346,10 +346,8 @@ mod tests { #[test] fn should_perform_union_of_access_rights_in_new() { - let context_rights = ContextAccessRights::new( - CONTRACT_HASH, - vec![UREF_NO_PERMISSIONS, UREF_READ, UREF_ADD], - ); + let context_rights = + ContextAccessRights::new(ENTITY_HASH, vec![UREF_NO_PERMISSIONS, UREF_READ, UREF_ADD]); // Expect the three discrete URefs' rights to be unioned into READ_ADD. let mut expected_rights = BTreeMap::new(); @@ -359,7 +357,7 @@ mod tests { #[test] fn should_grant_access_rights() { - let mut context_rights = ContextAccessRights::new(CONTRACT_HASH, vec![UREF_READ_ADD]); + let mut context_rights = ContextAccessRights::new(ENTITY_HASH, vec![UREF_READ_ADD]); let granted_access = context_rights.grant_access(UREF_READ); assert_eq!(granted_access, GrantedAccess::PreExisting); let granted_access = context_rights.grant_access(UREF_READ_ADD_WRITE); @@ -385,7 +383,7 @@ mod tests { #[test] fn should_remove_access_rights() { - let mut context_rights = ContextAccessRights::new(CONTRACT_HASH, vec![UREF_READ_ADD_WRITE]); + let mut context_rights = ContextAccessRights::new(ENTITY_HASH, vec![UREF_READ_ADD_WRITE]); assert!(context_rights.has_access_rights_to_uref(&UREF_READ_ADD_WRITE)); // Strip write access from the context rights. diff --git a/types/src/addressable_entity.rs b/types/src/addressable_entity.rs index c27775aad7..5c2dbf2328 100644 --- a/types/src/addressable_entity.rs +++ b/types/src/addressable_entity.rs @@ -47,13 +47,14 @@ pub use self::{ use crate::{ account::{Account, AccountHash}, + byte_code::ByteCodeHash, bytesrepr::{self, FromBytes, ToBytes}, checksummed_hex, - contract_wasm::ContractWasmHash, - contracts::Contract, + contracts::{Contract, ContractHash}, + key::ByteCodeAddr, uref::{self, URef}, - AccessRights, CLType, CLTyped, ContextAccessRights, ContractPackageHash, Group, HashAddr, Key, - ProtocolVersion, KEY_HASH_LENGTH, + AccessRights, ApiError, CLType, CLTyped, ContextAccessRights, Group, HashAddr, Key, + PackageHash, ProtocolVersion, KEY_HASH_LENGTH, }; /// Maximum number of distinct user groups. @@ -70,7 +71,7 @@ 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 CONTRACT_STRING_PREFIX: &str = "contract-"; +const ADDRESSABLE_ENTITY_STRING_PREFIX: &str = "addressable-entity-"; /// Set of errors which may happen when working with contract headers. #[derive(Debug, PartialEq, Eq)] @@ -88,9 +89,9 @@ pub enum Error { /// Attempted to disable a contract that does not exist. /// ``` /// # use casper_types::addressable_entity::Error; - /// assert_eq!(2, Error::ContractNotFound as u8); + /// assert_eq!(2, Error::EntityNotFound as u8); /// ``` - ContractNotFound = 2, + EntityNotFound = 2, /// Attempted to create a user group which already exists (use the update /// function to change an existing user group). /// ``` @@ -145,7 +146,7 @@ impl TryFrom for Error { fn try_from(value: u8) -> Result { let error = match value { v if v == Self::PreviouslyUsedVersion as u8 => Self::PreviouslyUsedVersion, - v if v == Self::ContractNotFound as u8 => Self::ContractNotFound, + v if v == Self::EntityNotFound as u8 => Self::EntityNotFound, v if v == Self::GroupAlreadyExists as u8 => Self::GroupAlreadyExists, v if v == Self::MaxGroupsExceeded as u8 => Self::MaxGroupsExceeded, v if v == Self::MaxTotalURefsExceeded as u8 => Self::MaxTotalURefsExceeded, @@ -225,14 +226,14 @@ impl Display for FromStrError { derive(JsonSchema), schemars(description = "The hex-encoded address of the addressable entity.") )] -pub struct ContractHash( +pub struct AddressableEntityHash( #[cfg_attr(feature = "json-schema", schemars(skip, with = "String"))] HashAddr, ); -impl ContractHash { - /// Constructs a new `ContractHash` from the raw bytes of the contract hash. - pub const fn new(value: HashAddr) -> ContractHash { - ContractHash(value) +impl AddressableEntityHash { + /// Constructs a new `AddressableEntityHash` from the raw bytes of the contract hash. + pub const fn new(value: HashAddr) -> AddressableEntityHash { + AddressableEntityHash(value) } /// Returns the raw bytes of the contract hash as an array. @@ -245,45 +246,55 @@ impl ContractHash { &self.0 } - /// Formats the `ContractHash` for users getting and putting. + /// Formats the `AddressableEntityHash` for users getting and putting. pub fn to_formatted_string(self) -> String { format!( "{}{}", - CONTRACT_STRING_PREFIX, + ADDRESSABLE_ENTITY_STRING_PREFIX, base16::encode_lower(&self.0), ) } /// Parses a string formatted as per `Self::to_formatted_string()` into a - /// `ContractHash`. + /// `AddressableEntityHash`. pub fn from_formatted_str(input: &str) -> Result { let remainder = input - .strip_prefix(CONTRACT_STRING_PREFIX) + .strip_prefix(ADDRESSABLE_ENTITY_STRING_PREFIX) .ok_or(FromStrError::InvalidPrefix)?; let bytes = HashAddr::try_from(checksummed_hex::decode(remainder)?.as_ref())?; - Ok(ContractHash(bytes)) + Ok(AddressableEntityHash(bytes)) } } -impl Display for ContractHash { +impl From for AddressableEntityHash { + fn from(contract_hash: ContractHash) -> Self { + AddressableEntityHash::new(contract_hash.value()) + } +} + +impl Display for AddressableEntityHash { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "{}", base16::encode_lower(&self.0)) } } -impl Debug for ContractHash { +impl Debug for AddressableEntityHash { fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { - write!(f, "ContractHash({})", base16::encode_lower(&self.0)) + write!( + f, + "AddressableEntityHash({})", + base16::encode_lower(&self.0) + ) } } -impl CLTyped for ContractHash { +impl CLTyped for AddressableEntityHash { fn cl_type() -> CLType { CLType::ByteArray(KEY_HASH_LENGTH as u32) } } -impl ToBytes for ContractHash { +impl ToBytes for AddressableEntityHash { #[inline(always)] fn to_bytes(&self) -> Result, bytesrepr::Error> { self.0.to_bytes() @@ -301,20 +312,32 @@ impl ToBytes for ContractHash { } } -impl FromBytes for ContractHash { +impl FromBytes for AddressableEntityHash { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { let (bytes, rem) = FromBytes::from_bytes(bytes)?; - Ok((ContractHash::new(bytes), rem)) + Ok((AddressableEntityHash::new(bytes), rem)) } } -impl From<[u8; 32]> for ContractHash { +impl From<[u8; 32]> for AddressableEntityHash { fn from(bytes: [u8; 32]) -> Self { - ContractHash(bytes) + AddressableEntityHash(bytes) + } +} + +impl TryFrom for AddressableEntityHash { + type Error = ApiError; + + fn try_from(value: Key) -> Result { + if let Key::AddressableEntity((_, entity_addr)) = value { + Ok(AddressableEntityHash::new(entity_addr)) + } else { + Err(ApiError::Formatting) + } } } -impl Serialize for ContractHash { +impl Serialize for AddressableEntityHash { fn serialize(&self, serializer: S) -> Result { if serializer.is_human_readable() { self.to_formatted_string().serialize(serializer) @@ -324,40 +347,40 @@ impl Serialize for ContractHash { } } -impl<'de> Deserialize<'de> for ContractHash { +impl<'de> Deserialize<'de> for AddressableEntityHash { fn deserialize>(deserializer: D) -> Result { if deserializer.is_human_readable() { let formatted_string = String::deserialize(deserializer)?; - ContractHash::from_formatted_str(&formatted_string).map_err(SerdeError::custom) + AddressableEntityHash::from_formatted_str(&formatted_string).map_err(SerdeError::custom) } else { let bytes = HashAddr::deserialize(deserializer)?; - Ok(ContractHash(bytes)) + Ok(AddressableEntityHash(bytes)) } } } -impl AsRef<[u8]> for ContractHash { +impl AsRef<[u8]> for AddressableEntityHash { fn as_ref(&self) -> &[u8] { self.0.as_ref() } } -impl TryFrom<&[u8]> for ContractHash { +impl TryFrom<&[u8]> for AddressableEntityHash { type Error = TryFromSliceForContractHashError; fn try_from(bytes: &[u8]) -> Result { HashAddr::try_from(bytes) - .map(ContractHash::new) + .map(AddressableEntityHash::new) .map_err(|_| TryFromSliceForContractHashError(())) } } -impl TryFrom<&Vec> for ContractHash { +impl TryFrom<&Vec> for AddressableEntityHash { type Error = TryFromSliceForContractHashError; fn try_from(bytes: &Vec) -> Result { HashAddr::try_from(bytes as &[u8]) - .map(ContractHash::new) + .map(AddressableEntityHash::new) .map_err(|_| TryFromSliceForContractHashError(())) } } @@ -536,6 +559,15 @@ impl FromBytes for EntryPoints { } } +impl Default for EntryPoints { + fn default() -> Self { + let mut entry_points = EntryPoints::new(); + let entry_point = EntryPoint::default(); + entry_points.add_entry_point(entry_point); + entry_points + } +} + impl EntryPoints { /// Constructs a new, empty `EntryPoints`. pub const fn new() -> EntryPoints { @@ -584,6 +616,13 @@ impl EntryPoints { pub fn is_empty(&self) -> bool { self.0.is_empty() } + + /// Checks if any of the entry points are of the type Session. + pub fn contains_stored_session(&self) -> bool { + self.0 + .values() + .any(|entry_point| entry_point.entry_point_type == EntryPointType::Session) + } } impl From> for EntryPoints { @@ -613,8 +652,8 @@ impl KeyValueJsonSchema for EntryPointLabels { #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] pub struct AddressableEntity { - contract_package_hash: ContractPackageHash, - contract_wasm_hash: ContractWasmHash, + package_hash: PackageHash, + byte_code_hash: ByteCodeHash, named_keys: NamedKeys, entry_points: EntryPoints, protocol_version: ProtocolVersion, @@ -625,8 +664,8 @@ pub struct AddressableEntity { impl From for ( - ContractPackageHash, - ContractWasmHash, + PackageHash, + ByteCodeHash, NamedKeys, EntryPoints, ProtocolVersion, @@ -635,16 +674,16 @@ impl From ActionThresholds, ) { - fn from(contract: AddressableEntity) -> Self { + fn from(entity: AddressableEntity) -> Self { ( - contract.contract_package_hash, - contract.contract_wasm_hash, - contract.named_keys, - contract.entry_points, - contract.protocol_version, - contract.main_purse, - contract.associated_keys, - contract.action_thresholds, + entity.package_hash, + entity.byte_code_hash, + entity.named_keys, + entity.entry_points, + entity.protocol_version, + entity.main_purse, + entity.associated_keys, + entity.action_thresholds, ) } } @@ -653,8 +692,8 @@ impl AddressableEntity { /// `AddressableEntity` constructor. #[allow(clippy::too_many_arguments)] pub fn new( - contract_package_hash: ContractPackageHash, - contract_wasm_hash: ContractWasmHash, + package_hash: PackageHash, + byte_code_hash: ByteCodeHash, named_keys: NamedKeys, entry_points: EntryPoints, protocol_version: ProtocolVersion, @@ -663,8 +702,8 @@ impl AddressableEntity { action_thresholds: ActionThresholds, ) -> Self { AddressableEntity { - contract_package_hash, - contract_wasm_hash, + package_hash, + byte_code_hash, named_keys, entry_points, protocol_version, @@ -675,13 +714,13 @@ impl AddressableEntity { } /// Hash for accessing contract package - pub fn contract_package_hash(&self) -> ContractPackageHash { - self.contract_package_hash + pub fn package_hash(&self) -> PackageHash { + self.package_hash } /// Hash for accessing contract WASM - pub fn contract_wasm_hash(&self) -> ContractWasmHash { - self.contract_wasm_hash + pub fn byte_code_hash(&self) -> ByteCodeHash { + self.byte_code_hash } /// Checks whether there is a method with the given name @@ -838,7 +877,7 @@ impl AddressableEntity { !authorization_keys.is_empty() && authorization_keys .iter() - .all(|e| self.associated_keys.contains_key(e)) + .any(|e| self.associated_keys.contains_key(e)) } /// Checks whether the sum of the weights of all authorization keys is @@ -861,14 +900,24 @@ impl AddressableEntity { total_weight >= *self.action_thresholds().key_management() } + /// Checks whether the sum of the weights of all authorization keys is + /// greater or equal to upgrade management threshold. + pub fn can_upgrade_with(&self, authorization_keys: &BTreeSet) -> bool { + let total_weight = self + .associated_keys + .calculate_keys_weight(authorization_keys); + + total_weight >= *self.action_thresholds().upgrade_management() + } + /// Adds new entry point pub fn add_entry_point>(&mut self, entry_point: EntryPoint) { self.entry_points.add_entry_point(entry_point); } - /// Hash for accessing wasm bytes - pub fn contract_wasm_key(&self) -> Key { - self.contract_wasm_hash.into() + /// Addr for accessing wasm bytes + pub fn byte_code_addr(&self) -> ByteCodeAddr { + self.byte_code_hash.value() } /// Returns immutable reference to methods @@ -907,21 +956,39 @@ impl AddressableEntity { } /// Extracts the access rights from the named keys of the addressable entity. - pub fn extract_access_rights(&self, contract_hash: ContractHash) -> ContextAccessRights { + pub fn extract_access_rights(&self, entity_hash: AddressableEntityHash) -> ContextAccessRights { let urefs_iter = self .named_keys .keys() .filter_map(|key| key.as_uref().copied()) .chain(iter::once(self.main_purse)); - ContextAccessRights::new(contract_hash, urefs_iter) + ContextAccessRights::new(entity_hash, urefs_iter) + } + + /// Update the byte code hash for a given Entity associated with an Account. + pub fn update_session_entity( + self, + byte_code_hash: ByteCodeHash, + entry_points: EntryPoints, + ) -> Self { + Self { + package_hash: self.package_hash, + byte_code_hash, + named_keys: self.named_keys, + entry_points, + protocol_version: self.protocol_version, + main_purse: self.main_purse, + associated_keys: self.associated_keys, + action_thresholds: self.action_thresholds, + } } } impl ToBytes for AddressableEntity { fn to_bytes(&self) -> Result, bytesrepr::Error> { let mut result = bytesrepr::allocate_buffer(self)?; - self.contract_package_hash().write_bytes(&mut result)?; - self.contract_wasm_hash().write_bytes(&mut result)?; + self.package_hash().write_bytes(&mut result)?; + self.byte_code_hash().write_bytes(&mut result)?; self.named_keys().write_bytes(&mut result)?; self.entry_points().write_bytes(&mut result)?; self.protocol_version().write_bytes(&mut result)?; @@ -933,8 +1000,8 @@ impl ToBytes for AddressableEntity { fn serialized_length(&self) -> usize { ToBytes::serialized_length(&self.entry_points) - + ToBytes::serialized_length(&self.contract_package_hash) - + ToBytes::serialized_length(&self.contract_wasm_hash) + + ToBytes::serialized_length(&self.package_hash) + + ToBytes::serialized_length(&self.byte_code_hash) + ToBytes::serialized_length(&self.protocol_version) + ToBytes::serialized_length(&self.named_keys) + ToBytes::serialized_length(&self.main_purse) @@ -943,8 +1010,8 @@ impl ToBytes for AddressableEntity { } fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - self.contract_package_hash().write_bytes(writer)?; - self.contract_wasm_hash().write_bytes(writer)?; + self.package_hash().write_bytes(writer)?; + self.byte_code_hash().write_bytes(writer)?; self.named_keys().write_bytes(writer)?; self.entry_points().write_bytes(writer)?; self.protocol_version().write_bytes(writer)?; @@ -957,8 +1024,8 @@ impl ToBytes for AddressableEntity { impl FromBytes for AddressableEntity { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (contract_package_hash, bytes) = ContractPackageHash::from_bytes(bytes)?; - let (contract_wasm_hash, bytes) = ContractWasmHash::from_bytes(bytes)?; + let (package_hash, bytes) = PackageHash::from_bytes(bytes)?; + let (contract_wasm_hash, bytes) = ByteCodeHash::from_bytes(bytes)?; let (named_keys, bytes) = NamedKeys::from_bytes(bytes)?; let (entry_points, bytes) = EntryPoints::from_bytes(bytes)?; let (protocol_version, bytes) = ProtocolVersion::from_bytes(bytes)?; @@ -967,8 +1034,8 @@ impl FromBytes for AddressableEntity { let (action_thresholds, bytes) = ActionThresholds::from_bytes(bytes)?; Ok(( AddressableEntity { - contract_package_hash, - contract_wasm_hash, + package_hash, + byte_code_hash: contract_wasm_hash, named_keys, entry_points, protocol_version, @@ -986,8 +1053,8 @@ impl Default for AddressableEntity { AddressableEntity { named_keys: NamedKeys::new(), entry_points: EntryPoints::new_with_default_entry_point(), - contract_wasm_hash: [0; KEY_HASH_LENGTH].into(), - contract_package_hash: [0; KEY_HASH_LENGTH].into(), + byte_code_hash: [0; KEY_HASH_LENGTH].into(), + package_hash: [0; KEY_HASH_LENGTH].into(), protocol_version: ProtocolVersion::V1_0_0, main_purse: URef::default(), action_thresholds: ActionThresholds::default(), @@ -999,8 +1066,8 @@ impl Default for AddressableEntity { impl From for AddressableEntity { fn from(value: Contract) -> Self { AddressableEntity::new( - value.contract_package_hash(), - value.contract_wasm_hash(), + PackageHash::new(value.contract_package_hash().value()), + ByteCodeHash::new(value.contract_wasm_hash().value()), value.named_keys().clone(), value.entry_points().clone(), value.protocol_version(), @@ -1014,8 +1081,8 @@ impl From for AddressableEntity { impl From for AddressableEntity { fn from(value: Account) -> Self { AddressableEntity::new( - ContractPackageHash::default(), - ContractWasmHash::new([0u8; 32]), + PackageHash::default(), + ByteCodeHash::new([0u8; 32]), value.named_keys().clone(), EntryPoints::new(), ProtocolVersion::default(), @@ -1035,12 +1102,14 @@ impl From for AddressableEntity { #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] pub enum EntryPointType { - /// Runs as session code + /// Runs as session code (caller) + /// Deprecated, retained to allow read back of legacy stored session. Session = 0b00000000, - /// Runs within contract's context - Contract = 0b00000001, - /// Installer entry point. - Install = 0b10000000, + /// 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) + Factory = 0b10000000, } impl EntryPointType { @@ -1057,6 +1126,14 @@ impl EntryPointType { pub fn bits(self) -> u8 { self as u8 } + + /// 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, + } + } } impl ToBytes for EntryPointType { @@ -1391,57 +1468,58 @@ mod tests { use crate::{AccessRights, URef, UREF_ADDR_LENGTH}; #[test] - fn contract_hash_from_slice() { + fn entity_hash_from_slice() { let bytes: Vec = (0..32).collect(); - let contract_hash = HashAddr::try_from(&bytes[..]).expect("should create contract hash"); - let contract_hash = ContractHash::new(contract_hash); - assert_eq!(&bytes, &contract_hash.as_bytes()); + let entity_hash = HashAddr::try_from(&bytes[..]).expect("should create contract hash"); + let entity_hash = AddressableEntityHash::new(entity_hash); + assert_eq!(&bytes, &entity_hash.as_bytes()); } #[test] - fn contract_hash_from_str() { - let contract_hash = ContractHash([3; 32]); - let encoded = contract_hash.to_formatted_string(); - let decoded = ContractHash::from_formatted_str(&encoded).unwrap(); - assert_eq!(contract_hash, decoded); + fn entity_hash_from_str() { + let entity_hash = AddressableEntityHash([3; 32]); + let encoded = entity_hash.to_formatted_string(); + let decoded = AddressableEntityHash::from_formatted_str(&encoded).unwrap(); + assert_eq!(entity_hash, decoded); let invalid_prefix = - "contract--0000000000000000000000000000000000000000000000000000000000000000"; - assert!(ContractHash::from_formatted_str(invalid_prefix).is_err()); + "addressable-entity--0000000000000000000000000000000000000000000000000000000000000000"; + assert!(AddressableEntityHash::from_formatted_str(invalid_prefix).is_err()); - let short_addr = "contract-00000000000000000000000000000000000000000000000000000000000000"; - assert!(ContractHash::from_formatted_str(short_addr).is_err()); + let short_addr = + "addressable-entity-00000000000000000000000000000000000000000000000000000000000000"; + assert!(AddressableEntityHash::from_formatted_str(short_addr).is_err()); let long_addr = - "contract-000000000000000000000000000000000000000000000000000000000000000000"; - assert!(ContractHash::from_formatted_str(long_addr).is_err()); + "addressable-entity-000000000000000000000000000000000000000000000000000000000000000000"; + assert!(AddressableEntityHash::from_formatted_str(long_addr).is_err()); let invalid_hex = - "contract-000000000000000000000000000000000000000000000000000000000000000g"; - assert!(ContractHash::from_formatted_str(invalid_hex).is_err()); + "addressable-entity-000000000000000000000000000000000000000000000000000000000000000g"; + assert!(AddressableEntityHash::from_formatted_str(invalid_hex).is_err()); } #[test] - fn contract_hash_serde_roundtrip() { - let contract_hash = ContractHash([255; 32]); - let serialized = bincode::serialize(&contract_hash).unwrap(); + fn entity_hash_serde_roundtrip() { + let entity_hash = AddressableEntityHash([255; 32]); + let serialized = bincode::serialize(&entity_hash).unwrap(); let deserialized = bincode::deserialize(&serialized).unwrap(); - assert_eq!(contract_hash, deserialized) + assert_eq!(entity_hash, deserialized) } #[test] - fn contract_hash_json_roundtrip() { - let contract_hash = ContractHash([255; 32]); - let json_string = serde_json::to_string_pretty(&contract_hash).unwrap(); + fn entity_hash_json_roundtrip() { + let entity_hash = AddressableEntityHash([255; 32]); + let json_string = serde_json::to_string_pretty(&entity_hash).unwrap(); let decoded = serde_json::from_str(&json_string).unwrap(); - assert_eq!(contract_hash, decoded) + assert_eq!(entity_hash, decoded) } #[test] fn should_extract_access_rights() { const MAIN_PURSE: URef = URef::new([2; 32], AccessRights::READ_ADD_WRITE); - let contract_hash = ContractHash([255; 32]); + let entity_hash = AddressableEntityHash([255; 32]); let uref = URef::new([84; UREF_ADDR_LENGTH], AccessRights::READ_ADD); let uref_r = URef::new([42; UREF_ADDR_LENGTH], AccessRights::READ); let uref_a = URef::new([42; UREF_ADDR_LENGTH], AccessRights::ADD); @@ -1453,17 +1531,17 @@ mod tests { named_keys.insert("d".to_string(), Key::URef(uref)); let associated_keys = AssociatedKeys::new(AccountHash::new([254; 32]), Weight::new(1)); let contract = AddressableEntity::new( - ContractPackageHash::new([254; 32]), - ContractWasmHash::new([253; 32]), + PackageHash::new([254; 32]), + ByteCodeHash::new([253; 32]), named_keys, EntryPoints::new_with_default_entry_point(), ProtocolVersion::V1_0_0, MAIN_PURSE, associated_keys, - ActionThresholds::new(Weight::new(1), Weight::new(1)) + ActionThresholds::new(Weight::new(1), Weight::new(1), Weight::new(1)) .expect("should create thresholds"), ); - let access_rights = contract.extract_access_rights(contract_hash); + let access_rights = contract.extract_access_rights(entity_hash); let expected_uref = URef::new([42; UREF_ADDR_LENGTH], AccessRights::READ_ADD_WRITE); assert!( access_rights.has_access_rights_to_uref(&uref), diff --git a/types/src/addressable_entity/action_thresholds.rs b/types/src/addressable_entity/action_thresholds.rs index b833db6989..c944e47403 100644 --- a/types/src/addressable_entity/action_thresholds.rs +++ b/types/src/addressable_entity/action_thresholds.rs @@ -21,10 +21,10 @@ use crate::{ pub struct ActionThresholds { /// Threshold for deploy execution. pub deployment: Weight, + /// Threshold for upgrading contracts. + pub upgrade_management: Weight, /// Threshold for managing action threshold. pub key_management: Weight, - // !TODO add this action threshold and gate the ability to upgrade a contract behind it. - // pub upgrade_management: Weight, } impl ActionThresholds { @@ -34,6 +34,7 @@ impl ActionThresholds { /// key management threshold. pub fn new( deployment: Weight, + upgrade_management: Weight, key_management: Weight, ) -> Result { if deployment > key_management { @@ -41,6 +42,7 @@ impl ActionThresholds { } Ok(ActionThresholds { deployment, + upgrade_management, key_management, }) } @@ -75,6 +77,15 @@ impl ActionThresholds { } } + /// Sets new threshold for [ActionType::UpgradeManagement]. + pub fn set_upgrade_management_threshold( + &mut self, + upgrade_management: Weight, + ) -> Result<(), SetThresholdFailure> { + self.upgrade_management = upgrade_management; + Ok(()) + } + /// Returns the deployment action threshold. pub fn deployment(&self) -> &Weight { &self.deployment @@ -85,6 +96,11 @@ impl ActionThresholds { &self.key_management } + /// Returns the upgrade management action threshold. + pub fn upgrade_management(&self) -> &Weight { + &self.upgrade_management + } + /// Unified function that takes an action type, and changes appropriate /// threshold defined by the [ActionType] variants. pub fn set_threshold( @@ -95,6 +111,7 @@ impl ActionThresholds { match action_type { ActionType::Deployment => self.set_deployment_threshold(new_threshold), ActionType::KeyManagement => self.set_key_management_threshold(new_threshold), + ActionType::UpgradeManagement => self.set_upgrade_management_threshold(new_threshold), } } } @@ -103,6 +120,7 @@ impl Default for ActionThresholds { fn default() -> Self { ActionThresholds { deployment: Weight::new(1), + upgrade_management: Weight::new(1), key_management: Weight::new(1), } } @@ -113,6 +131,7 @@ impl From for ActionThresholds { Self { deployment: Weight::new(value.deployment.value()), key_management: Weight::new(value.key_management.value()), + upgrade_management: Weight::new(1), } } } @@ -121,16 +140,18 @@ impl ToBytes for ActionThresholds { fn to_bytes(&self) -> Result, Error> { let mut result = bytesrepr::unchecked_allocate_buffer(self); result.append(&mut self.deployment.to_bytes()?); + result.append(&mut self.upgrade_management.to_bytes()?); result.append(&mut self.key_management.to_bytes()?); Ok(result) } fn serialized_length(&self) -> usize { - 2 * WEIGHT_SERIALIZED_LENGTH + 3 * WEIGHT_SERIALIZED_LENGTH } fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { self.deployment().write_bytes(writer)?; + self.upgrade_management().write_bytes(writer)?; self.key_management().write_bytes(writer)?; Ok(()) } @@ -139,9 +160,11 @@ impl ToBytes for ActionThresholds { impl FromBytes for ActionThresholds { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> { let (deployment, rem) = Weight::from_bytes(bytes)?; + let (upgrade_management, rem) = Weight::from_bytes(rem)?; let (key_management, rem) = Weight::from_bytes(rem)?; let ret = ActionThresholds { deployment, + upgrade_management, key_management, }; Ok((ret, rem)) @@ -166,20 +189,23 @@ mod tests { #[test] fn should_create_new_action_thresholds() { - let action_thresholds = ActionThresholds::new(Weight::new(1), Weight::new(42)).unwrap(); + let action_thresholds = + ActionThresholds::new(Weight::new(1), Weight::new(1), Weight::new(42)).unwrap(); assert_eq!(*action_thresholds.deployment(), Weight::new(1)); + assert_eq!(*action_thresholds.upgrade_management(), Weight::new(1)); assert_eq!(*action_thresholds.key_management(), Weight::new(42)); } #[test] fn should_not_create_action_thresholds_with_invalid_deployment_threshold() { // deployment cant be greater than key management - assert!(ActionThresholds::new(Weight::new(5), Weight::new(1)).is_err()); + assert!(ActionThresholds::new(Weight::new(5), Weight::new(1), Weight::new(1)).is_err()); } #[test] fn serialization_roundtrip() { - let action_thresholds = ActionThresholds::new(Weight::new(1), Weight::new(42)).unwrap(); + let action_thresholds = + ActionThresholds::new(Weight::new(1), Weight::new(1), Weight::new(42)).unwrap(); bytesrepr::test_serialization_roundtrip(&action_thresholds); } } diff --git a/types/src/addressable_entity/action_type.rs b/types/src/addressable_entity/action_type.rs index 2a4862a5af..2a627309ba 100644 --- a/types/src/addressable_entity/action_type.rs +++ b/types/src/addressable_entity/action_type.rs @@ -12,6 +12,11 @@ pub enum ActionType { /// [`Weight`](super::Weight)s of signing [`AccountHash`](super::AccountHash)s required to /// perform various actions). KeyManagement = 1, + /// Represents changing the associated keys (i.e. map of [`AccountHash`](super::AccountHash)s + /// to [`Weight`](super::Weight)s) or action thresholds (i.e. the total + /// [`Weight`](super::Weight)s of signing [`AccountHash`](super::AccountHash)s required to + /// upgrade the addressable entity. + UpgradeManagement = 2, } // This conversion is not intended to be used by third party crates. @@ -26,6 +31,7 @@ impl TryFrom for ActionType { match value { d if d == ActionType::Deployment as u32 => Ok(ActionType::Deployment), d if d == ActionType::KeyManagement as u32 => Ok(ActionType::KeyManagement), + d if d == ActionType::UpgradeManagement as u32 => Ok(ActionType::UpgradeManagement), _ => Err(TryFromIntError(())), } } diff --git a/types/src/api_error.rs b/types/src/api_error.rs index 75bb0db216..d7de342b99 100644 --- a/types/src/api_error.rs +++ b/types/src/api_error.rs @@ -278,7 +278,7 @@ pub enum ApiError { /// assert_eq!(ApiError::from(28), ApiError::InsufficientTotalWeight); /// ``` InsufficientTotalWeight, - /// The given `u32` doesn't map to a [`SystemContractType`](crate::system::SystemContractType). + /// The given `u32` doesn't map to a [`SystemContractType`](crate::system::SystemEntityType). /// ``` /// # use casper_types::ApiError; /// assert_eq!(ApiError::from(29), ApiError::InvalidSystemContract); diff --git a/types/src/byte_code.rs b/types/src/byte_code.rs new file mode 100644 index 0000000000..700e7cdade --- /dev/null +++ b/types/src/byte_code.rs @@ -0,0 +1,441 @@ +use alloc::{format, string::String, vec::Vec}; +use core::{ + array::TryFromSliceError, + convert::TryFrom, + fmt::{self, Debug, 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::{gen::SchemaGenerator, schema::Schema, JsonSchema}; +use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer}; + +use crate::{ + addressable_entity, bytesrepr, + bytesrepr::{Bytes, Error, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, + checksummed_hex, + key::ByteCodeAddr, + uref, CLType, CLTyped, +}; + +const BYTE_CODE_MAX_DISPLAY_LEN: usize = 16; +const KEY_HASH_LENGTH: usize = 32; +const WASM_STRING_PREFIX: &str = "contract-wasm-"; + +/// Associated error type of `TryFrom<&[u8]>` for `ByteCodeHash`. +#[derive(Debug)] +pub struct TryFromSliceForContractHashError(()); + +#[derive(Debug)] +#[non_exhaustive] +pub enum FromStrError { + InvalidPrefix, + Hex(base16::DecodeError), + Hash(TryFromSliceError), + AccountHash(addressable_entity::FromAccountHashStrError), + URef(uref::FromStrError), +} + +impl From for FromStrError { + fn from(error: base16::DecodeError) -> Self { + FromStrError::Hex(error) + } +} + +impl From for FromStrError { + fn from(error: TryFromSliceError) -> Self { + FromStrError::Hash(error) + } +} + +impl From for FromStrError { + fn from(error: addressable_entity::FromAccountHashStrError) -> Self { + FromStrError::AccountHash(error) + } +} + +impl From for FromStrError { + fn from(error: uref::FromStrError) -> Self { + FromStrError::URef(error) + } +} + +impl Display for FromStrError { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + FromStrError::InvalidPrefix => write!(f, "invalid prefix"), + FromStrError::Hex(error) => write!(f, "decode from hex: {}", error), + FromStrError::Hash(error) => write!(f, "hash from string error: {}", error), + FromStrError::AccountHash(error) => { + write!(f, "account hash from string error: {:?}", error) + } + FromStrError::URef(error) => write!(f, "uref from string error: {:?}", error), + } + } +} + +/// A newtype wrapping a `HashAddr` which is the raw bytes of +/// the ByteCodeHash +#[derive(Default, PartialOrd, Ord, PartialEq, Eq, Hash, Clone, Copy)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +pub struct ByteCodeHash(ByteCodeAddr); + +impl ByteCodeHash { + /// Constructs a new `ByteCodeHash` from the raw bytes of the contract wasm hash. + pub const fn new(value: ByteCodeAddr) -> ByteCodeHash { + ByteCodeHash(value) + } + + /// Returns the raw bytes of the contract hash as an array. + pub fn value(&self) -> ByteCodeAddr { + self.0 + } + + /// Returns the raw bytes of the contract hash as a `slice`. + pub fn as_bytes(&self) -> &[u8] { + &self.0 + } + + /// Formats the `ByteCodeHash` for users getting and putting. + pub fn to_formatted_string(self) -> String { + format!("{}{}", WASM_STRING_PREFIX, base16::encode_lower(&self.0),) + } + + /// Parses a string formatted as per `Self::to_formatted_string()` into a + /// `ByteCodeHash`. + pub fn from_formatted_str(input: &str) -> Result { + let remainder = input + .strip_prefix(WASM_STRING_PREFIX) + .ok_or(FromStrError::InvalidPrefix)?; + let bytes = ByteCodeAddr::try_from(checksummed_hex::decode(remainder)?.as_ref())?; + Ok(ByteCodeHash(bytes)) + } +} + +impl Display for ByteCodeHash { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", base16::encode_lower(&self.0)) + } +} + +impl Debug for ByteCodeHash { + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "ByteCodeHash({})", base16::encode_lower(&self.0)) + } +} + +impl CLTyped for ByteCodeHash { + fn cl_type() -> CLType { + CLType::ByteArray(KEY_HASH_LENGTH as u32) + } +} + +impl ToBytes for ByteCodeHash { + #[inline(always)] + fn to_bytes(&self) -> Result, 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<(), Error> { + self.0.write_bytes(writer)?; + Ok(()) + } +} + +impl FromBytes for ByteCodeHash { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> { + let (bytes, rem) = FromBytes::from_bytes(bytes)?; + Ok((ByteCodeHash::new(bytes), rem)) + } +} + +impl From<[u8; 32]> for ByteCodeHash { + fn from(bytes: [u8; 32]) -> Self { + ByteCodeHash(bytes) + } +} + +impl Serialize for ByteCodeHash { + 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 ByteCodeHash { + fn deserialize>(deserializer: D) -> Result { + if deserializer.is_human_readable() { + let formatted_string = String::deserialize(deserializer)?; + ByteCodeHash::from_formatted_str(&formatted_string).map_err(SerdeError::custom) + } else { + let bytes = ByteCodeAddr::deserialize(deserializer)?; + Ok(ByteCodeHash(bytes)) + } + } +} + +impl AsRef<[u8]> for ByteCodeHash { + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } +} + +impl TryFrom<&[u8]> for ByteCodeHash { + type Error = TryFromSliceForContractHashError; + + fn try_from(bytes: &[u8]) -> Result { + ByteCodeAddr::try_from(bytes) + .map(ByteCodeHash::new) + .map_err(|_| TryFromSliceForContractHashError(())) + } +} + +impl TryFrom<&Vec> for ByteCodeHash { + type Error = TryFromSliceForContractHashError; + + fn try_from(bytes: &Vec) -> Result { + ByteCodeAddr::try_from(bytes as &[u8]) + .map(ByteCodeHash::new) + .map_err(|_| TryFromSliceForContractHashError(())) + } +} + +#[cfg(feature = "json-schema")] +impl JsonSchema for ByteCodeHash { + fn schema_name() -> String { + String::from("ByteCodeHash") + } + + fn json_schema(gen: &mut SchemaGenerator) -> Schema { + let schema = gen.subschema_for::(); + let mut schema_object = schema.into_object(); + schema_object.metadata().description = + Some("The hash address of the contract wasm".to_string()); + schema_object.into() + } +} + +#[repr(u8)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +#[derive(PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash, Serialize, Deserialize)] +/// The type of Byte code. +pub enum ByteCodeKind { + /// Empty byte code. + Empty = 0, + /// Byte code to be executed with the V1 Casper execution engine. + V1CasperWasm = 1, +} + +impl TryFrom for ByteCodeKind { + type Error = Error; + + fn try_from(value: u8) -> Result { + match value { + 0 => Ok(ByteCodeKind::Empty), + 1 => Ok(ByteCodeKind::V1CasperWasm), + _ => Err(Error::Formatting), + } + } +} + +impl ToBytes for ByteCodeKind { + 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 { + U8_SERIALIZED_LENGTH + } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), Error> { + match self { + ByteCodeKind::Empty => 0u8.write_bytes(writer)?, + ByteCodeKind::V1CasperWasm => 1u8.write_bytes(writer)?, + } + Ok(()) + } +} + +#[cfg(any(feature = "testing", test))] +impl Distribution for Standard { + fn sample(&self, rng: &mut R) -> ByteCodeKind { + match rng.gen_range(0..=1) { + 0 => ByteCodeKind::Empty, + 1 => ByteCodeKind::V1CasperWasm, + _ => unreachable!(), + } + } +} + +/// A container for contract's WASM bytes. +#[derive(PartialEq, Eq, Clone, Serialize, Deserialize)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +pub struct ByteCode { + byte_code_kind: ByteCodeKind, + bytes: Bytes, +} + +impl Debug for ByteCode { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + if self.bytes.len() > BYTE_CODE_MAX_DISPLAY_LEN { + write!( + f, + "ByteCode(0x{}...)", + base16::encode_lower(&self.bytes[..BYTE_CODE_MAX_DISPLAY_LEN]) + ) + } else { + write!(f, "ByteCode(0x{})", base16::encode_lower(&self.bytes)) + } + } +} + +impl ByteCode { + /// Creates new WASM object from bytes. + pub fn new(byte_code_kind: ByteCodeKind, bytes: Vec) -> Self { + ByteCode { + byte_code_kind, + bytes: bytes.into(), + } + } + + /// Consumes instance of [`ByteCode`] and returns its bytes. + pub fn take_bytes(self) -> Vec { + self.bytes.into() + } + + /// Returns a slice of contained WASM bytes. + pub fn bytes(&self) -> &[u8] { + self.bytes.as_ref() + } + + /// Return the type of byte code. + pub fn byte_code_tag(&self) -> ByteCodeKind { + self.byte_code_kind + } +} + +impl ToBytes for ByteCode { + 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 { + self.byte_code_kind.serialized_length() + self.bytes.serialized_length() + } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), Error> { + self.byte_code_kind.write_bytes(writer)?; + self.bytes.write_bytes(writer)?; + Ok(()) + } +} + +impl FromBytes for ByteCode { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> { + let (byte_code_kind, remainder) = u8::from_bytes(bytes)?; + let (bytes, rem1) = FromBytes::from_bytes(remainder)?; + let byte_code_kind = ByteCodeKind::try_from(byte_code_kind)?; + Ok(( + ByteCode { + byte_code_kind, + bytes, + }, + rem1, + )) + } +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_debug_repr_of_short_wasm() { + const SIZE: usize = 8; + let wasm_bytes = vec![0; SIZE]; + let byte_code = ByteCode::new(ByteCodeKind::V1CasperWasm, wasm_bytes); + // String output is less than the bytes itself + assert_eq!(format!("{:?}", byte_code), "ByteCode(0x0000000000000000)"); + } + + #[test] + fn test_debug_repr_of_long_wasm() { + const SIZE: usize = 65; + let wasm_bytes = vec![0; SIZE]; + let byte_code = ByteCode::new(ByteCodeKind::V1CasperWasm, wasm_bytes); + // String output is less than the bytes itself + assert_eq!( + format!("{:?}", byte_code), + "ByteCode(0x00000000000000000000000000000000...)" + ); + } + + #[test] + fn contract_wasm_hash_from_slice() { + let bytes: Vec = (0..32).collect(); + let byte_code_hash = + ByteCodeAddr::try_from(&bytes[..]).expect("should create byte code hash"); + let contract_hash = ByteCodeHash::new(byte_code_hash); + assert_eq!(&bytes, &contract_hash.as_bytes()); + } + + #[test] + fn contract_wasm_hash_from_str() { + let byte_code_hash = ByteCodeHash([3; 32]); + let encoded = byte_code_hash.to_formatted_string(); + let decoded = ByteCodeHash::from_formatted_str(&encoded).unwrap(); + assert_eq!(byte_code_hash, decoded); + + let invalid_prefix = + "contractwasm-0000000000000000000000000000000000000000000000000000000000000000"; + assert!(ByteCodeHash::from_formatted_str(invalid_prefix).is_err()); + + let short_addr = + "contract-wasm-00000000000000000000000000000000000000000000000000000000000000"; + assert!(ByteCodeHash::from_formatted_str(short_addr).is_err()); + + let long_addr = + "contract-wasm-000000000000000000000000000000000000000000000000000000000000000000"; + assert!(ByteCodeHash::from_formatted_str(long_addr).is_err()); + + let invalid_hex = + "contract-wasm-000000000000000000000000000000000000000000000000000000000000000g"; + assert!(ByteCodeHash::from_formatted_str(invalid_hex).is_err()); + } + + #[test] + fn contract_wasm_hash_serde_roundtrip() { + let byte_code_hash = ByteCodeHash([255; 32]); + let serialized = bincode::serialize(&byte_code_hash).unwrap(); + let deserialized = bincode::deserialize(&serialized).unwrap(); + assert_eq!(byte_code_hash, deserialized) + } + + #[test] + fn contract_wasm_hash_json_roundtrip() { + let byte_code_hash = ByteCodeHash([255; 32]); + let json_string = serde_json::to_string_pretty(&byte_code_hash).unwrap(); + let decoded = serde_json::from_str(&json_string).unwrap(); + assert_eq!(byte_code_hash, decoded) + } +} diff --git a/types/src/chainspec/vm_config/host_function_costs.rs b/types/src/chainspec/vm_config/host_function_costs.rs index 3037f4b53f..c08dc14e74 100644 --- a/types/src/chainspec/vm_config/host_function_costs.rs +++ b/types/src/chainspec/vm_config/host_function_costs.rs @@ -270,7 +270,7 @@ pub struct HostFunctionCosts { /// Cost of calling the `create_contract_user_group` host function. pub create_contract_user_group: HostFunction<[Cost; 8]>, /// Cost of calling the `add_contract_version` host function. - pub add_contract_version: HostFunction<[Cost; 10]>, + pub add_contract_version: HostFunction<[Cost; 9]>, /// Cost of calling the `disable_contract_version` host function. pub disable_contract_version: HostFunction<[Cost; 4]>, /// Cost of calling the `call_contract` host function. @@ -295,6 +295,8 @@ pub struct HostFunctionCosts { pub random_bytes: HostFunction<[Cost; 2]>, /// Cost of calling the `enable_contract_version` host function. pub enable_contract_version: HostFunction<[Cost; 4]>, + /// Cost of calling the `add_session_version` host function. + pub add_session_version: HostFunction<[Cost; 2]>, } impl Default for HostFunctionCosts { @@ -427,6 +429,7 @@ impl Default for HostFunctionCosts { blake2b: HostFunction::default(), random_bytes: HostFunction::default(), enable_contract_version: HostFunction::default(), + add_session_version: HostFunction::default(), } } } @@ -478,6 +481,7 @@ impl ToBytes for HostFunctionCosts { ret.append(&mut self.blake2b.to_bytes()?); ret.append(&mut self.random_bytes.to_bytes()?); ret.append(&mut self.enable_contract_version.to_bytes()?); + ret.append(&mut self.add_session_version.to_bytes()?); Ok(ret) } @@ -526,6 +530,7 @@ impl ToBytes for HostFunctionCosts { + self.blake2b.serialized_length() + self.random_bytes.serialized_length() + self.enable_contract_version.serialized_length() + + self.add_session_version.serialized_length() } } @@ -575,6 +580,7 @@ impl FromBytes for HostFunctionCosts { let (blake2b, rem) = FromBytes::from_bytes(rem)?; let (random_bytes, rem) = FromBytes::from_bytes(rem)?; let (enable_contract_version, rem) = FromBytes::from_bytes(rem)?; + let (add_session_version, rem) = FromBytes::from_bytes(rem)?; Ok(( HostFunctionCosts { read_value, @@ -621,6 +627,7 @@ impl FromBytes for HostFunctionCosts { blake2b, random_bytes, enable_contract_version, + add_session_version, }, rem, )) @@ -674,6 +681,7 @@ impl Distribution for Standard { blake2b: rng.gen(), random_bytes: rng.gen(), enable_contract_version: rng.gen(), + add_session_version: rng.gen(), } } } @@ -737,6 +745,7 @@ pub mod gens { blake2b in host_function_cost_arb(), random_bytes in host_function_cost_arb(), enable_contract_version in host_function_cost_arb(), + add_session_version in host_function_cost_arb(), ) -> HostFunctionCosts { HostFunctionCosts { read_value, @@ -783,6 +792,7 @@ pub mod gens { blake2b, random_bytes, enable_contract_version, + add_session_version } } } diff --git a/types/src/contract_wasm.rs b/types/src/contract_wasm.rs index 1b69aecd2b..57019cde40 100644 --- a/types/src/contract_wasm.rs +++ b/types/src/contract_wasm.rs @@ -12,12 +12,13 @@ use schemars::{gen::SchemaGenerator, schema::Schema, JsonSchema}; use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer}; use crate::{ - addressable_entity, + account, + addressable_entity::TryFromSliceForAccountHashError, bytesrepr::{Bytes, Error, FromBytes, ToBytes}, - checksummed_hex, uref, CLType, CLTyped, HashAddr, + checksummed_hex, uref, ByteCode, ByteCodeKind, CLType, CLTyped, HashAddr, }; -const BYTE_CODE_MAX_DISPLAY_LEN: usize = 16; +const CONTRACT_WASM_MAX_DISPLAY_LEN: usize = 16; const KEY_HASH_LENGTH: usize = 32; const WASM_STRING_PREFIX: &str = "contract-wasm-"; @@ -30,9 +31,9 @@ pub struct TryFromSliceForContractHashError(()); pub enum FromStrError { InvalidPrefix, Hex(base16::DecodeError), - // Account(TryFromSliceForAccountHashError), + Account(TryFromSliceForAccountHashError), Hash(TryFromSliceError), - AccountHash(addressable_entity::FromAccountHashStrError), + AccountHash(account::FromStrError), URef(uref::FromStrError), } @@ -42,14 +43,20 @@ impl From for FromStrError { } } +impl From for FromStrError { + fn from(error: TryFromSliceForAccountHashError) -> Self { + FromStrError::Account(error) + } +} + impl From for FromStrError { fn from(error: TryFromSliceError) -> Self { FromStrError::Hash(error) } } -impl From for FromStrError { - fn from(error: addressable_entity::FromAccountHashStrError) -> Self { +impl From for FromStrError { + fn from(error: account::FromStrError) -> Self { FromStrError::AccountHash(error) } } @@ -65,7 +72,7 @@ impl Display for FromStrError { match self { FromStrError::InvalidPrefix => write!(f, "invalid prefix"), FromStrError::Hex(error) => write!(f, "decode from hex: {}", error), - // FromStrError::Account(error) => write!(f, "account from string error: {:?}", error), + FromStrError::Account(error) => write!(f, "account from string error: {:?}", error), FromStrError::Hash(error) => write!(f, "hash from string error: {}", error), FromStrError::AccountHash(error) => { write!(f, "account hash from string error: {:?}", error) @@ -227,42 +234,36 @@ impl JsonSchema for ContractWasmHash { /// A container for contract's WASM bytes. #[derive(PartialEq, Eq, Clone, Serialize, Deserialize)] -#[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] +#[cfg_attr(feature = "datasize", derive(DataSize))] pub struct ContractWasm { bytes: Bytes, } -impl Debug for ContractWasm { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - if self.bytes.len() > BYTE_CODE_MAX_DISPLAY_LEN { - write!( - f, - "ContractWasm(0x{}...)", - base16::encode_lower(&self.bytes[..BYTE_CODE_MAX_DISPLAY_LEN]) - ) - } else { - write!(f, "ContractWasm(0x{})", base16::encode_lower(&self.bytes)) - } - } -} - impl ContractWasm { - /// Creates new WASM object from bytes. + #[cfg(test)] pub fn new(bytes: Vec) -> Self { - ContractWasm { + Self { bytes: bytes.into(), } } - /// Consumes instance of [`ContractWasm`] and returns its bytes. - pub fn take_bytes(self) -> Vec { + fn take_bytes(self) -> Vec { self.bytes.into() } +} - /// Returns a slice of contained WASM bytes. - pub fn bytes(&self) -> &[u8] { - self.bytes.as_ref() +impl Debug for ContractWasm { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + if self.bytes.len() > CONTRACT_WASM_MAX_DISPLAY_LEN { + write!( + f, + "ContractWasm(0x{}...)", + base16::encode_lower(&self.bytes[..CONTRACT_WASM_MAX_DISPLAY_LEN]) + ) + } else { + write!(f, "ContractWasm(0x{})", base16::encode_lower(&self.bytes)) + } } } @@ -288,6 +289,12 @@ impl FromBytes for ContractWasm { } } +impl From for ByteCode { + fn from(value: ContractWasm) -> Self { + ByteCode::new(ByteCodeKind::V1CasperWasm, value.take_bytes()) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/types/src/contracts.rs b/types/src/contracts.rs index bf72892366..e09d902e8d 100644 --- a/types/src/contracts.rs +++ b/types/src/contracts.rs @@ -1,21 +1,36 @@ //! Data types for supporting contract headers feature. -use alloc::vec::Vec; +// TODO - remove once schemars stops causing warning. +#![allow(clippy::field_reassign_with_default)] + +use alloc::{ + collections::{BTreeMap, BTreeSet}, + format, + string::String, + vec::Vec, +}; use core::{ + array::TryFromSliceError, convert::TryFrom, fmt::{self, Debug, Display, Formatter}, }; + #[cfg(feature = "datasize")] use datasize::DataSize; - #[cfg(feature = "json-schema")] -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +use schemars::{gen::SchemaGenerator, schema::Schema, JsonSchema}; +use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer}; use crate::{ - addressable_entity::{EntryPoint, NamedKeys}, + account, + addressable_entity::{NamedKeys, TryFromSliceForAccountHashError}, bytesrepr::{self, FromBytes, ToBytes, U32_SERIALIZED_LENGTH}, + checksummed_hex, contract_wasm::ContractWasmHash, - ContractPackageHash, EntryPoints, ProtocolVersion, KEY_HASH_LENGTH, + package::{PackageKind, PackageStatus}, + uref, + uref::URef, + AddressableEntityHash, CLType, CLTyped, EntityVersionKey, EntryPoint, EntryPoints, Groups, + HashAddr, Key, Package, ProtocolVersion, KEY_HASH_LENGTH, }; /// Maximum number of distinct user groups. @@ -23,6 +38,11 @@ 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". +const PACKAGE_STRING_LEGACY_EXTRA_PREFIX: &str = "wasm"; + /// Set of errors which may happen when working with contract headers. #[derive(Debug, PartialEq, Eq)] #[repr(u8)] @@ -120,6 +140,69 @@ impl Display for TryFromSliceForContractHashError { } } +/// An error from parsing a formatted contract string +#[derive(Debug)] +#[non_exhaustive] +pub enum FromStrError { + /// Invalid formatted string prefix. + InvalidPrefix, + /// Error when decoding a hex string + Hex(base16::DecodeError), + /// Error when parsing an account + Account(TryFromSliceForAccountHashError), + /// Error when parsing the hash. + Hash(TryFromSliceError), + /// Error when parsing an account hash. + AccountHash(account::FromStrError), + /// Error when parsing an uref. + URef(uref::FromStrError), +} + +impl From for FromStrError { + fn from(error: base16::DecodeError) -> Self { + FromStrError::Hex(error) + } +} + +impl From for FromStrError { + fn from(error: TryFromSliceForAccountHashError) -> Self { + FromStrError::Account(error) + } +} + +impl From for FromStrError { + fn from(error: TryFromSliceError) -> Self { + FromStrError::Hash(error) + } +} + +impl From for FromStrError { + fn from(error: account::FromStrError) -> Self { + FromStrError::AccountHash(error) + } +} + +impl From for FromStrError { + fn from(error: uref::FromStrError) -> Self { + FromStrError::URef(error) + } +} + +impl Display for FromStrError { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + FromStrError::InvalidPrefix => write!(f, "invalid prefix"), + FromStrError::Hex(error) => write!(f, "decode from hex: {}", error), + FromStrError::Account(error) => write!(f, "account from string error: {:?}", error), + FromStrError::Hash(error) => write!(f, "hash from string error: {}", error), + FromStrError::AccountHash(error) => { + write!(f, "account hash from string error: {:?}", error) + } + FromStrError::URef(error) => write!(f, "uref from string error: {:?}", error), + } + } +} + /// Automatically incremented value for a contract version within a major `ProtocolVersion`. pub type ContractVersion = u32; @@ -129,10 +212,654 @@ pub const CONTRACT_INITIAL_VERSION: ContractVersion = 1; /// Major element of `ProtocolVersion` a `ContractVersion` is compatible with. pub type ProtocolVersionMajor = u32; +/// Major element of `ProtocolVersion` combined with `ContractVersion`. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +#[cfg_attr(feature = "datasize", derive(DataSize))] +pub struct ContractVersionKey(ProtocolVersionMajor, ContractVersion); + +impl ContractVersionKey { + /// Returns a new instance of ContractVersionKey with provided values. + pub fn new( + protocol_version_major: ProtocolVersionMajor, + contract_version: ContractVersion, + ) -> Self { + Self(protocol_version_major, contract_version) + } + + /// Returns the major element of the protocol version this contract is compatible with. + pub fn protocol_version_major(self) -> ProtocolVersionMajor { + self.0 + } + + /// Returns the contract version within the protocol major version. + pub fn contract_version(self) -> ContractVersion { + self.1 + } +} + +impl From for (ProtocolVersionMajor, ContractVersion) { + fn from(contract_version_key: ContractVersionKey) -> Self { + (contract_version_key.0, contract_version_key.1) + } +} + /// Serialized length of `ContractVersionKey`. pub const CONTRACT_VERSION_KEY_SERIALIZED_LENGTH: usize = U32_SERIALIZED_LENGTH + U32_SERIALIZED_LENGTH; +impl ToBytes for ContractVersionKey { + fn to_bytes(&self) -> Result, bytesrepr::Error> { + let mut ret = bytesrepr::unchecked_allocate_buffer(self); + ret.append(&mut self.0.to_bytes()?); + ret.append(&mut self.1.to_bytes()?); + Ok(ret) + } + + fn serialized_length(&self) -> usize { + CONTRACT_VERSION_KEY_SERIALIZED_LENGTH + } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + self.0.write_bytes(writer)?; + self.1.write_bytes(writer)?; + Ok(()) + } +} + +impl FromBytes for ContractVersionKey { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (major, rem): (u32, &[u8]) = FromBytes::from_bytes(bytes)?; + let (contract, rem): (ContractVersion, &[u8]) = FromBytes::from_bytes(rem)?; + Ok((ContractVersionKey::new(major, contract), rem)) + } +} + +impl fmt::Display for ContractVersionKey { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}.{}", self.0, self.1) + } +} + +/// Collection of contract versions. +pub type ContractVersions = BTreeMap; + +/// Collection of disabled contract versions. The runtime will not permit disabled +/// contract versions to be executed. +pub type DisabledVersions = BTreeSet; + +/// A newtype wrapping a `HashAddr` which references a [`Contract`] in the global state. +#[derive(Default, PartialOrd, Ord, PartialEq, Eq, Hash, Clone, Copy)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +pub struct ContractHash(HashAddr); + +impl ContractHash { + /// Constructs a new `ContractHash` from the raw bytes of the contract hash. + pub const fn new(value: HashAddr) -> ContractHash { + ContractHash(value) + } + + /// Returns the raw bytes of the contract hash as an array. + pub fn value(&self) -> HashAddr { + self.0 + } + + /// Returns the raw bytes of the contract hash as a `slice`. + pub fn as_bytes(&self) -> &[u8] { + &self.0 + } + + /// Formats the `ContractHash` for users getting and putting. + pub fn to_formatted_string(self) -> String { + format!( + "{}{}", + CONTRACT_STRING_PREFIX, + base16::encode_lower(&self.0), + ) + } + + /// Parses a string formatted as per `Self::to_formatted_string()` into a + /// `ContractHash`. + pub fn from_formatted_str(input: &str) -> Result { + let remainder = input + .strip_prefix(CONTRACT_STRING_PREFIX) + .ok_or(FromStrError::InvalidPrefix)?; + let bytes = HashAddr::try_from(checksummed_hex::decode(remainder)?.as_ref())?; + Ok(ContractHash(bytes)) + } +} + +impl Display for ContractHash { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", base16::encode_lower(&self.0)) + } +} + +impl Debug for ContractHash { + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "ContractHash({})", base16::encode_lower(&self.0)) + } +} + +impl CLTyped for ContractHash { + fn cl_type() -> CLType { + CLType::ByteArray(KEY_HASH_LENGTH as u32) + } +} + +impl ToBytes for ContractHash { + #[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> { + writer.extend_from_slice(&self.0); + Ok(()) + } +} + +impl FromBytes for ContractHash { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (bytes, rem) = FromBytes::from_bytes(bytes)?; + Ok((ContractHash::new(bytes), rem)) + } +} + +impl From<[u8; 32]> for ContractHash { + fn from(bytes: [u8; 32]) -> Self { + ContractHash(bytes) + } +} + +impl Serialize for ContractHash { + 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 ContractHash { + fn deserialize>(deserializer: D) -> Result { + if deserializer.is_human_readable() { + let formatted_string = String::deserialize(deserializer)?; + ContractHash::from_formatted_str(&formatted_string).map_err(SerdeError::custom) + } else { + let bytes = HashAddr::deserialize(deserializer)?; + Ok(ContractHash(bytes)) + } + } +} + +impl AsRef<[u8]> for ContractHash { + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } +} + +impl TryFrom<&[u8]> for ContractHash { + type Error = TryFromSliceForContractHashError; + + fn try_from(bytes: &[u8]) -> Result { + HashAddr::try_from(bytes) + .map(ContractHash::new) + .map_err(|_| TryFromSliceForContractHashError(())) + } +} + +impl TryFrom<&Vec> for ContractHash { + type Error = TryFromSliceForContractHashError; + + fn try_from(bytes: &Vec) -> Result { + HashAddr::try_from(bytes as &[u8]) + .map(ContractHash::new) + .map_err(|_| TryFromSliceForContractHashError(())) + } +} + +#[cfg(feature = "json-schema")] +impl JsonSchema for ContractHash { + fn schema_name() -> String { + String::from("ContractHash") + } + + fn json_schema(gen: &mut SchemaGenerator) -> Schema { + let schema = gen.subschema_for::(); + let mut schema_object = schema.into_object(); + schema_object.metadata().description = Some("The hash address of the contract".to_string()); + schema_object.into() + } +} + +/// A newtype wrapping a `HashAddr` which references a [`ContractPackage`] in the global state. +#[derive(Default, PartialOrd, Ord, PartialEq, Eq, Hash, Clone, Copy)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +pub struct ContractPackageHash(HashAddr); + +impl ContractPackageHash { + /// Constructs a new `ContractPackageHash` from the raw bytes of the contract package hash. + pub const fn new(value: HashAddr) -> ContractPackageHash { + ContractPackageHash(value) + } + + /// Returns the raw bytes of the contract hash as an array. + pub fn value(&self) -> HashAddr { + self.0 + } + + /// Returns the raw bytes of the contract hash as a `slice`. + pub fn as_bytes(&self) -> &[u8] { + &self.0 + } + + /// Formats the `ContractPackageHash` for users getting and putting. + pub fn to_formatted_string(self) -> String { + format!("{}{}", PACKAGE_STRING_PREFIX, base16::encode_lower(&self.0),) + } + + /// Parses a string formatted as per `Self::to_formatted_string()` into a + /// `ContractPackageHash`. + pub fn from_formatted_str(input: &str) -> Result { + let remainder = input + .strip_prefix(PACKAGE_STRING_PREFIX) + .ok_or(FromStrError::InvalidPrefix)?; + + let hex_addr = remainder + .strip_prefix(PACKAGE_STRING_LEGACY_EXTRA_PREFIX) + .unwrap_or(remainder); + + let bytes = HashAddr::try_from(checksummed_hex::decode(hex_addr)?.as_ref())?; + Ok(ContractPackageHash(bytes)) + } +} + +impl Display for ContractPackageHash { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", base16::encode_lower(&self.0)) + } +} + +impl Debug for ContractPackageHash { + fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { + write!(f, "ContractPackageHash({})", base16::encode_lower(&self.0)) + } +} + +impl CLTyped for ContractPackageHash { + fn cl_type() -> CLType { + CLType::ByteArray(KEY_HASH_LENGTH as u32) + } +} + +impl ToBytes for ContractPackageHash { + #[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> { + writer.extend_from_slice(&self.0); + Ok(()) + } +} + +impl FromBytes for ContractPackageHash { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (bytes, rem) = FromBytes::from_bytes(bytes)?; + Ok((ContractPackageHash::new(bytes), rem)) + } +} + +impl From<[u8; 32]> for ContractPackageHash { + fn from(bytes: [u8; 32]) -> Self { + ContractPackageHash(bytes) + } +} + +impl Serialize for ContractPackageHash { + 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 ContractPackageHash { + fn deserialize>(deserializer: D) -> Result { + if deserializer.is_human_readable() { + let formatted_string = String::deserialize(deserializer)?; + ContractPackageHash::from_formatted_str(&formatted_string).map_err(SerdeError::custom) + } else { + let bytes = HashAddr::deserialize(deserializer)?; + Ok(ContractPackageHash(bytes)) + } + } +} + +impl AsRef<[u8]> for ContractPackageHash { + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } +} + +impl TryFrom<&[u8]> for ContractPackageHash { + type Error = TryFromSliceForContractHashError; + + fn try_from(bytes: &[u8]) -> Result { + HashAddr::try_from(bytes) + .map(ContractPackageHash::new) + .map_err(|_| TryFromSliceForContractHashError(())) + } +} + +impl TryFrom<&Vec> for ContractPackageHash { + type Error = TryFromSliceForContractHashError; + + fn try_from(bytes: &Vec) -> Result { + HashAddr::try_from(bytes as &[u8]) + .map(ContractPackageHash::new) + .map_err(|_| TryFromSliceForContractHashError(())) + } +} + +#[cfg(feature = "json-schema")] +impl JsonSchema for ContractPackageHash { + fn schema_name() -> String { + String::from("ContractPackageHash") + } + + fn json_schema(gen: &mut SchemaGenerator) -> Schema { + let schema = gen.subschema_for::(); + let mut schema_object = schema.into_object(); + schema_object.metadata().description = + Some("The hash address of the contract package".to_string()); + schema_object.into() + } +} + +/// A enum to determine the lock status of the contract package. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +pub enum ContractPackageStatus { + /// The package is locked and cannot be versioned. + Locked, + /// The package is unlocked and can be versioned. + Unlocked, +} + +impl ContractPackageStatus { + /// Create a new status flag based on a boolean value + pub fn new(is_locked: bool) -> Self { + if is_locked { + ContractPackageStatus::Locked + } else { + ContractPackageStatus::Unlocked + } + } +} + +impl Default for ContractPackageStatus { + fn default() -> Self { + Self::Unlocked + } +} + +impl ToBytes for ContractPackageStatus { + fn to_bytes(&self) -> Result, bytesrepr::Error> { + let mut result = bytesrepr::allocate_buffer(self)?; + match self { + ContractPackageStatus::Unlocked => result.append(&mut false.to_bytes()?), + ContractPackageStatus::Locked => result.append(&mut true.to_bytes()?), + } + Ok(result) + } + + fn serialized_length(&self) -> usize { + match self { + ContractPackageStatus::Unlocked => false.serialized_length(), + ContractPackageStatus::Locked => true.serialized_length(), + } + } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + match self { + ContractPackageStatus::Locked => writer.push(u8::from(true)), + ContractPackageStatus::Unlocked => writer.push(u8::from(false)), + } + Ok(()) + } +} + +impl FromBytes for ContractPackageStatus { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (val, bytes) = bool::from_bytes(bytes)?; + let status = ContractPackageStatus::new(val); + Ok((status, bytes)) + } +} + +/// Contract definition, metadata, and security container. +#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +#[cfg_attr(feature = "datasize", derive(DataSize))] +pub struct ContractPackage { + /// Key used to add or disable versions + access_key: URef, + /// All versions (enabled & disabled) + versions: ContractVersions, + /// Disabled versions + disabled_versions: DisabledVersions, + /// Mapping maintaining the set of URefs associated with each "user + /// group". This can be used to control access to methods in a particular + /// version of the contract. A method is callable by any context which + /// "knows" any of the URefs associated with the method's user group. + groups: Groups, + /// A flag that determines whether a contract is locked + lock_status: ContractPackageStatus, +} + +impl CLTyped for ContractPackage { + fn cl_type() -> CLType { + CLType::Any + } +} + +impl ContractPackage { + /// Create new `ContractPackage` (with no versions) from given access key. + pub fn new( + access_key: URef, + versions: ContractVersions, + disabled_versions: DisabledVersions, + groups: Groups, + lock_status: ContractPackageStatus, + ) -> Self { + ContractPackage { + access_key, + versions, + disabled_versions, + groups, + lock_status, + } + } + + /// Get the access key for this contract. + pub fn access_key(&self) -> URef { + self.access_key + } + + /// Get the group definitions for this contract. + pub fn groups(&self) -> &Groups { + &self.groups + } + + /// Returns reference to all of this contract's versions. + pub fn versions(&self) -> &ContractVersions { + &self.versions + } + + /// Returns mutable reference to all of this contract's versions (enabled and disabled). + pub fn versions_mut(&mut self) -> &mut ContractVersions { + &mut self.versions + } + + /// Consumes the object and returns all of this contract's versions (enabled and disabled). + pub fn take_versions(self) -> ContractVersions { + self.versions + } + + /// Returns all of this contract's disabled versions. + pub fn disabled_versions(&self) -> &DisabledVersions { + &self.disabled_versions + } + + /// Returns mut reference to all of this contract's disabled versions. + pub fn disabled_versions_mut(&mut self) -> &mut DisabledVersions { + &mut self.disabled_versions + } + + #[cfg(test)] + fn next_contract_version_for(&self, protocol_version: ProtocolVersionMajor) -> ContractVersion { + let current_version = self + .versions + .keys() + .rev() + .find_map(|&contract_version_key| { + if contract_version_key.protocol_version_major() == protocol_version { + Some(contract_version_key.contract_version()) + } else { + None + } + }) + .unwrap_or(0); + + current_version + 1 + } + + #[cfg(test)] + fn insert_contract_version( + &mut self, + protocol_version_major: ProtocolVersionMajor, + contract_hash: ContractHash, + ) -> ContractVersionKey { + let contract_version = self.next_contract_version_for(protocol_version_major); + let key = ContractVersionKey::new(protocol_version_major, contract_version); + self.versions.insert(key, contract_hash); + key + } + + #[cfg(test)] + fn groups_mut(&mut self) -> &mut Groups { + &mut self.groups + } +} + +impl ToBytes for ContractPackage { + fn to_bytes(&self) -> Result, bytesrepr::Error> { + let mut result = bytesrepr::allocate_buffer(self)?; + self.access_key().write_bytes(&mut result)?; + self.versions().write_bytes(&mut result)?; + self.disabled_versions().write_bytes(&mut result)?; + self.groups().write_bytes(&mut result)?; + self.lock_status.write_bytes(&mut result)?; + Ok(result) + } + + fn serialized_length(&self) -> usize { + self.access_key.serialized_length() + + self.versions.serialized_length() + + self.disabled_versions.serialized_length() + + self.groups.serialized_length() + + self.lock_status.serialized_length() + } + + fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { + self.access_key().write_bytes(writer)?; + self.versions().write_bytes(writer)?; + self.disabled_versions().write_bytes(writer)?; + self.groups().write_bytes(writer)?; + self.lock_status.write_bytes(writer)?; + Ok(()) + } +} + +impl FromBytes for ContractPackage { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (access_key, bytes) = URef::from_bytes(bytes)?; + let (versions, bytes) = ContractVersions::from_bytes(bytes)?; + let (disabled_versions, bytes) = DisabledVersions::from_bytes(bytes)?; + let (groups, bytes) = Groups::from_bytes(bytes)?; + let (lock_status, bytes) = ContractPackageStatus::from_bytes(bytes)?; + let result = ContractPackage { + access_key, + versions, + disabled_versions, + groups, + lock_status, + }; + + Ok((result, bytes)) + } +} + +impl From for Package { + fn from(value: ContractPackage) -> Self { + let versions: BTreeMap = value + .versions + .into_iter() + .map(|(version, contract_hash)| { + let entity_version = EntityVersionKey::new(2, version.contract_version()); + let entity_hash: AddressableEntityHash = + AddressableEntityHash::new(contract_hash.value()); + (entity_version, entity_hash) + }) + .collect(); + + let disabled_versions = value + .disabled_versions + .into_iter() + .map(|contract_versions| { + EntityVersionKey::new( + contract_versions.protocol_version_major(), + contract_versions.contract_version(), + ) + }) + .collect(); + + let lock_status = if value.lock_status == ContractPackageStatus::Locked { + PackageStatus::Locked + } else { + PackageStatus::Unlocked + }; + + Package::new( + value.access_key, + versions.into(), + disabled_versions, + value.groups, + lock_status, + PackageKind::SmartContract, + ) + } +} + /// Methods and type signatures supported by a contract. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "datasize", derive(DataSize))] @@ -145,6 +872,26 @@ pub struct Contract { protocol_version: ProtocolVersion, } +impl From + for ( + ContractPackageHash, + ContractWasmHash, + NamedKeys, + EntryPoints, + ProtocolVersion, + ) +{ + fn from(contract: Contract) -> Self { + ( + contract.contract_package_hash, + contract.contract_wasm_hash, + contract.named_keys, + contract.entry_points, + contract.protocol_version, + ) + } +} + impl Contract { /// `Contract` constructor. pub fn new( @@ -188,14 +935,14 @@ impl Contract { self.protocol_version } - /// Appends new named keys. - pub fn append_named_keys(&mut self, named_keys: NamedKeys) { - self.named_keys.append(named_keys) + /// Adds new entry point + pub fn add_entry_point>(&mut self, entry_point: EntryPoint) { + self.entry_points.add_entry_point(entry_point); } - /// Returns a reference to `named_keys` - pub fn named_keys(&self) -> &NamedKeys { - &self.named_keys + /// Hash for accessing contract bytes + pub fn contract_wasm_key(&self) -> Key { + self.contract_wasm_hash.into() } /// Returns immutable reference to methods @@ -203,20 +950,45 @@ impl Contract { &self.entry_points } + /// Takes `named_keys` + pub fn take_named_keys(self) -> NamedKeys { + self.named_keys + } + + /// Returns a reference to `named_keys` + pub fn named_keys(&self) -> &NamedKeys { + &self.named_keys + } + + /// Appends `keys` to `named_keys` + pub fn named_keys_append(&mut self, keys: NamedKeys) { + self.named_keys.append(keys); + } + + /// Removes given named key. + pub fn remove_named_key(&mut self, key: &str) -> Option { + self.named_keys.remove(key) + } + /// Set protocol_version. pub fn set_protocol_version(&mut self, protocol_version: ProtocolVersion) { self.protocol_version = protocol_version; } + + /// Determines if `Contract` is compatible with a given `ProtocolVersion`. + pub fn is_compatible_protocol_version(&self, protocol_version: ProtocolVersion) -> bool { + self.protocol_version.value().major == protocol_version.value().major + } } impl ToBytes for Contract { fn to_bytes(&self) -> Result, bytesrepr::Error> { let mut result = bytesrepr::allocate_buffer(self)?; - self.contract_package_hash.write_bytes(&mut result)?; - self.contract_wasm_hash.write_bytes(&mut result)?; - self.named_keys.write_bytes(&mut result)?; - self.entry_points.write_bytes(&mut result)?; - self.protocol_version.write_bytes(&mut result)?; + self.contract_package_hash().write_bytes(&mut result)?; + self.contract_wasm_hash().write_bytes(&mut result)?; + self.named_keys().write_bytes(&mut result)?; + self.entry_points().write_bytes(&mut result)?; + self.protocol_version().write_bytes(&mut result)?; Ok(result) } @@ -229,11 +1001,11 @@ impl ToBytes for Contract { } fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { - self.contract_package_hash.write_bytes(writer)?; - self.contract_wasm_hash.write_bytes(writer)?; - self.named_keys.write_bytes(writer)?; - self.entry_points.write_bytes(writer)?; - self.protocol_version.write_bytes(writer)?; + self.contract_package_hash().write_bytes(writer)?; + self.contract_wasm_hash().write_bytes(writer)?; + self.named_keys().write_bytes(writer)?; + self.entry_points().write_bytes(writer)?; + self.protocol_version().write_bytes(writer)?; Ok(()) } } @@ -261,11 +1033,276 @@ impl FromBytes for Contract { impl Default for Contract { fn default() -> Self { Contract { - named_keys: NamedKeys::new(), - entry_points: EntryPoints::new_with_default_entry_point(), + named_keys: NamedKeys::default(), + entry_points: EntryPoints::default(), contract_wasm_hash: [0; KEY_HASH_LENGTH].into(), contract_package_hash: [0; KEY_HASH_LENGTH].into(), protocol_version: ProtocolVersion::V1_0_0, } } } + +/// Default name for an entry point +pub const DEFAULT_ENTRY_POINT_NAME: &str = "call"; + +/// Default name for an installer entry point +pub const ENTRY_POINT_NAME_INSTALL: &str = "install"; + +/// Default name for an upgrade entry point +pub const UPGRADE_ENTRY_POINT_NAME: &str = "upgrade"; + +#[cfg(test)] +mod tests { + + use super::*; + use crate::{AccessRights, EntryPointAccess, EntryPointType, Group, Parameter, URef}; + use alloc::borrow::ToOwned; + + const CONTRACT_HASH_V1: ContractHash = ContractHash::new([42; 32]); + const CONTRACT_HASH_V2: ContractHash = ContractHash::new([84; 32]); + + fn make_contract_package() -> ContractPackage { + let mut contract_package = ContractPackage::new( + URef::new([0; 32], AccessRights::NONE), + ContractVersions::default(), + DisabledVersions::default(), + Groups::default(), + ContractPackageStatus::default(), + ); + + // add groups + { + let group_urefs = { + let mut ret = BTreeSet::new(); + ret.insert(URef::new([1; 32], AccessRights::READ)); + ret + }; + + contract_package + .groups_mut() + .insert(Group::new("Group 1"), group_urefs.clone()); + + contract_package + .groups_mut() + .insert(Group::new("Group 2"), group_urefs); + } + + // add entry_points + let _entry_points = { + let mut ret = BTreeMap::new(); + let entrypoint = EntryPoint::new( + "method0".to_string(), + vec![], + CLType::U32, + EntryPointAccess::groups(&["Group 2"]), + EntryPointType::Session, + ); + ret.insert(entrypoint.name().to_owned(), entrypoint); + let entrypoint = EntryPoint::new( + "method1".to_string(), + vec![Parameter::new("Foo", CLType::U32)], + CLType::U32, + EntryPointAccess::groups(&["Group 1"]), + EntryPointType::Session, + ); + ret.insert(entrypoint.name().to_owned(), entrypoint); + ret + }; + + let _contract_package_hash = [41; 32]; + let _contract_wasm_hash = [43; 32]; + let _named_keys = NamedKeys::new(); + let protocol_version = ProtocolVersion::V1_0_0; + + let v1 = contract_package + .insert_contract_version(protocol_version.value().major, CONTRACT_HASH_V1); + let v2 = contract_package + .insert_contract_version(protocol_version.value().major, CONTRACT_HASH_V2); + + assert!(v2 > v1); + + contract_package + } + + #[test] + fn roundtrip_serialization() { + let contract_package = make_contract_package(); + let bytes = contract_package.to_bytes().expect("should serialize"); + let (decoded_package, rem) = + ContractPackage::from_bytes(&bytes).expect("should deserialize"); + assert_eq!(contract_package, decoded_package); + assert_eq!(rem.len(), 0); + } + + #[test] + fn contract_hash_from_slice() { + let bytes: Vec = (0..32).collect(); + let contract_hash = HashAddr::try_from(&bytes[..]).expect("should create contract hash"); + let contract_hash = ContractHash::new(contract_hash); + assert_eq!(&bytes, &contract_hash.as_bytes()); + } + + #[test] + fn contract_package_hash_from_slice() { + let bytes: Vec = (0..32).collect(); + let contract_hash = HashAddr::try_from(&bytes[..]).expect("should create contract hash"); + let contract_hash = ContractPackageHash::new(contract_hash); + assert_eq!(&bytes, &contract_hash.as_bytes()); + } + + #[test] + fn contract_hash_from_str() { + let contract_hash = ContractHash([3; 32]); + let encoded = contract_hash.to_formatted_string(); + let decoded = ContractHash::from_formatted_str(&encoded).unwrap(); + assert_eq!(contract_hash, decoded); + + let invalid_prefix = + "contract--0000000000000000000000000000000000000000000000000000000000000000"; + assert!(ContractHash::from_formatted_str(invalid_prefix).is_err()); + + let short_addr = "contract-00000000000000000000000000000000000000000000000000000000000000"; + assert!(ContractHash::from_formatted_str(short_addr).is_err()); + + let long_addr = + "contract-000000000000000000000000000000000000000000000000000000000000000000"; + assert!(ContractHash::from_formatted_str(long_addr).is_err()); + + let invalid_hex = + "contract-000000000000000000000000000000000000000000000000000000000000000g"; + assert!(ContractHash::from_formatted_str(invalid_hex).is_err()); + } + + #[test] + fn contract_package_hash_from_str() { + let contract_package_hash = ContractPackageHash([3; 32]); + let encoded = contract_package_hash.to_formatted_string(); + let decoded = ContractPackageHash::from_formatted_str(&encoded).unwrap(); + assert_eq!(contract_package_hash, decoded); + + let invalid_prefix = + "contract-package0000000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + ContractPackageHash::from_formatted_str(invalid_prefix).unwrap_err(), + FromStrError::InvalidPrefix + )); + + let short_addr = + "contract-package-00000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + ContractPackageHash::from_formatted_str(short_addr).unwrap_err(), + FromStrError::Hash(_) + )); + + let long_addr = + "contract-package-000000000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + ContractPackageHash::from_formatted_str(long_addr).unwrap_err(), + FromStrError::Hash(_) + )); + + let invalid_hex = + "contract-package-000000000000000000000000000000000000000000000000000000000000000g"; + assert!(matches!( + ContractPackageHash::from_formatted_str(invalid_hex).unwrap_err(), + FromStrError::Hex(_) + )); + } + + #[test] + fn contract_package_hash_from_legacy_str() { + let contract_package_hash = ContractPackageHash([3; 32]); + let hex_addr = contract_package_hash.to_string(); + let legacy_encoded = format!("contract-package-wasm{}", hex_addr); + let decoded_from_legacy = ContractPackageHash::from_formatted_str(&legacy_encoded) + .expect("should accept legacy prefixed string"); + assert_eq!( + contract_package_hash, decoded_from_legacy, + "decoded_from_legacy should equal decoded" + ); + + let invalid_prefix = + "contract-packagewasm0000000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + ContractPackageHash::from_formatted_str(invalid_prefix).unwrap_err(), + FromStrError::InvalidPrefix + )); + + let short_addr = + "contract-package-wasm00000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + ContractPackageHash::from_formatted_str(short_addr).unwrap_err(), + FromStrError::Hash(_) + )); + + let long_addr = + "contract-package-wasm000000000000000000000000000000000000000000000000000000000000000000"; + assert!(matches!( + ContractPackageHash::from_formatted_str(long_addr).unwrap_err(), + FromStrError::Hash(_) + )); + + let invalid_hex = + "contract-package-wasm000000000000000000000000000000000000000000000000000000000000000g"; + assert!(matches!( + ContractPackageHash::from_formatted_str(invalid_hex).unwrap_err(), + FromStrError::Hex(_) + )); + } + + #[test] + fn contract_hash_serde_roundtrip() { + let contract_hash = ContractHash([255; 32]); + let serialized = bincode::serialize(&contract_hash).unwrap(); + let deserialized = bincode::deserialize(&serialized).unwrap(); + assert_eq!(contract_hash, deserialized) + } + + #[test] + fn contract_hash_json_roundtrip() { + let contract_hash = ContractHash([255; 32]); + let json_string = serde_json::to_string_pretty(&contract_hash).unwrap(); + let decoded = serde_json::from_str(&json_string).unwrap(); + assert_eq!(contract_hash, decoded) + } + + #[test] + fn contract_package_hash_serde_roundtrip() { + let contract_hash = ContractPackageHash([255; 32]); + let serialized = bincode::serialize(&contract_hash).unwrap(); + let deserialized = bincode::deserialize(&serialized).unwrap(); + assert_eq!(contract_hash, deserialized) + } + + #[test] + fn contract_package_hash_json_roundtrip() { + let contract_hash = ContractPackageHash([255; 32]); + let json_string = serde_json::to_string_pretty(&contract_hash).unwrap(); + let decoded = serde_json::from_str(&json_string).unwrap(); + assert_eq!(contract_hash, decoded) + } +} + +#[cfg(test)] +mod prop_tests { + use proptest::prelude::*; + + use crate::{bytesrepr, gens}; + + proptest! { + #![proptest_config(ProptestConfig { + cases: 1024, + .. ProptestConfig::default() + })] + + #[test] + fn test_value_contract(contract in gens::contract_arb()) { + bytesrepr::test_serialization_roundtrip(&contract); + } + + #[test] + fn test_value_contract_package(contract_pkg in gens::contract_package_arb()) { + bytesrepr::test_serialization_roundtrip(&contract_pkg); + } + } +} diff --git a/types/src/execution/execution_result_v1.rs b/types/src/execution/execution_result_v1.rs index 372e5d2ad7..377af24f64 100644 --- a/types/src/execution/execution_result_v1.rs +++ b/types/src/execution/execution_result_v1.rs @@ -64,9 +64,9 @@ enum TransformTag { Identity = 0, WriteCLValue = 1, WriteAccount = 2, - WriteContractWasm = 3, + WriteByteCode = 3, WriteContract = 4, - WriteContractPackage = 5, + WritePackage = 5, WriteDeployInfo = 6, WriteTransfer = 7, WriteEraInfo = 8, @@ -509,12 +509,10 @@ impl ToBytes for Transform { (TransformTag::WriteAccount as u8).write_bytes(writer)?; account_hash.write_bytes(writer) } - Transform::WriteContractWasm => { - (TransformTag::WriteContractWasm as u8).write_bytes(writer) - } + Transform::WriteContractWasm => (TransformTag::WriteByteCode as u8).write_bytes(writer), Transform::WriteContract => (TransformTag::WriteContract as u8).write_bytes(writer), Transform::WriteContractPackage => { - (TransformTag::WriteContractPackage as u8).write_bytes(writer) + (TransformTag::WritePackage as u8).write_bytes(writer) } Transform::WriteDeployInfo(deploy_info) => { (TransformTag::WriteDeployInfo as u8).write_bytes(writer)?; @@ -630,9 +628,9 @@ impl FromBytes for Transform { let (account_hash, remainder) = AccountHash::from_bytes(remainder)?; Ok((Transform::WriteAccount(account_hash), remainder)) } - TransformTag::WriteContractWasm => Ok((Transform::WriteContractWasm, remainder)), + TransformTag::WriteByteCode => Ok((Transform::WriteContractWasm, remainder)), TransformTag::WriteContract => Ok((Transform::WriteContract, remainder)), - TransformTag::WriteContractPackage => Ok((Transform::WriteContractPackage, remainder)), + TransformTag::WritePackage => Ok((Transform::WriteContractPackage, remainder)), TransformTag::WriteDeployInfo => { let (deploy_info, remainder) = DeployInfo::from_bytes(remainder)?; Ok((Transform::WriteDeployInfo(deploy_info), remainder)) diff --git a/types/src/execution/transform_kind.rs b/types/src/execution/transform_kind.rs index de9ada8835..421131e9e9 100644 --- a/types/src/execution/transform_kind.rs +++ b/types/src/execution/transform_kind.rs @@ -117,14 +117,14 @@ impl TransformKind { let found = format!("{:?}", cl_value.cl_type()); Err(StoredValueTypeMismatch::new(expected, found).into()) } - StoredValue::ContractPackage(_) => { + StoredValue::Package(_) => { let expected = "Contract or Account".to_string(); let found = "ContractPackage".to_string(); Err(StoredValueTypeMismatch::new(expected, found).into()) } - StoredValue::ContractWasm(_) => { + StoredValue::ByteCode(_) => { let expected = "Contract or Account".to_string(); - let found = "ContractWasm".to_string(); + let found = "ByteCode".to_string(); Err(StoredValueTypeMismatch::new(expected, found).into()) } StoredValue::Transfer(_) => { @@ -162,6 +162,16 @@ impl TransformKind { let found = "Unbonding".to_string(); Err(StoredValueTypeMismatch::new(expected, found).into()) } + StoredValue::ContractWasm(_) => { + let expected = "Contract or Account".to_string(); + let found = "ContractWasm".to_string(); + Err(StoredValueTypeMismatch::new(expected, found).into()) + } + StoredValue::ContractPackage(_) => { + let expected = "Contract or Account".to_string(); + let found = "ContractPackage".to_string(); + Err(StoredValueTypeMismatch::new(expected, found).into()) + } }, TransformKind::Failure(error) => Err(error), } @@ -378,7 +388,8 @@ mod tests { use num::{Bounded, Num}; use crate::{ - bytesrepr::Bytes, testing::TestRng, AccessRights, ContractWasm, Key, URef, U128, U256, U512, + byte_code::ByteCodeKind, bytesrepr::Bytes, testing::TestRng, AccessRights, ByteCode, Key, + URef, U128, U256, U512, }; use super::*; @@ -510,8 +521,8 @@ mod tests { }; } - let contract = StoredValue::ContractWasm(ContractWasm::new(vec![])); - assert_yields_type_mismatch_error(contract); + let byte_code = StoredValue::ByteCode(ByteCode::new(ByteCodeKind::V1CasperWasm, vec![])); + assert_yields_type_mismatch_error(byte_code); let uref = URef::new(ZERO_ARRAY, AccessRights::READ); diff --git a/types/src/gens.rs b/types/src/gens.rs index 16837be4ee..ffe7e62476 100644 --- a/types/src/gens.rs +++ b/types/src/gens.rs @@ -16,13 +16,13 @@ use crate::{ account::{self, action_thresholds::gens::account_action_thresholds_arb, AccountHash}, addressable_entity::{NamedKeys, Parameters, Weight}, crypto::gens::public_key_arb_no_system, - package::{ContractPackageStatus, ContractVersionKey, ContractVersions, Groups}, + package::{EntityVersionKey, EntityVersions, Groups, PackageStatus}, system::auction::{ gens::era_info_arb, DelegationRate, Delegator, UnbondingPurse, WithdrawPurse, DELEGATION_RATE_DENOMINATOR, }, transfer::TransferAddr, - AccessRights, AddressableEntity, CLType, CLValue, ContractHash, ContractWasm, EntryPoint, + AccessRights, AddressableEntity, AddressableEntityHash, ByteCode, CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, EraId, Group, Key, NamedArg, Package, Parameter, Phase, ProtocolVersion, SemVer, StoredValue, URef, U128, U256, U512, }; @@ -32,9 +32,13 @@ use crate::{ addressable_entity::{ action_thresholds::gens::action_thresholds_arb, associated_keys::gens::associated_keys_arb, }, - contracts::Contract, + byte_code::ByteCodeKind, + contracts::{ + Contract, ContractHash, ContractPackage, ContractPackageStatus, ContractVersionKey, + ContractVersions, + }, deploy_info::gens::{deploy_hash_arb, transfer_addr_arb}, - package::ContractPackageKind, + package::PackageKind, system::auction::{Bid, BidAddr, BidKind, ValidatorBid}, }; pub use crate::{deploy_info::gens::deploy_info_arb, transfer::gens::transfer_arb}; @@ -307,8 +311,8 @@ pub fn entry_point_access_arb() -> impl Strategy { pub fn entry_point_type_arb() -> impl Strategy { prop_oneof![ Just(EntryPointType::Session), - Just(EntryPointType::Contract), - Just(EntryPointType::Install), + Just(EntryPointType::AddressableEntity), + Just(EntryPointType::Factory), ] } @@ -360,6 +364,24 @@ pub fn account_arb() -> impl Strategy { ) } +pub fn contract_package_arb() -> impl Strategy { + ( + uref_arb(), + contract_versions_arb(), + disabled_contract_versions_arb(), + groups_arb(), + ) + .prop_map(|(access_key, versions, disabled_versions, groups)| { + ContractPackage::new( + access_key, + versions, + disabled_versions, + groups, + ContractPackageStatus::default(), + ) + }) +} + pub fn contract_arb() -> impl Strategy { ( protocol_version_arb(), @@ -423,8 +445,9 @@ pub fn addressable_entity_arb() -> impl Strategy { ) } -pub fn contract_wasm_arb() -> impl Strategy { - collection::vec(any::(), 1..1000).prop_map(ContractWasm::new) +pub fn byte_code_arb() -> impl Strategy { + collection::vec(any::(), 1..1000) + .prop_map(|byte_code| ByteCode::new(ByteCodeKind::V1CasperWasm, byte_code)) } pub fn contract_version_key_arb() -> impl Strategy { @@ -432,16 +455,33 @@ pub fn contract_version_key_arb() -> impl Strategy { .prop_map(|(major, contract_ver)| ContractVersionKey::new(major, contract_ver)) } +pub fn entity_version_key_arb() -> impl Strategy { + (1..32u32, 1..1000u32) + .prop_map(|(major, contract_ver)| EntityVersionKey::new(major, contract_ver)) +} + pub fn contract_versions_arb() -> impl Strategy { collection::btree_map( contract_version_key_arb(), u8_slice_32().prop_map(ContractHash::new), 1..5, ) - .prop_map(ContractVersions::from) } -pub fn disabled_versions_arb() -> impl Strategy> { +pub fn entity_versions_arb() -> impl Strategy { + collection::btree_map( + entity_version_key_arb(), + u8_slice_32().prop_map(AddressableEntityHash::new), + 1..5, + ) + .prop_map(EntityVersions::from) +} + +pub fn disabled_versions_arb() -> impl Strategy> { + collection::btree_set(entity_version_key_arb(), 0..5) +} + +pub fn disabled_contract_versions_arb() -> impl Strategy> { collection::btree_set(contract_version_key_arb(), 0..5) } @@ -450,10 +490,10 @@ pub fn groups_arb() -> impl Strategy { .prop_map(Groups::from) } -pub fn contract_package_arb() -> impl Strategy { +pub fn package_arb() -> impl Strategy { ( uref_arb(), - contract_versions_arb(), + entity_versions_arb(), disabled_versions_arb(), groups_arb(), ) @@ -463,8 +503,8 @@ pub fn contract_package_arb() -> impl Strategy { versions, disabled_versions, groups, - ContractPackageStatus::default(), - ContractPackageKind::default(), + PackageStatus::default(), + PackageKind::SmartContract, ) }) } @@ -624,10 +664,10 @@ pub fn stored_value_arb() -> impl Strategy { prop_oneof![ cl_value_arb().prop_map(StoredValue::CLValue), account_arb().prop_map(StoredValue::Account), - contract_wasm_arb().prop_map(StoredValue::ContractWasm), + byte_code_arb().prop_map(StoredValue::ByteCode), contract_arb().prop_map(StoredValue::Contract), addressable_entity_arb().prop_map(StoredValue::AddressableEntity), - contract_package_arb().prop_map(StoredValue::ContractPackage), + package_arb().prop_map(StoredValue::Package), transfer_arb().prop_map(StoredValue::Transfer), deploy_info_arb().prop_map(StoredValue::DeployInfo), era_info_arb(1..10).prop_map(StoredValue::EraInfo), @@ -654,5 +694,7 @@ pub fn stored_value_arb() -> impl Strategy { StoredValue::Unbonding(_) => stored_value, StoredValue::AddressableEntity(_) => stored_value, StoredValue::BidKind(_) => stored_value, + StoredValue::Package(_) => stored_value, + StoredValue::ByteCode(_) => stored_value, }) } diff --git a/types/src/key.rs b/types/src/key.rs index 46a81ebc05..fb63753ef6 100644 --- a/types/src/key.rs +++ b/types/src/key.rs @@ -32,11 +32,13 @@ use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Seria use crate::{ account::{AccountHash, ACCOUNT_HASH_LENGTH}, addressable_entity, - addressable_entity::ContractHash, - bytesrepr::{self, Error, FromBytes, ToBytes, U64_SERIALIZED_LENGTH}, + addressable_entity::AddressableEntityHash, + byte_code::ByteCodeKind, + bytesrepr::{self, Error, FromBytes, ToBytes, U64_SERIALIZED_LENGTH, U8_SERIALIZED_LENGTH}, checksummed_hex, contract_wasm::ContractWasmHash, - package::ContractPackageHash, + contracts::{ContractHash, ContractPackageHash}, + package::{PackageHash, PackageKindTag}, system::auction::{BidAddr, BidAddrTag}, uref::{self, URef, URefAddr, UREF_SERIALIZED_LENGTH}, DeployHash, Digest, EraId, Tagged, TransferAddr, TransferFromStrError, TRANSFER_ADDR_LENGTH, @@ -56,6 +58,18 @@ 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_ADDR_PREFIX: &str = "package-"; +const ENTITY_ADDR_PREFIX: &str = "addressable-entity-"; + +const ACCOUNT_ENTITY_PREFIX: &str = "account-"; +const CONTRACT_ENTITY_PREFIX: &str = "contract-"; +const SYSTEM_ENTITY_PREFIX: &str = "system-"; + +const BYTE_CODE_ADDR_PREFIX: &str = "byte-code-"; + +const WASM_PREFIX: &str = "v1-wasm-"; + +const EMPTY_PREFIX: &str = "empty-"; /// The number of bytes in a Blake2b hash pub const BLAKE2B_DIGEST_LENGTH: usize = 32; @@ -69,6 +83,8 @@ pub const KEY_DEPLOY_INFO_LENGTH: usize = DeployHash::LENGTH; pub const KEY_DICTIONARY_LENGTH: usize = 32; /// The maximum length for a `dictionary_item_key`. pub const DICTIONARY_ITEM_KEY_MAX_LENGTH: usize = 128; +/// The maximum length for an `Addr`. +pub const ADDR_LENGTH: usize = 32; const PADDING_BYTES: [u8; 32] = [0u8; 32]; const KEY_ID_SERIALIZED_LENGTH: usize = 1; const BID_TAG_SERIALIZED_LENGTH: usize = 1; @@ -94,12 +110,22 @@ const KEY_CHAINSPEC_REGISTRY_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + PADDING_BYTES.len(); 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 MAX_SERIALIZED_LENGTH: usize = KEY_DELEGATOR_BID_SERIALIZED_LENGTH; /// An alias for [`Key`]s hash variant. pub type HashAddr = [u8; KEY_HASH_LENGTH]; +/// An alias for [`Key`]s package variant. +pub type PackageAddr = [u8; ADDR_LENGTH]; + +/// An alias for [`Key`]s entity variant. +pub type EntityAddr = [u8; ADDR_LENGTH]; + +/// An alias for [`Key`]s byte code variant. +pub type ByteCodeAddr = [u8; ADDR_LENGTH]; + /// An alias for [`Key`]s dictionary variant. pub type DictionaryAddr = [u8; KEY_DICTIONARY_LENGTH]; @@ -123,6 +149,9 @@ pub enum KeyTag { ChainspecRegistry = 13, ChecksumRegistry = 14, BidAddr = 15, + Package = 16, + AddressableEntity = 17, + ByteCode = 18, } impl Display for KeyTag { @@ -144,6 +173,9 @@ impl Display for KeyTag { KeyTag::ChainspecRegistry => write!(f, "ChainspecRegistry"), KeyTag::ChecksumRegistry => write!(f, "ChecksumRegistry"), KeyTag::BidAddr => write!(f, "BidAddr"), + KeyTag::Package => write!(f, "Package"), + KeyTag::AddressableEntity => write!(f, "AddressableEntity"), + KeyTag::ByteCode => write!(f, "ByteCode"), } } } @@ -187,6 +219,12 @@ pub enum Key { ChecksumRegistry, /// A `Key` under which we store bid information BidAddr(BidAddr), + /// A `Key` under which we store package information. + Package(PackageAddr), + /// A `Key` under which we write an addressable entity. + AddressableEntity((PackageKindTag, EntityAddr)), + /// A `Key` under which we write a byte code record. + ByteCode((ByteCodeKind, ByteCodeAddr)), } #[cfg(feature = "json-schema")] @@ -243,6 +281,12 @@ pub enum FromStrError { ChecksumRegistry(String), /// Bid parse error. BidAddr(String), + /// Package parse error. + Package(String), + /// Entity parse error. + AddressableEntity(String), + /// Byte code parse error. + ByteCode(String), /// Unknown prefix. UnknownPrefix, } @@ -302,6 +346,13 @@ impl Display for FromStrError { 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::UnknownPrefix => write!(f, "unknown prefix for key"), } } @@ -328,6 +379,9 @@ impl Key { 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"), } } @@ -414,6 +468,57 @@ impl Key { Key::BidAddr(bid_addr) => { format!("{}{}", BID_ADDR_PREFIX, bid_addr) } + Key::Package(package_addr) => { + format!( + "{}{}", + PACKAGE_ADDR_PREFIX, + base16::encode_lower(&package_addr) + ) + } + Key::AddressableEntity((package_tag, entity_addr)) => match package_tag { + PackageKindTag::System => { + format!( + "{}{}{}", + ENTITY_ADDR_PREFIX, + SYSTEM_ENTITY_PREFIX, + base16::encode_lower(&entity_addr) + ) + } + PackageKindTag::Account => { + format!( + "{}{}{}", + ENTITY_ADDR_PREFIX, + ACCOUNT_ENTITY_PREFIX, + base16::encode_lower(&entity_addr) + ) + } + PackageKindTag::SmartContract => { + format!( + "{}{}{}", + ENTITY_ADDR_PREFIX, + CONTRACT_ENTITY_PREFIX, + base16::encode_lower(&entity_addr) + ) + } + }, + Key::ByteCode((byte_code_kind, byte_code_addr)) => match byte_code_kind { + ByteCodeKind::Empty => { + format!( + "{}{}{}", + BYTE_CODE_ADDR_PREFIX, + EMPTY_PREFIX, + base16::encode_lower(&byte_code_addr) + ) + } + ByteCodeKind::V1CasperWasm => { + format!( + "{}{}{}", + BYTE_CODE_ADDR_PREFIX, + WASM_PREFIX, + base16::encode_lower(&byte_code_addr) + ) + } + }, } } @@ -577,6 +682,59 @@ impl Key { return Ok(Key::ChecksumRegistry); } + if let Some(entity_string) = + input.strip_prefix(&format!("{}{}", ENTITY_ADDR_PREFIX, ACCOUNT_ENTITY_PREFIX)) + { + let addr = checksummed_hex::decode(entity_string) + .map_err(|error| FromStrError::AddressableEntity(error.to_string()))?; + let hash_addr = EntityAddr::try_from(addr.as_ref()) + .map_err(|error| FromStrError::AddressableEntity(error.to_string()))?; + return Ok(Key::AddressableEntity((PackageKindTag::Account, hash_addr))); + } + + if let Some(entity_string) = + input.strip_prefix(&format!("{}{}", ENTITY_ADDR_PREFIX, SYSTEM_ENTITY_PREFIX)) + { + let addr = checksummed_hex::decode(entity_string) + .map_err(|error| FromStrError::AddressableEntity(error.to_string()))?; + let hash_addr = EntityAddr::try_from(addr.as_ref()) + .map_err(|error| FromStrError::AddressableEntity(error.to_string()))?; + return Ok(Key::AddressableEntity((PackageKindTag::System, hash_addr))); + } + + if let Some(entity_string) = + input.strip_prefix(&format!("{}{}", ENTITY_ADDR_PREFIX, CONTRACT_ENTITY_PREFIX)) + { + let addr = checksummed_hex::decode(entity_string) + .map_err(|error| FromStrError::AddressableEntity(error.to_string()))?; + let hash_addr = EntityAddr::try_from(addr.as_ref()) + .map_err(|error| FromStrError::AddressableEntity(error.to_string()))?; + return Ok(Key::AddressableEntity(( + PackageKindTag::SmartContract, + hash_addr, + ))); + } + + if let Some(byte_code_string) = + input.strip_prefix(&format!("{}{}", BYTE_CODE_ADDR_PREFIX, EMPTY_PREFIX)) + { + let addr = checksummed_hex::decode(byte_code_string) + .map_err(|error| FromStrError::ByteCode(error.to_string()))?; + let byte_code_addr = ByteCodeAddr::try_from(addr.as_ref()) + .map_err(|error| FromStrError::ByteCode(error.to_string()))?; + return Ok(Key::ByteCode((ByteCodeKind::Empty, byte_code_addr))); + } + + if let Some(byte_code_string) = + input.strip_prefix(&format!("{}{}", BYTE_CODE_ADDR_PREFIX, WASM_PREFIX)) + { + let addr = checksummed_hex::decode(byte_code_string) + .map_err(|error| FromStrError::ByteCode(error.to_string()))?; + let byte_code_addr = ByteCodeAddr::try_from(addr.as_ref()) + .map_err(|error| FromStrError::ByteCode(error.to_string()))?; + return Ok(Key::ByteCode((ByteCodeKind::V1CasperWasm, byte_code_addr))); + } + Err(FromStrError::UnknownPrefix) } @@ -591,18 +749,43 @@ impl Key { /// Returns the inner bytes of `self` if `self` is of type [`Key::Hash`], otherwise returns /// `None`. - pub fn into_hash(self) -> Option { + pub fn into_hash_addr(self) -> Option { match self { Key::Hash(hash) => Some(hash), _ => None, } } - /// Returns [`ContractHash`] of `self` if `self` is of type [`Key::Hash`], otherwise returns + /// Returns the inner bytes of `self` if `self` is of type [`Key::AddressableEntity`], otherwise + /// returns `None`. + pub fn into_entity_addr(self) -> Option { + match self { + Key::AddressableEntity((_, hash)) => Some(hash), + _ => None, + } + } + + /// Returns the inner bytes of `self` if `self` is of type [`Key::Package`], otherwise returns /// `None`. - pub fn into_contract_hash(self) -> Option { - let hash_addr = self.into_hash()?; - Some(ContractHash::new(hash_addr)) + pub fn into_package_addr(self) -> Option { + match self { + Key::Package(package_addr) => Some(package_addr), + _ => None, + } + } + + /// Returns [`AddressableEntityHash`] of `self` if `self` is of type [`Key::AddressableEntity`], + /// otherwise returns `None`. + pub fn into_entity_hash(self) -> Option { + let entity_addr = self.into_entity_addr()?; + Some(AddressableEntityHash::new(entity_addr)) + } + + /// Returns [`PackageHash`] of `self` if `self` is of type [`Key::Package`], otherwise + /// returns `None`. + pub fn into_package_hash(self) -> Option { + let package_addr = self.into_package_addr()?; + Some(PackageHash::new(package_addr)) } /// Returns a reference to the inner [`URef`] if `self` is of type [`Key::URef`], otherwise @@ -678,6 +861,25 @@ impl Key { Key::Dictionary(addr) } + /// Creates a new [`Key::AddressableEntity`] variant from a package kind and an entity + /// hash. + pub fn addressable_entity_key( + package_kind_tag: PackageKindTag, + entity_hash: AddressableEntityHash, + ) -> Self { + Key::AddressableEntity((package_kind_tag, entity_hash.value())) + } + + /// Creates a new [`Key::AddressableEntity`] for a Smart contract. + pub fn contract_entity_key(entity_hash: AddressableEntityHash) -> Key { + Self::addressable_entity_key(PackageKindTag::SmartContract, entity_hash) + } + + /// Creates a new [`Key::ByteCode`] variant from a byte code kind and an byte code addr. + pub fn byte_code_key(byte_code_kind: ByteCodeKind, byte_code_addr: ByteCodeAddr) -> Self { + Key::ByteCode((byte_code_kind, byte_code_addr)) + } + /// Returns true if the key is of type [`Key::Dictionary`]. pub fn is_dictionary_key(&self) -> bool { if let Key::Dictionary(_) = self { @@ -711,6 +913,15 @@ impl Key { None } } + + /// Returns if they inner Key is for a system contract entity. + pub fn is_system_key(&self) -> bool { + if let Self::AddressableEntity((PackageKindTag::System, _)) = self { + return true; + } + + false + } } impl Display for Key { @@ -758,6 +969,23 @@ impl Display for Key { ) } Key::BidAddr(bid_addr) => write!(f, "Key::BidAddr({})", bid_addr), + Key::Package(package_addr) => { + write!(f, "Key::Package({})", base16::encode_lower(package_addr)) + } + Key::AddressableEntity((kind_tag, entity_addr)) => write!( + f, + "Key::AddressableEntity({}-{})", + *kind_tag as u8, + base16::encode_lower(entity_addr) + ), + Key::ByteCode((kind, byte_code_addr)) => { + write!( + f, + "Key::ByteCode({}-{})", + *kind as u8, + base16::encode_lower(byte_code_addr) + ) + } } } } @@ -787,6 +1015,9 @@ impl Tagged for Key { Key::ChainspecRegistry => KeyTag::ChainspecRegistry, Key::ChecksumRegistry => KeyTag::ChecksumRegistry, Key::BidAddr(_) => KeyTag::BidAddr, + Key::Package(_) => KeyTag::Package, + Key::AddressableEntity(_) => KeyTag::AddressableEntity, + Key::ByteCode(_) => KeyTag::ByteCode, } } } @@ -816,21 +1047,27 @@ impl From for Key { } } -impl From for Key { - fn from(contract_hash: ContractHash) -> Key { - Key::Hash(contract_hash.value()) +impl From for Key { + fn from(package_hash: PackageHash) -> Key { + Key::Package(package_hash.value()) } } impl From for Key { - fn from(wasm_hash: ContractWasmHash) -> Key { + fn from(wasm_hash: ContractWasmHash) -> Self { Key::Hash(wasm_hash.value()) } } impl From for Key { - fn from(package_hash: ContractPackageHash) -> Key { - Key::Hash(package_hash.value()) + fn from(contract_package_hash: ContractPackageHash) -> Self { + Key::Hash(contract_package_hash.value()) + } +} + +impl From for Key { + fn from(contract_hash: ContractHash) -> Self { + Key::Hash(contract_hash.value()) } } @@ -866,6 +1103,13 @@ impl ToBytes for Key { KEY_ID_SERIALIZED_LENGTH + bid_addr.serialized_length() } }, + Key::Package(_) => KEY_PACKAGE_SERIALIZED_LENGTH, + Key::AddressableEntity(_) => { + U8_SERIALIZED_LENGTH + KEY_ID_SERIALIZED_LENGTH + ADDR_LENGTH + } + Key::ByteCode((byte_code_kind, _)) => { + byte_code_kind.serialized_length() + KEY_ID_SERIALIZED_LENGTH + ADDR_LENGTH + } } } @@ -895,6 +1139,15 @@ impl ToBytes for Key { } BidAddrTag::Validator | BidAddrTag::Delegator => bid_addr.write_bytes(writer), }, + Key::Package(package_addr) => package_addr.write_bytes(writer), + Key::AddressableEntity((package_kind, entity_addr)) => { + writer.push(*package_kind as u8); + entity_addr.write_bytes(writer) + } + Key::ByteCode((byte_code_kind, byte_code_addr)) => { + byte_code_kind.write_bytes(writer)?; + byte_code_addr.write_bytes(writer) + } } } } @@ -967,6 +1220,23 @@ impl FromBytes for Key { let (bid_addr, rem) = BidAddr::from_bytes(remainder)?; Ok((Key::BidAddr(bid_addr), rem)) } + tag if tag == KeyTag::Package as u8 => { + let (package_addr, rem) = PackageAddr::from_bytes(remainder)?; + Ok((Key::Package(package_addr), rem)) + } + tag if tag == KeyTag::AddressableEntity as u8 => { + let (package_kind_tag, rem) = u8::from_bytes(remainder)?; + let package_kind_tag = PackageKindTag::try_from(package_kind_tag)?; + let (entity_addr, rem) = EntityAddr::from_bytes(rem)?; + Ok((Key::AddressableEntity((package_kind_tag, entity_addr)), rem)) + } + tag if tag == KeyTag::ByteCode as u8 => { + let (byte_code_kind, remainder) = u8::from_bytes(remainder)?; + let byte_code_kind = ByteCodeKind::try_from(byte_code_kind)?; + let (byte_code_addr, rem) = ByteCodeAddr::from_bytes(remainder)?; + + Ok((Key::ByteCode((byte_code_kind, byte_code_addr)), rem)) + } _ => Err(Error::Formatting), } } @@ -993,13 +1263,16 @@ fn please_add_to_distribution_impl(key: Key) { Key::ChainspecRegistry => unimplemented!(), Key::ChecksumRegistry => unimplemented!(), Key::BidAddr(_) => unimplemented!(), + Key::Package(_) => unimplemented!(), + Key::AddressableEntity(_) => unimplemented!(), + Key::ByteCode(_) => unimplemented!(), } } #[cfg(any(feature = "testing", test))] impl Distribution for Standard { fn sample(&self, rng: &mut R) -> Key { - match rng.gen_range(0..=14) { + match rng.gen_range(0..=18) { 0 => Key::Account(rng.gen()), 1 => Key::Hash(rng.gen()), 2 => Key::URef(rng.gen()), @@ -1016,6 +1289,9 @@ impl Distribution for Standard { 13 => Key::ChainspecRegistry, 14 => Key::ChecksumRegistry, 15 => Key::BidAddr(rng.gen()), + 16 => Key::Package(rng.gen()), + 17 => Key::AddressableEntity((rng.gen(), rng.gen())), + 18 => Key::ByteCode((rng.gen(), rng.gen())), _ => unreachable!(), } } @@ -1043,6 +1319,9 @@ mod serde_helpers { ChainspecRegistry, ChecksumRegistry, BidAddr(&'a BidAddr), + Package(&'a PackageAddr), + AddressableEntity((&'a PackageKindTag, &'a EntityAddr)), + ByteCode((&'a ByteCodeKind, &'a ByteCodeAddr)), } #[derive(Deserialize)] @@ -1064,6 +1343,9 @@ mod serde_helpers { ChainspecRegistry, ChecksumRegistry, BidAddr(BidAddr), + Package(PackageAddr), + AddressableEntity((PackageKindTag, EntityAddr)), + ByteCode((ByteCodeKind, ByteCodeAddr)), } impl<'a> From<&'a Key> for BinarySerHelper<'a> { @@ -1085,6 +1367,13 @@ mod serde_helpers { Key::ChainspecRegistry => BinarySerHelper::ChainspecRegistry, Key::ChecksumRegistry => BinarySerHelper::ChecksumRegistry, Key::BidAddr(bid_addr) => BinarySerHelper::BidAddr(bid_addr), + Key::Package(package_addr) => BinarySerHelper::Package(package_addr), + Key::AddressableEntity((package_kind, entity_addr)) => { + BinarySerHelper::AddressableEntity((package_kind, entity_addr)) + } + Key::ByteCode((byte_code_kind, byte_code_addr)) => { + BinarySerHelper::ByteCode((byte_code_kind, byte_code_addr)) + } } } } @@ -1108,6 +1397,13 @@ mod serde_helpers { BinaryDeserHelper::ChainspecRegistry => Key::ChainspecRegistry, BinaryDeserHelper::ChecksumRegistry => Key::ChecksumRegistry, BinaryDeserHelper::BidAddr(bid_addr) => Key::BidAddr(bid_addr), + BinaryDeserHelper::Package(package_addr) => Key::Package(package_addr), + BinaryDeserHelper::AddressableEntity((package_kind, entity_addr)) => { + Key::AddressableEntity((package_kind, entity_addr)) + } + BinaryDeserHelper::ByteCode((byte_kind, byte_code_addr)) => { + Key::ByteCode((byte_kind, byte_code_addr)) + } } } } @@ -1338,7 +1634,7 @@ mod tests { let account_hash = AccountHash::new(account); let key1 = Key::Account(account_hash); assert_eq!(key1.into_account(), Some(account_hash)); - assert!(key1.into_hash().is_none()); + assert!(key1.into_entity_addr().is_none()); assert!(key1.as_uref().is_none()); } @@ -1347,7 +1643,25 @@ mod tests { let hash = [42; KEY_HASH_LENGTH]; let key1 = Key::Hash(hash); assert!(key1.into_account().is_none()); - assert_eq!(key1.into_hash(), Some(hash)); + assert_eq!(key1.into_hash_addr(), Some(hash)); + assert!(key1.as_uref().is_none()); + } + + #[test] + fn check_entity_key_getters() { + let hash = [42; KEY_HASH_LENGTH]; + let key1 = Key::contract_entity_key(AddressableEntityHash::new(hash)); + assert!(key1.into_account().is_none()); + assert_eq!(key1.into_entity_addr(), Some(hash)); + assert!(key1.as_uref().is_none()); + } + + #[test] + fn check_package_key_getters() { + let hash = [42; KEY_HASH_LENGTH]; + let key1 = Key::Package(hash); + assert!(key1.into_account().is_none()); + assert_eq!(key1.into_package_addr(), Some(hash)); assert!(key1.as_uref().is_none()); } @@ -1356,7 +1670,7 @@ mod tests { let uref = URef::new([42; 32], AccessRights::READ_ADD_WRITE); let key1 = Key::URef(uref); assert!(key1.into_account().is_none()); - assert!(key1.into_hash().is_none()); + assert!(key1.into_entity_addr().is_none()); assert_eq!(key1.as_uref(), Some(&uref)); } diff --git a/types/src/lib.rs b/types/src/lib.rs index 9c8c2c8804..8b3bb0b895 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -28,6 +28,7 @@ pub mod addressable_entity; pub mod api_error; mod block; mod block_time; +mod byte_code; pub mod bytesrepr; #[cfg(any(feature = "std", test))] mod chainspec; @@ -78,8 +79,8 @@ pub use access_rights::{ }; #[doc(inline)] pub use addressable_entity::{ - AddressableEntity, ContractHash, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, - Parameter, + AddressableEntity, AddressableEntityHash, EntryPoint, EntryPointAccess, EntryPointType, + EntryPoints, Parameter, }; #[doc(inline)] pub use api_error::ApiError; @@ -96,6 +97,7 @@ pub use block::{ pub use block::{TestBlockBuilder, TestBlockV1Builder}; pub use block_time::{BlockTime, BLOCKTIME_SERIALIZED_LENGTH}; +pub use byte_code::{ByteCode, ByteCodeHash, ByteCodeKind}; #[cfg(any(feature = "std", test))] pub use chainspec::{ AccountConfig, AccountsConfig, ActivationPoint, AdministratorAccount, AuctionCosts, @@ -126,7 +128,7 @@ pub use chainspec::{ }; pub use cl_type::{named_key_type, CLType, CLTyped}; pub use cl_value::{CLTypeMismatch, CLValue, CLValueError}; -pub use contract_wasm::{ContractWasm, ContractWasmHash}; +pub use contract_wasm::ContractWasm; #[doc(inline)] pub use contracts::Contract; pub use crypto::*; @@ -141,13 +143,13 @@ pub use gas::Gas; pub use json_pretty_printer::json_pretty_print; #[doc(inline)] pub use key::{ - DictionaryAddr, FromStrError as KeyFromStrError, HashAddr, Key, KeyTag, BLAKE2B_DIGEST_LENGTH, - DICTIONARY_ITEM_KEY_MAX_LENGTH, KEY_DICTIONARY_LENGTH, KEY_HASH_LENGTH, + ByteCodeAddr, DictionaryAddr, EntityAddr, FromStrError as KeyFromStrError, HashAddr, Key, + KeyTag, PackageAddr, BLAKE2B_DIGEST_LENGTH, DICTIONARY_ITEM_KEY_MAX_LENGTH, + KEY_DICTIONARY_LENGTH, KEY_HASH_LENGTH, }; pub use motes::Motes; pub use package::{ - ContractPackageHash, ContractVersion, ContractVersionKey, ContractVersions, Group, Groups, - Package, + EntityVersion, EntityVersionKey, EntityVersions, Group, Groups, Package, PackageHash, }; pub use phase::{Phase, PHASE_SERIALIZED_LENGTH}; pub use protocol_version::{ProtocolVersion, VersionCheckResult}; @@ -162,10 +164,10 @@ pub use transaction::runtime_args::{NamedArg, RuntimeArgs}; #[cfg(any(all(feature = "std", feature = "testing"), test))] pub use transaction::TestTransactionV1Builder; pub use transaction::{ - runtime_args, AuctionTransactionV1, ContractIdentifier, ContractPackageIdentifier, Deploy, - DeployApproval, DeployApprovalsHash, DeployConfigurationFailure, DeployDecodeFromJsonError, - DeployError, DeployExcessiveSizeError, DeployFootprint, DeployHash, DeployHeader, DeployId, - DirectCallV1, ExecutableDeployItem, ExecutableDeployItemIdentifier, NativeTransactionV1, + runtime_args, AuctionTransactionV1, Deploy, DeployApproval, DeployApprovalsHash, + DeployConfigurationFailure, DeployDecodeFromJsonError, DeployError, DeployExcessiveSizeError, + DeployFootprint, DeployHash, DeployHeader, DeployId, DirectCallV1, EntityIdentifier, + ExecutableDeployItem, ExecutableDeployItemIdentifier, NativeTransactionV1, PackageIdentifier, PricingModeV1, Transaction, TransactionApprovalsHash, TransactionHash, TransactionId, TransactionV1, TransactionV1Approval, TransactionV1ApprovalsHash, TransactionV1ConfigFailure, TransactionV1DecodeFromJsonError, TransactionV1Error, TransactionV1ExcessiveSizeError, diff --git a/types/src/package.rs b/types/src/package.rs index 85c7a84cc9..cab96d9a84 100644 --- a/types/src/package.rs +++ b/types/src/package.rs @@ -1,4 +1,5 @@ //! Module containing the Package and associated types for addressable entities. + use alloc::{ collections::{BTreeMap, BTreeSet}, format, @@ -12,6 +13,11 @@ use core::{ #[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::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer}; @@ -25,9 +31,10 @@ use crate::{ bytesrepr::{self, FromBytes, ToBytes, U32_SERIALIZED_LENGTH, U8_SERIALIZED_LENGTH}, checksummed_hex, crypto::{self, PublicKey}, - system::SystemContractType, + system::SystemEntityType, uref::URef, - CLType, CLTyped, ContractHash, HashAddr, BLAKE2B_DIGEST_LENGTH, KEY_HASH_LENGTH, + AddressableEntityHash, CLType, CLTyped, HashAddr, Key, Tagged, BLAKE2B_DIGEST_LENGTH, + KEY_HASH_LENGTH, }; /// Maximum number of distinct user groups. @@ -105,34 +112,34 @@ impl FromBytes for Group { } /// Automatically incremented value for a contract version within a major `ProtocolVersion`. -pub type ContractVersion = u32; +pub type EntityVersion = u32; -/// Within each discrete major `ProtocolVersion`, contract version resets to this value. -pub const CONTRACT_INITIAL_VERSION: ContractVersion = 1; +/// Within each discrete major `ProtocolVersion`, entity version resets to this value. +pub const ENTITY_INITIAL_VERSION: EntityVersion = 1; -/// Major element of `ProtocolVersion` a `ContractVersion` is compatible with. +/// Major element of `ProtocolVersion` a `EntityVersion` is compatible with. pub type ProtocolVersionMajor = u32; -/// Major element of `ProtocolVersion` combined with `ContractVersion`. +/// Major element of `ProtocolVersion` combined with `EntityVersion`. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] -pub struct ContractVersionKey { +pub struct EntityVersionKey { /// Major element of `ProtocolVersion` a `ContractVersion` is compatible with. protocol_version_major: ProtocolVersionMajor, /// Automatically incremented value for a contract version within a major `ProtocolVersion`. - contract_version: ContractVersion, + entity_version: EntityVersion, } -impl ContractVersionKey { +impl EntityVersionKey { /// Returns a new instance of ContractVersionKey with provided values. pub fn new( protocol_version_major: ProtocolVersionMajor, - contract_version: ContractVersion, + entity_version: EntityVersion, ) -> Self { Self { protocol_version_major, - contract_version, + entity_version, } } @@ -142,21 +149,21 @@ impl ContractVersionKey { } /// Returns the contract version within the protocol major version. - pub fn contract_version(self) -> ContractVersion { - self.contract_version + pub fn entity_version(self) -> EntityVersion { + self.entity_version } } -impl From for (ProtocolVersionMajor, ContractVersion) { - fn from(contract_version_key: ContractVersionKey) -> Self { +impl From for (ProtocolVersionMajor, EntityVersion) { + fn from(entity_version_key: EntityVersionKey) -> Self { ( - contract_version_key.protocol_version_major, - contract_version_key.contract_version, + entity_version_key.protocol_version_major, + entity_version_key.entity_version, ) } } -impl ToBytes for ContractVersionKey { +impl ToBytes for EntityVersionKey { fn to_bytes(&self) -> Result, bytesrepr::Error> { let mut buffer = bytesrepr::allocate_buffer(self)?; self.write_bytes(&mut buffer)?; @@ -164,71 +171,78 @@ impl ToBytes for ContractVersionKey { } fn serialized_length(&self) -> usize { - CONTRACT_VERSION_KEY_SERIALIZED_LENGTH + ENTITY_VERSION_KEY_SERIALIZED_LENGTH } fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { self.protocol_version_major.write_bytes(writer)?; - self.contract_version.write_bytes(writer) + self.entity_version.write_bytes(writer) } } -impl FromBytes for ContractVersionKey { +impl FromBytes for EntityVersionKey { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { let (protocol_version_major, remainder) = ProtocolVersionMajor::from_bytes(bytes)?; - let (contract_version, remainder) = ContractVersion::from_bytes(remainder)?; + let (entity_version, remainder) = EntityVersion::from_bytes(remainder)?; Ok(( - ContractVersionKey { + EntityVersionKey { protocol_version_major, - contract_version, + entity_version, }, remainder, )) } } -impl Display for ContractVersionKey { +impl Display for EntityVersionKey { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!( - f, - "{}.{}", - self.protocol_version_major, self.contract_version - ) + write!(f, "{}.{}", self.protocol_version_major, self.entity_version) } } -/// Serialized length of `ContractVersionKey`. -pub const CONTRACT_VERSION_KEY_SERIALIZED_LENGTH: usize = +/// Serialized length of `EntityVersionKey`. +pub const ENTITY_VERSION_KEY_SERIALIZED_LENGTH: usize = U32_SERIALIZED_LENGTH + U32_SERIALIZED_LENGTH; -/// Collection of contract versions. +/// Collection of entity versions. #[derive(Clone, PartialEq, Eq, Default, Serialize, Deserialize, Debug)] #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] #[serde(transparent, deny_unknown_fields)] -pub struct ContractVersions( - #[serde(with = "BTreeMapToArray::")] - BTreeMap, +pub struct EntityVersions( + #[serde( + with = "BTreeMapToArray::" + )] + BTreeMap, ); -impl ContractVersions { - /// Constructs a new, empty `ContractVersions`. +impl EntityVersions { + /// Constructs a new, empty `EntityVersions`. pub const fn new() -> Self { - ContractVersions(BTreeMap::new()) + EntityVersions(BTreeMap::new()) } - /// Returns an iterator over the `ContractHash`s (i.e. the map's values). - pub fn contract_hashes(&self) -> impl Iterator { + /// Returns an iterator over the `AddressableEntityHash`s (i.e. the map's values). + pub fn contract_hashes(&self) -> impl Iterator { self.0.values() } - /// Returns the `ContractHash` under the key - pub fn get(&self, key: &ContractVersionKey) -> Option<&ContractHash> { + /// Returns the `AddressableEntityHash` under the key + pub fn get(&self, key: &EntityVersionKey) -> Option<&AddressableEntityHash> { self.0.get(key) } + + /// Retrieve the first entity version key if it exists + pub fn maybe_first(&mut self) -> Option<(EntityVersionKey, AddressableEntityHash)> { + if let Some((entity_version_key, entity_hash)) = self.0.iter().next() { + Some((*entity_version_key, *entity_hash)) + } else { + None + } + } } -impl ToBytes for ContractVersions { +impl ToBytes for EntityVersions { fn to_bytes(&self) -> Result, bytesrepr::Error> { self.0.to_bytes() } @@ -242,31 +256,30 @@ impl ToBytes for ContractVersions { } } -impl FromBytes for ContractVersions { +impl FromBytes for EntityVersions { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { let (versions, remainder) = - BTreeMap::::from_bytes(bytes)?; - Ok((ContractVersions(versions), remainder)) + BTreeMap::::from_bytes(bytes)?; + Ok((EntityVersions(versions), remainder)) } } -#[cfg(any(feature = "testing", feature = "gens", test))] -impl From> for ContractVersions { - fn from(value: BTreeMap) -> Self { - ContractVersions(value) +impl From> for EntityVersions { + fn from(value: BTreeMap) -> Self { + EntityVersions(value) } } -struct ContractVersionLabels; +struct EntityVersionLabels; -impl KeyValueLabels for ContractVersionLabels { - const KEY: &'static str = "contract_version_key"; - const VALUE: &'static str = "contract_hash"; +impl KeyValueLabels for EntityVersionLabels { + const KEY: &'static str = "entity_version_key"; + const VALUE: &'static str = "addressable_entity_hash"; } #[cfg(feature = "json-schema")] -impl KeyValueJsonSchema for ContractVersionLabels { - const JSON_SCHEMA_KV_NAME: Option<&'static str> = Some("ContractVersionAndHash"); +impl KeyValueJsonSchema for EntityVersionLabels { + const JSON_SCHEMA_KV_NAME: Option<&'static str> = Some("EntityVersionAndHash"); } /// Collection of named groups. #[derive(Clone, PartialEq, Eq, Default, Serialize, Deserialize, Debug)] @@ -374,35 +387,35 @@ impl From>> for Groups { #[cfg_attr( feature = "json-schema", derive(JsonSchema), - schemars(description = "The hex-encoded address of the contract package.") + schemars(description = "The hex-encoded address of the Package.") )] -pub struct ContractPackageHash( +pub struct PackageHash( #[cfg_attr(feature = "json-schema", schemars(skip, with = "String"))] HashAddr, ); -impl ContractPackageHash { - /// Constructs a new `ContractPackageHash` from the raw bytes of the contract package hash. - pub const fn new(value: HashAddr) -> ContractPackageHash { - ContractPackageHash(value) +impl PackageHash { + /// Constructs a new `PackageHash` from the raw bytes of the package hash. + pub const fn new(value: HashAddr) -> PackageHash { + PackageHash(value) } - /// Returns the raw bytes of the contract hash as an array. + /// Returns the raw bytes of the entity hash as an array. pub fn value(&self) -> HashAddr { self.0 } - /// Returns the raw bytes of the contract hash as a `slice`. + /// Returns the raw bytes of the entity hash as a `slice`. pub fn as_bytes(&self) -> &[u8] { &self.0 } - /// Formats the `ContractPackageHash` for users getting and putting. + /// Formats the `PackageHash` for users getting and putting. pub fn to_formatted_string(self) -> String { format!("{}{}", PACKAGE_STRING_PREFIX, base16::encode_lower(&self.0),) } /// Parses a string formatted as per `Self::to_formatted_string()` into a - /// `ContractPackageHash`. + /// `PackageHash`. pub fn from_formatted_str(input: &str) -> Result { let remainder = input .strip_prefix(PACKAGE_STRING_PREFIX) @@ -413,7 +426,7 @@ impl ContractPackageHash { .unwrap_or(remainder); let bytes = HashAddr::try_from(checksummed_hex::decode(hex_addr)?.as_ref())?; - Ok(ContractPackageHash(bytes)) + Ok(PackageHash(bytes)) } /// Parses a `PublicKey` and outputs the corresponding account hash. @@ -446,25 +459,25 @@ impl ContractPackageHash { } } -impl Display for ContractPackageHash { +impl Display for PackageHash { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "{}", base16::encode_lower(&self.0)) } } -impl Debug for ContractPackageHash { +impl Debug for PackageHash { fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { - write!(f, "ContractPackageHash({})", base16::encode_lower(&self.0)) + write!(f, "PackageHash({})", base16::encode_lower(&self.0)) } } -impl CLTyped for ContractPackageHash { +impl CLTyped for PackageHash { fn cl_type() -> CLType { CLType::ByteArray(KEY_HASH_LENGTH as u32) } } -impl ToBytes for ContractPackageHash { +impl ToBytes for PackageHash { #[inline(always)] fn to_bytes(&self) -> Result, bytesrepr::Error> { self.0.to_bytes() @@ -482,20 +495,20 @@ impl ToBytes for ContractPackageHash { } } -impl FromBytes for ContractPackageHash { +impl FromBytes for PackageHash { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { let (bytes, rem) = FromBytes::from_bytes(bytes)?; - Ok((ContractPackageHash::new(bytes), rem)) + Ok((PackageHash::new(bytes), rem)) } } -impl From<[u8; 32]> for ContractPackageHash { +impl From<[u8; 32]> for PackageHash { fn from(bytes: [u8; 32]) -> Self { - ContractPackageHash(bytes) + PackageHash(bytes) } } -impl Serialize for ContractPackageHash { +impl Serialize for PackageHash { fn serialize(&self, serializer: S) -> Result { if serializer.is_human_readable() { self.to_formatted_string().serialize(serializer) @@ -505,134 +518,169 @@ impl Serialize for ContractPackageHash { } } -impl<'de> Deserialize<'de> for ContractPackageHash { +impl<'de> Deserialize<'de> for PackageHash { fn deserialize>(deserializer: D) -> Result { if deserializer.is_human_readable() { let formatted_string = String::deserialize(deserializer)?; - ContractPackageHash::from_formatted_str(&formatted_string).map_err(SerdeError::custom) + PackageHash::from_formatted_str(&formatted_string).map_err(SerdeError::custom) } else { let bytes = HashAddr::deserialize(deserializer)?; - Ok(ContractPackageHash(bytes)) + Ok(PackageHash(bytes)) } } } -impl AsRef<[u8]> for ContractPackageHash { +impl AsRef<[u8]> for PackageHash { fn as_ref(&self) -> &[u8] { self.0.as_ref() } } -impl TryFrom<&[u8]> for ContractPackageHash { +impl TryFrom<&[u8]> for PackageHash { type Error = TryFromSliceForPackageHashError; fn try_from(bytes: &[u8]) -> Result { HashAddr::try_from(bytes) - .map(ContractPackageHash::new) + .map(PackageHash::new) .map_err(|_| TryFromSliceForPackageHashError(())) } } -impl TryFrom<&Vec> for ContractPackageHash { +impl TryFrom<&Vec> for PackageHash { type Error = TryFromSliceForPackageHashError; fn try_from(bytes: &Vec) -> Result { HashAddr::try_from(bytes as &[u8]) - .map(ContractPackageHash::new) + .map(PackageHash::new) .map_err(|_| TryFromSliceForPackageHashError(())) } } -impl From<&PublicKey> for ContractPackageHash { +impl From<&PublicKey> for PackageHash { fn from(public_key: &PublicKey) -> Self { - ContractPackageHash::from_public_key(public_key, crypto::blake2b) + PackageHash::from_public_key(public_key, crypto::blake2b) } } -/// A enum to determine the lock status of the contract package. +/// A enum to determine the lock status of the package. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] -pub enum ContractPackageStatus { +pub enum PackageStatus { /// The package is locked and cannot be versioned. Locked, /// The package is unlocked and can be versioned. Unlocked, } -impl ContractPackageStatus { +impl PackageStatus { /// Create a new status flag based on a boolean value pub fn new(is_locked: bool) -> Self { if is_locked { - ContractPackageStatus::Locked + PackageStatus::Locked } else { - ContractPackageStatus::Unlocked + PackageStatus::Unlocked } } } -impl Default for ContractPackageStatus { +impl Default for PackageStatus { fn default() -> Self { Self::Unlocked } } -impl ToBytes for ContractPackageStatus { +impl ToBytes for PackageStatus { fn to_bytes(&self) -> Result, bytesrepr::Error> { let mut result = bytesrepr::allocate_buffer(self)?; match self { - ContractPackageStatus::Unlocked => result.append(&mut false.to_bytes()?), - ContractPackageStatus::Locked => result.append(&mut true.to_bytes()?), + PackageStatus::Unlocked => result.append(&mut false.to_bytes()?), + PackageStatus::Locked => result.append(&mut true.to_bytes()?), } Ok(result) } fn serialized_length(&self) -> usize { match self { - ContractPackageStatus::Unlocked => false.serialized_length(), - ContractPackageStatus::Locked => true.serialized_length(), + PackageStatus::Unlocked => false.serialized_length(), + PackageStatus::Locked => true.serialized_length(), } } fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { match self { - ContractPackageStatus::Locked => writer.push(u8::from(true)), - ContractPackageStatus::Unlocked => writer.push(u8::from(false)), + PackageStatus::Locked => writer.push(u8::from(true)), + PackageStatus::Unlocked => writer.push(u8::from(false)), } Ok(()) } } -impl FromBytes for ContractPackageStatus { +impl FromBytes for PackageStatus { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { let (val, bytes) = bool::from_bytes(bytes)?; - let status = ContractPackageStatus::new(val); + let status = PackageStatus::new(val); Ok((status, bytes)) } } -#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)] +#[allow(missing_docs)] +#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[repr(u8)] +pub enum PackageKindTag { + System = 0, + Account = 1, + SmartContract = 2, +} + +impl TryFrom for PackageKindTag { + type Error = bytesrepr::Error; + + fn try_from(value: u8) -> Result { + match value { + 0 => Ok(PackageKindTag::System), + 1 => Ok(PackageKindTag::Account), + 2 => Ok(PackageKindTag::SmartContract), + _ => Err(bytesrepr::Error::Formatting), + } + } +} + +#[cfg(any(feature = "testing", test))] +impl Distribution for Standard { + fn sample(&self, rng: &mut R) -> PackageKindTag { + match rng.gen_range(0..=1) { + 0 => PackageKindTag::System, + 1 => PackageKindTag::Account, + 2 => PackageKindTag::SmartContract, + _ => unreachable!(), + } + } +} + +#[derive( + Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Serialize, Deserialize, +)] #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] -/// The type of contract package. -pub enum ContractPackageKind { - /// Contract Packages associated with Wasm stored on chain. - Wasm, - /// Contract Package associated with a native contract implementation. - System(SystemContractType), - /// Contract Package associated with an Account hash. +/// The type of Package. +pub enum PackageKind { + /// Package associated with a native contract implementation. + System(SystemEntityType), + /// Package associated with an Account hash. Account(AccountHash), - /// Contract Packages from the previous format. + /// Packages associated with Wasm stored on chain. #[default] - Legacy, + SmartContract, } -impl ContractPackageKind { - /// Returns the Account hash associated with a Contract Package based on the package kind. +impl PackageKind { + /// Returns the Account hash associated with a Package based on the package kind. pub fn maybe_account_hash(&self) -> Option { match self { Self::Account(account_hash) => Some(*account_hash), - Self::Wasm | Self::System(_) | Self::Legacy => None, + Self::SmartContract | Self::System(_) => None, } } @@ -640,7 +688,7 @@ impl ContractPackageKind { pub fn associated_keys(&self) -> AssociatedKeys { match self { Self::Account(account_hash) => AssociatedKeys::new(*account_hash, Weight::new(1)), - Self::Wasm | Self::System(_) | Self::Legacy => AssociatedKeys::default(), + Self::SmartContract | Self::System(_) => AssociatedKeys::default(), } } @@ -651,12 +699,12 @@ impl ContractPackageKind { /// Returns if the current package is the system mint. pub fn is_system_mint(&self) -> bool { - matches!(self, Self::System(SystemContractType::Mint)) + matches!(self, Self::System(SystemEntityType::Mint)) } /// Returns if the current package is the system auction. pub fn is_system_auction(&self) -> bool { - matches!(self, Self::System(SystemContractType::Auction)) + matches!(self, Self::System(SystemEntityType::Auction)) } /// Returns if the current package is associated with the system addressable entity. @@ -673,7 +721,24 @@ impl ContractPackageKind { } } -impl ToBytes for ContractPackageKind { +impl Tagged for PackageKind { + fn tag(&self) -> PackageKindTag { + match self { + PackageKind::System(_) => PackageKindTag::System, + PackageKind::Account(_) => PackageKindTag::Account, + PackageKind::SmartContract => PackageKindTag::SmartContract, + } + } +} + +impl Tagged for PackageKind { + fn tag(&self) -> u8 { + let package_kind_tag: PackageKindTag = self.tag(); + package_kind_tag as u8 + } +} + +impl ToBytes for PackageKind { fn to_bytes(&self) -> Result, bytesrepr::Error> { let mut buffer = bytesrepr::allocate_buffer(self)?; self.write_bytes(&mut buffer)?; @@ -683,69 +748,79 @@ impl ToBytes for ContractPackageKind { fn serialized_length(&self) -> usize { U8_SERIALIZED_LENGTH + match self { - ContractPackageKind::Wasm | ContractPackageKind::Legacy => 0, - ContractPackageKind::System(system_contract_type) => { - system_contract_type.serialized_length() - } - ContractPackageKind::Account(account_hash) => account_hash.serialized_length(), + PackageKind::SmartContract => 0, + PackageKind::System(system_entity_type) => system_entity_type.serialized_length(), + PackageKind::Account(account_hash) => account_hash.serialized_length(), } } fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { match self { - ContractPackageKind::Wasm => PACKAGE_KIND_WASM_TAG.write_bytes(writer), - ContractPackageKind::System(system_contract_type) => { - PACKAGE_KIND_SYSTEM_CONTRACT_TAG.write_bytes(writer)?; - system_contract_type.write_bytes(writer) + PackageKind::SmartContract => { + writer.push(self.tag()); + Ok(()) + } + PackageKind::System(system_entity_type) => { + writer.push(self.tag()); + system_entity_type.write_bytes(writer) } - ContractPackageKind::Account(account_hash) => { - PACKAGE_KIND_ACCOUNT_TAG.write_bytes(writer)?; + PackageKind::Account(account_hash) => { + writer.push(self.tag()); account_hash.write_bytes(writer) } - ContractPackageKind::Legacy => PACKAGE_KIND_LEGACY_TAG.write_bytes(writer), } } } -impl FromBytes for ContractPackageKind { +impl FromBytes for PackageKind { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { let (tag, remainder) = u8::from_bytes(bytes)?; match tag { - PACKAGE_KIND_WASM_TAG => Ok((ContractPackageKind::Wasm, remainder)), - PACKAGE_KIND_SYSTEM_CONTRACT_TAG => { - let (system_contract_type, remainder) = SystemContractType::from_bytes(remainder)?; - Ok((ContractPackageKind::System(system_contract_type), remainder)) + tag if tag == PackageKindTag::System as u8 => { + let (entity_type, remainder) = SystemEntityType::from_bytes(remainder)?; + Ok((PackageKind::System(entity_type), remainder)) } - PACKAGE_KIND_ACCOUNT_TAG => { + tag if tag == PackageKindTag::Account as u8 => { let (account_hash, remainder) = AccountHash::from_bytes(remainder)?; - Ok((ContractPackageKind::Account(account_hash), remainder)) + Ok((PackageKind::Account(account_hash), remainder)) + } + tag if tag == PackageKindTag::SmartContract as u8 => { + Ok((PackageKind::SmartContract, remainder)) } - PACKAGE_KIND_LEGACY_TAG => Ok((ContractPackageKind::Legacy, remainder)), _ => Err(bytesrepr::Error::Formatting), } } } -impl Display for ContractPackageKind { +impl Display for PackageKind { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { - ContractPackageKind::Wasm => { - write!(f, "ContractPackageKind:Wasm") - } - ContractPackageKind::System(system_contract) => { - write!(f, "ContractPackageKind:System({})", system_contract) + PackageKind::SmartContract => { + write!(f, "PackageKind:Wasm") } - ContractPackageKind::Account(account_hash) => { - write!(f, "ContractPackageKind:Account({})", account_hash) + PackageKind::System(system_entity) => { + write!(f, "PackageKind:System({})", system_entity) } - ContractPackageKind::Legacy => { - write!(f, "ContractPackageKind:Legacy") + PackageKind::Account(account_hash) => { + write!(f, "PackageKind:Account({})", account_hash) } } } } -/// Contract definition, metadata, and security container. +#[cfg(any(feature = "testing", test))] +impl Distribution for Standard { + fn sample(&self, rng: &mut R) -> PackageKind { + match rng.gen_range(0..=2) { + 0 => PackageKind::System(rng.gen()), + 1 => PackageKind::Account(rng.gen()), + 2 => PackageKind::SmartContract, + _ => unreachable!(), + } + } +} + +/// Entity definition, metadata, and security container. #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)] #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] @@ -753,18 +828,18 @@ pub struct Package { /// Key used to add or disable versions. access_key: URef, /// All versions (enabled & disabled). - versions: ContractVersions, - /// Collection of disabled contract versions. The runtime will not permit disabled contract + versions: EntityVersions, + /// Collection of disabled entity versions. The runtime will not permit disabled entity /// versions to be executed. - disabled_versions: BTreeSet, + disabled_versions: BTreeSet, /// Mapping maintaining the set of URefs associated with each "user group". This can be used to - /// control access to methods in a particular version of the contract. A method is callable by + /// control access to methods in a particular version of the entity. A method is callable by /// any context which "knows" any of the URefs associated with the method's user group. groups: Groups, - /// A flag that determines whether a contract is locked - lock_status: ContractPackageStatus, + /// A flag that determines whether a entity is locked + lock_status: PackageStatus, /// The kind of package. - contract_package_kind: ContractPackageKind, + package_kind: PackageKind, } impl CLTyped for Package { @@ -777,11 +852,11 @@ impl Package { /// Create new `Package` (with no versions) from given access key. pub fn new( access_key: URef, - versions: ContractVersions, - disabled_versions: BTreeSet, + versions: EntityVersions, + disabled_versions: BTreeSet, groups: Groups, - lock_status: ContractPackageStatus, - contract_package_kind: ContractPackageKind, + lock_status: PackageStatus, + package_kind: PackageKind, ) -> Self { Package { access_key, @@ -789,116 +864,119 @@ impl Package { disabled_versions, groups, lock_status, - contract_package_kind, + package_kind, } } - /// Enable the contract version corresponding to the given hash (if it exists). - pub fn enable_version(&mut self, contract_hash: ContractHash) -> Result<(), Error> { - let contract_version_key = self - .find_contract_version_key_by_hash(&contract_hash) + /// Enable the entity version corresponding to the given hash (if it exists). + pub fn enable_version(&mut self, entity_hash: AddressableEntityHash) -> Result<(), Error> { + let entity_version_key = self + .find_entity_version_key_by_hash(&entity_hash) .copied() - .ok_or(Error::ContractNotFound)?; + .ok_or(Error::EntityNotFound)?; - self.disabled_versions.remove(&contract_version_key); + self.disabled_versions.remove(&entity_version_key); Ok(()) } - /// Get the access key for this contract. + /// Get the access key for this entity. pub fn access_key(&self) -> URef { self.access_key } - /// Get the mutable group definitions for this contract. + /// Get the mutable group definitions for this entity. pub fn groups_mut(&mut self) -> &mut Groups { &mut self.groups } - /// Get the group definitions for this contract. + /// Get the group definitions for this entity. pub fn groups(&self) -> &Groups { &self.groups } - /// Adds new group to this contract. + /// Adds new group to this entity. pub fn add_group(&mut self, group: Group, urefs: BTreeSet) { let v = self.groups.0.entry(group).or_insert_with(Default::default); v.extend(urefs) } - /// Lookup the contract hash for a given contract version (if present) - pub fn lookup_contract_hash( + /// Lookup the entity hash for a given entity version (if present) + pub fn lookup_entity_hash( &self, - contract_version_key: ContractVersionKey, - ) -> Option<&ContractHash> { - if !self.is_version_enabled(contract_version_key) { + entity_version_key: EntityVersionKey, + ) -> Option<&AddressableEntityHash> { + if !self.is_version_enabled(entity_version_key) { return None; } - self.versions.0.get(&contract_version_key) + self.versions.0.get(&entity_version_key) } - /// Checks if the given contract version exists and is available for use. - pub fn is_version_enabled(&self, contract_version_key: ContractVersionKey) -> bool { - !self.disabled_versions.contains(&contract_version_key) - && self.versions.0.contains_key(&contract_version_key) + /// Checks if the given entity version exists and is available for use. + pub fn is_version_enabled(&self, entity_version_key: EntityVersionKey) -> bool { + !self.disabled_versions.contains(&entity_version_key) + && self.versions.0.contains_key(&entity_version_key) } - /// Returns `true` if the given contract hash exists and is enabled. - pub fn is_contract_enabled(&self, contract_hash: &ContractHash) -> bool { - match self.find_contract_version_key_by_hash(contract_hash) { + /// Returns `true` if the given entity hash exists and is enabled. + pub fn is_entity_enabled(&self, entity_hash: &AddressableEntityHash) -> bool { + match self.find_entity_version_key_by_hash(entity_hash) { Some(version_key) => !self.disabled_versions.contains(version_key), None => false, } } - /// Insert a new contract version; the next sequential version number will be issued. - pub fn insert_contract_version( + /// Insert a new entity version; the next sequential version number will be issued. + pub fn insert_entity_version( &mut self, protocol_version_major: ProtocolVersionMajor, - contract_hash: ContractHash, - ) -> ContractVersionKey { - let contract_version = self.next_contract_version_for(protocol_version_major); - let key = ContractVersionKey::new(protocol_version_major, contract_version); - self.versions.0.insert(key, contract_hash); + entity_hash: AddressableEntityHash, + ) -> EntityVersionKey { + let contract_version = self.next_entity_version_for(protocol_version_major); + let key = EntityVersionKey::new(protocol_version_major, contract_version); + self.versions.0.insert(key, entity_hash); key } - /// Disable the contract version corresponding to the given hash (if it exists). - pub fn disable_contract_version(&mut self, contract_hash: ContractHash) -> Result<(), Error> { - let contract_version_key = self + /// Disable the entity version corresponding to the given hash (if it exists). + pub fn disable_entity_version( + &mut self, + entity_hash: AddressableEntityHash, + ) -> Result<(), Error> { + let entity_version_key = self .versions .0 .iter() - .filter_map(|(k, v)| if *v == contract_hash { Some(*k) } else { None }) + .filter_map(|(k, v)| if *v == entity_hash { Some(*k) } else { None }) .next() - .ok_or(Error::ContractNotFound)?; + .ok_or(Error::EntityNotFound)?; - if !self.disabled_versions.contains(&contract_version_key) { - self.disabled_versions.insert(contract_version_key); + if !self.disabled_versions.contains(&entity_version_key) { + self.disabled_versions.insert(entity_version_key); } Ok(()) } - fn find_contract_version_key_by_hash( + fn find_entity_version_key_by_hash( &self, - contract_hash: &ContractHash, - ) -> Option<&ContractVersionKey> { + entity_hash: &AddressableEntityHash, + ) -> Option<&EntityVersionKey> { self.versions .0 .iter() - .filter_map(|(k, v)| if v == contract_hash { Some(k) } else { None }) + .filter_map(|(k, v)| if v == entity_hash { Some(k) } else { None }) .next() } - /// Returns reference to all of this contract's versions. - pub fn versions(&self) -> &ContractVersions { + /// Returns reference to all of this entity's versions. + pub fn versions(&self) -> &EntityVersions { &self.versions } - /// Returns all of this contract's enabled contract versions. - pub fn enabled_versions(&self) -> ContractVersions { - let mut ret = ContractVersions::new(); + /// Returns all of this entity's enabled entity versions. + pub fn enabled_versions(&self) -> EntityVersions { + let mut ret = EntityVersions::new(); for version in &self.versions.0 { if !self.is_version_enabled(*version.0) { continue; @@ -908,41 +986,41 @@ impl Package { ret } - /// Returns mutable reference to all of this contract's versions (enabled and disabled). - pub fn versions_mut(&mut self) -> &mut ContractVersions { + /// Returns mutable reference to all of this entity's versions (enabled and disabled). + pub fn versions_mut(&mut self) -> &mut EntityVersions { &mut self.versions } - /// Consumes the object and returns all of this contract's versions (enabled and disabled). - pub fn take_versions(self) -> ContractVersions { + /// Consumes the object and returns all of this entity's versions (enabled and disabled). + pub fn take_versions(self) -> EntityVersions { self.versions } - /// Returns all of this contract's disabled versions. - pub fn disabled_versions(&self) -> &BTreeSet { + /// Returns all of this entity's disabled versions. + pub fn disabled_versions(&self) -> &BTreeSet { &self.disabled_versions } - /// Returns mut reference to all of this contract's disabled versions. - pub fn disabled_versions_mut(&mut self) -> &mut BTreeSet { + /// Returns mut reference to all of this entity's disabled versions. + pub fn disabled_versions_mut(&mut self) -> &mut BTreeSet { &mut self.disabled_versions } - /// Removes a group from this contract (if it exists). + /// Removes a group from this entity (if it exists). pub fn remove_group(&mut self, group: &Group) -> bool { self.groups.0.remove(group).is_some() } - /// Gets the next available contract version for the given protocol version - fn next_contract_version_for(&self, protocol_version: ProtocolVersionMajor) -> ContractVersion { + /// Gets the next available entity version for the given protocol version + fn next_entity_version_for(&self, protocol_version: ProtocolVersionMajor) -> EntityVersion { let current_version = self .versions .0 .keys() .rev() - .find_map(|&contract_version_key| { - if contract_version_key.protocol_version_major() == protocol_version { - Some(contract_version_key.contract_version()) + .find_map(|&entity_version_key| { + if entity_version_key.protocol_version_major() == protocol_version { + Some(entity_version_key.entity_version()) } else { None } @@ -952,42 +1030,58 @@ impl Package { current_version + 1 } - /// Return the contract version key for the newest enabled contract version. - pub fn current_contract_version(&self) -> Option { + /// Return the entity version key for the newest enabled entity version. + pub fn current_entity_version(&self) -> Option { self.enabled_versions().0.keys().next_back().copied() } - /// Return the contract hash for the newest enabled contract version. - pub fn current_contract_hash(&self) -> Option { + /// Return the entity hash for the newest enabled entity version. + pub fn current_entity_hash(&self) -> Option { self.enabled_versions().0.values().next_back().copied() } - /// Return the lock status of the contract package. + /// Return the Key representation for the previous entity. + pub fn previous_entity_key(&self) -> Option { + if let Some(previous_entity_hash) = self.current_entity_hash() { + return Some(Key::addressable_entity_key( + self.get_package_kind().tag(), + previous_entity_hash, + )); + } + None + } + + /// Return the lock status of the entity package. pub fn is_locked(&self) -> bool { + if self.versions.0.is_empty() { + return false; + } + match self.lock_status { - ContractPackageStatus::Unlocked => false, - ContractPackageStatus::Locked => true, + PackageStatus::Unlocked => false, + PackageStatus::Locked => true, } } + // TODO: Check the history of this. /// Return the package status itself - pub fn get_lock_status(&self) -> ContractPackageStatus { + pub fn get_lock_status(&self) -> PackageStatus { self.lock_status.clone() } - /// Returns the kind of Contract Package. - pub fn get_package_kind(&self) -> ContractPackageKind { - self.contract_package_kind.clone() + /// Returns the kind of Package. + pub fn get_package_kind(&self) -> PackageKind { + self.package_kind } - /// Returns whether the contract package is of the legacy format. - pub fn is_legacy(&self) -> bool { - matches!(self.contract_package_kind, ContractPackageKind::Legacy) + /// Is the given Package associated to an Account. + pub fn is_account_kind(&self) -> bool { + matches!(self.package_kind, PackageKind::Account(_)) } - /// Update the contract package kind. - pub fn update_package_kind(&mut self, new_package_kind: ContractPackageKind) { - self.contract_package_kind = new_package_kind + /// Update the entity package kind. + pub fn update_package_kind(&mut self, new_package_kind: PackageKind) { + self.package_kind = new_package_kind } } @@ -1004,7 +1098,7 @@ impl ToBytes for Package { + self.disabled_versions.serialized_length() + self.groups.serialized_length() + self.lock_status.serialized_length() - + self.contract_package_kind.serialized_length() + + self.package_kind.serialized_length() } fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { @@ -1013,7 +1107,7 @@ impl ToBytes for Package { self.disabled_versions().write_bytes(writer)?; self.groups().write_bytes(writer)?; self.lock_status.write_bytes(writer)?; - self.contract_package_kind.write_bytes(writer)?; + self.package_kind.write_bytes(writer)?; Ok(()) } } @@ -1021,19 +1115,18 @@ impl ToBytes for Package { impl FromBytes for Package { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { let (access_key, bytes) = URef::from_bytes(bytes)?; - let (versions, bytes) = ContractVersions::from_bytes(bytes)?; - let (disabled_versions, bytes) = BTreeSet::::from_bytes(bytes)?; + let (versions, bytes) = EntityVersions::from_bytes(bytes)?; + let (disabled_versions, bytes) = BTreeSet::::from_bytes(bytes)?; let (groups, bytes) = Groups::from_bytes(bytes)?; - let (lock_status, bytes) = ContractPackageStatus::from_bytes(bytes)?; - let (contract_package_kind, bytes) = - ContractPackageKind::from_bytes(bytes).unwrap_or_default(); + let (lock_status, bytes) = PackageStatus::from_bytes(bytes)?; + let (package_kind, bytes) = PackageKind::from_bytes(bytes)?; let result = Package { access_key, versions, disabled_versions, groups, lock_status, - contract_package_kind, + package_kind, }; Ok((result, bytes)) @@ -1046,22 +1139,22 @@ mod tests { use super::*; use crate::{ - AccessRights, ContractVersionKey, EntryPoint, EntryPointAccess, EntryPointType, Parameter, + AccessRights, EntityVersionKey, EntryPoint, EntryPointAccess, EntryPointType, Parameter, ProtocolVersion, URef, }; use alloc::borrow::ToOwned; - const CONTRACT_HASH_V1: ContractHash = ContractHash::new([42; 32]); - const CONTRACT_HASH_V2: ContractHash = ContractHash::new([84; 32]); + const ENTITY_HASH_V1: AddressableEntityHash = AddressableEntityHash::new([42; 32]); + const ENTITY_HASH_V2: AddressableEntityHash = AddressableEntityHash::new([84; 32]); - fn make_contract_package_with_two_versions() -> Package { - let mut contract_package = Package::new( + fn make_package_with_two_versions() -> Package { + let mut package = Package::new( URef::new([0; 32], AccessRights::NONE), - ContractVersions::default(), + EntityVersions::default(), BTreeSet::new(), Groups::default(), - ContractPackageStatus::default(), - ContractPackageKind::Wasm, + PackageStatus::default(), + PackageKind::SmartContract, ); // add groups @@ -1072,11 +1165,11 @@ mod tests { ret }; - contract_package + package .groups_mut() .insert(Group::new("Group 1"), group_urefs.clone()); - contract_package + package .groups_mut() .insert(Group::new("Group 2"), group_urefs); } @@ -1105,340 +1198,320 @@ mod tests { let protocol_version = ProtocolVersion::V1_0_0; - let v1 = contract_package - .insert_contract_version(protocol_version.value().major, CONTRACT_HASH_V1); - let v2 = contract_package - .insert_contract_version(protocol_version.value().major, CONTRACT_HASH_V2); + let v1 = package.insert_entity_version(protocol_version.value().major, ENTITY_HASH_V1); + let v2 = package.insert_entity_version(protocol_version.value().major, ENTITY_HASH_V2); assert!(v2 > v1); - contract_package + package } #[test] - fn next_contract_version() { + fn next_entity_version() { let major = 1; - let mut contract_package = Package::new( + let mut package = Package::new( URef::new([0; 32], AccessRights::NONE), - ContractVersions::default(), + EntityVersions::default(), BTreeSet::default(), Groups::default(), - ContractPackageStatus::default(), - ContractPackageKind::Wasm, + PackageStatus::default(), + PackageKind::SmartContract, ); - assert_eq!(contract_package.next_contract_version_for(major), 1); + assert_eq!(package.next_entity_version_for(major), 1); - let next_version = contract_package.insert_contract_version(major, [123; 32].into()); - assert_eq!(next_version, ContractVersionKey::new(major, 1)); - assert_eq!(contract_package.next_contract_version_for(major), 2); - let next_version_2 = contract_package.insert_contract_version(major, [124; 32].into()); - assert_eq!(next_version_2, ContractVersionKey::new(major, 2)); + let next_version = package.insert_entity_version(major, [123; 32].into()); + assert_eq!(next_version, EntityVersionKey::new(major, 1)); + assert_eq!(package.next_entity_version_for(major), 2); + let next_version_2 = package.insert_entity_version(major, [124; 32].into()); + assert_eq!(next_version_2, EntityVersionKey::new(major, 2)); let major = 2; - assert_eq!(contract_package.next_contract_version_for(major), 1); - let next_version_3 = contract_package.insert_contract_version(major, [42; 32].into()); - assert_eq!(next_version_3, ContractVersionKey::new(major, 1)); + assert_eq!(package.next_entity_version_for(major), 1); + let next_version_3 = package.insert_entity_version(major, [42; 32].into()); + assert_eq!(next_version_3, EntityVersionKey::new(major, 1)); } #[test] fn roundtrip_serialization() { - let contract_package = make_contract_package_with_two_versions(); - let bytes = contract_package.to_bytes().expect("should serialize"); + let package = make_package_with_two_versions(); + let bytes = package.to_bytes().expect("should serialize"); let (decoded_package, rem) = Package::from_bytes(&bytes).expect("should deserialize"); - assert_eq!(contract_package, decoded_package); + assert_eq!(package, decoded_package); assert_eq!(rem.len(), 0); } #[test] fn should_remove_group() { - let mut contract_package = make_contract_package_with_two_versions(); + let mut package = make_package_with_two_versions(); - assert!(!contract_package.remove_group(&Group::new("Non-existent group"))); - assert!(contract_package.remove_group(&Group::new("Group 1"))); - assert!(!contract_package.remove_group(&Group::new("Group 1"))); // Group no longer exists + assert!(!package.remove_group(&Group::new("Non-existent group"))); + assert!(package.remove_group(&Group::new("Group 1"))); + assert!(!package.remove_group(&Group::new("Group 1"))); // Group no longer exists } #[test] - fn should_disable_and_enable_contract_version() { - const CONTRACT_HASH: ContractHash = ContractHash::new([123; 32]); + fn should_disable_and_enable_entity_version() { + const ENTITY_HASH: AddressableEntityHash = AddressableEntityHash::new([123; 32]); - let mut contract_package = make_contract_package_with_two_versions(); + let mut package = make_package_with_two_versions(); assert!( - !contract_package.is_contract_enabled(&CONTRACT_HASH), - "nonexisting contract contract should return false" + !package.is_entity_enabled(&ENTITY_HASH), + "nonexisting entity should return false" ); assert_eq!( - contract_package.current_contract_version(), - Some(ContractVersionKey::new(1, 2)) - ); - assert_eq!( - contract_package.current_contract_hash(), - Some(CONTRACT_HASH_V2) + package.current_entity_version(), + Some(EntityVersionKey::new(1, 2)) ); + assert_eq!(package.current_entity_hash(), Some(ENTITY_HASH_V2)); assert_eq!( - contract_package.versions(), - &ContractVersions::from(BTreeMap::from_iter([ - (ContractVersionKey::new(1, 1), CONTRACT_HASH_V1), - (ContractVersionKey::new(1, 2), CONTRACT_HASH_V2) + package.versions(), + &EntityVersions::from(BTreeMap::from_iter([ + (EntityVersionKey::new(1, 1), ENTITY_HASH_V1), + (EntityVersionKey::new(1, 2), ENTITY_HASH_V2) ])), ); assert_eq!( - contract_package.enabled_versions(), - ContractVersions::from(BTreeMap::from_iter([ - (ContractVersionKey::new(1, 1), CONTRACT_HASH_V1), - (ContractVersionKey::new(1, 2), CONTRACT_HASH_V2) + package.enabled_versions(), + EntityVersions::from(BTreeMap::from_iter([ + (EntityVersionKey::new(1, 1), ENTITY_HASH_V1), + (EntityVersionKey::new(1, 2), ENTITY_HASH_V2) ])), ); - assert!(!contract_package.is_contract_enabled(&CONTRACT_HASH)); + assert!(!package.is_entity_enabled(&ENTITY_HASH)); assert_eq!( - contract_package.disable_contract_version(CONTRACT_HASH), - Err(Error::ContractNotFound), - "should return contract not found error" + package.disable_entity_version(ENTITY_HASH), + Err(Error::EntityNotFound), + "should return entity not found error" ); assert!( - !contract_package.is_contract_enabled(&CONTRACT_HASH), - "disabling missing contract shouldnt change outcome" + !package.is_entity_enabled(&ENTITY_HASH), + "disabling missing entity shouldnt change outcome" ); - let next_version = contract_package.insert_contract_version(1, CONTRACT_HASH); + let next_version = package.insert_entity_version(1, ENTITY_HASH); assert!( - contract_package.is_version_enabled(next_version), + package.is_version_enabled(next_version), "version should exist and be enabled" ); - assert!(contract_package.is_contract_enabled(&CONTRACT_HASH)); + assert!(package.is_entity_enabled(&ENTITY_HASH)); assert!( - contract_package.is_contract_enabled(&CONTRACT_HASH), - "contract should be enabled" + package.is_entity_enabled(&ENTITY_HASH), + "entity should be enabled" ); assert_eq!( - contract_package.disable_contract_version(CONTRACT_HASH), + package.disable_entity_version(ENTITY_HASH), Ok(()), "should be able to disable version" ); - assert!(!contract_package.is_contract_enabled(&CONTRACT_HASH)); + assert!(!package.is_entity_enabled(&ENTITY_HASH)); assert!( - !contract_package.is_contract_enabled(&CONTRACT_HASH), - "contract should be disabled" + !package.is_entity_enabled(&ENTITY_HASH), + "entity should be disabled" ); assert_eq!( - contract_package.lookup_contract_hash(next_version), + package.lookup_entity_hash(next_version), None, - "should not return disabled contract version" + "should not return disabled entity version" ); assert!( - !contract_package.is_version_enabled(next_version), + !package.is_version_enabled(next_version), "version should not be enabled" ); assert_eq!( - contract_package.current_contract_version(), - Some(ContractVersionKey::new(1, 2)) + package.current_entity_version(), + Some(EntityVersionKey::new(1, 2)) ); + assert_eq!(package.current_entity_hash(), Some(ENTITY_HASH_V2)); assert_eq!( - contract_package.current_contract_hash(), - Some(CONTRACT_HASH_V2) - ); - assert_eq!( - contract_package.versions(), - &ContractVersions::from(BTreeMap::from_iter([ - (ContractVersionKey::new(1, 1), CONTRACT_HASH_V1), - (ContractVersionKey::new(1, 2), CONTRACT_HASH_V2), - (next_version, CONTRACT_HASH), + package.versions(), + &EntityVersions::from(BTreeMap::from_iter([ + (EntityVersionKey::new(1, 1), ENTITY_HASH_V1), + (EntityVersionKey::new(1, 2), ENTITY_HASH_V2), + (next_version, ENTITY_HASH), ])), ); assert_eq!( - contract_package.enabled_versions(), - ContractVersions::from(BTreeMap::from_iter([ - (ContractVersionKey::new(1, 1), CONTRACT_HASH_V1), - (ContractVersionKey::new(1, 2), CONTRACT_HASH_V2), + package.enabled_versions(), + EntityVersions::from(BTreeMap::from_iter([ + (EntityVersionKey::new(1, 1), ENTITY_HASH_V1), + (EntityVersionKey::new(1, 2), ENTITY_HASH_V2), ])), ); assert_eq!( - contract_package.disabled_versions(), + package.disabled_versions(), &BTreeSet::from_iter([next_version]), ); assert_eq!( - contract_package.current_contract_version(), - Some(ContractVersionKey::new(1, 2)) - ); - assert_eq!( - contract_package.current_contract_hash(), - Some(CONTRACT_HASH_V2) + package.current_entity_version(), + Some(EntityVersionKey::new(1, 2)) ); + assert_eq!(package.current_entity_hash(), Some(ENTITY_HASH_V2)); assert_eq!( - contract_package.disable_contract_version(CONTRACT_HASH_V2), + package.disable_entity_version(ENTITY_HASH_V2), Ok(()), "should be able to disable version 2" ); assert_eq!( - contract_package.enabled_versions(), - ContractVersions::from(BTreeMap::from_iter([( - ContractVersionKey::new(1, 1), - CONTRACT_HASH_V1 + package.enabled_versions(), + EntityVersions::from(BTreeMap::from_iter([( + EntityVersionKey::new(1, 1), + ENTITY_HASH_V1 ),])), ); assert_eq!( - contract_package.current_contract_version(), - Some(ContractVersionKey::new(1, 1)) - ); - assert_eq!( - contract_package.current_contract_hash(), - Some(CONTRACT_HASH_V1) + package.current_entity_version(), + Some(EntityVersionKey::new(1, 1)) ); + assert_eq!(package.current_entity_hash(), Some(ENTITY_HASH_V1)); assert_eq!( - contract_package.disabled_versions(), - &BTreeSet::from_iter([next_version, ContractVersionKey::new(1, 2)]), + package.disabled_versions(), + &BTreeSet::from_iter([next_version, EntityVersionKey::new(1, 2)]), ); - assert_eq!(contract_package.enable_version(CONTRACT_HASH_V2), Ok(()),); + assert_eq!(package.enable_version(ENTITY_HASH_V2), Ok(()),); assert_eq!( - contract_package.enabled_versions(), - ContractVersions::from(BTreeMap::from_iter([ - (ContractVersionKey::new(1, 1), CONTRACT_HASH_V1), - (ContractVersionKey::new(1, 2), CONTRACT_HASH_V2), + package.enabled_versions(), + EntityVersions::from(BTreeMap::from_iter([ + (EntityVersionKey::new(1, 1), ENTITY_HASH_V1), + (EntityVersionKey::new(1, 2), ENTITY_HASH_V2), ])), ); assert_eq!( - contract_package.disabled_versions(), + package.disabled_versions(), &BTreeSet::from_iter([next_version]) ); - assert_eq!( - contract_package.current_contract_hash(), - Some(CONTRACT_HASH_V2) - ); + assert_eq!(package.current_entity_hash(), Some(ENTITY_HASH_V2)); - assert_eq!(contract_package.enable_version(CONTRACT_HASH), Ok(()),); + assert_eq!(package.enable_version(ENTITY_HASH), Ok(()),); assert_eq!( - contract_package.enable_version(CONTRACT_HASH), + package.enable_version(ENTITY_HASH), Ok(()), - "enabling a contract twice should be a noop" + "enabling a entity twice should be a noop" ); assert_eq!( - contract_package.enabled_versions(), - ContractVersions::from(BTreeMap::from_iter([ - (ContractVersionKey::new(1, 1), CONTRACT_HASH_V1), - (ContractVersionKey::new(1, 2), CONTRACT_HASH_V2), - (next_version, CONTRACT_HASH), + package.enabled_versions(), + EntityVersions::from(BTreeMap::from_iter([ + (EntityVersionKey::new(1, 1), ENTITY_HASH_V1), + (EntityVersionKey::new(1, 2), ENTITY_HASH_V2), + (next_version, ENTITY_HASH), ])), ); - assert_eq!(contract_package.disabled_versions(), &BTreeSet::new(),); + assert_eq!(package.disabled_versions(), &BTreeSet::new(),); - assert_eq!( - contract_package.current_contract_hash(), - Some(CONTRACT_HASH) - ); + assert_eq!(package.current_entity_hash(), Some(ENTITY_HASH)); } #[test] fn should_not_allow_to_enable_non_existing_version() { - let mut contract_package = make_contract_package_with_two_versions(); + let mut package = make_package_with_two_versions(); assert_eq!( - contract_package.enable_version(ContractHash::default()), - Err(Error::ContractNotFound), + package.enable_version(AddressableEntityHash::default()), + Err(Error::EntityNotFound), ); } #[test] - fn contract_package_hash_from_slice() { + fn package_hash_from_slice() { let bytes: Vec = (0..32).collect(); - let contract_hash = HashAddr::try_from(&bytes[..]).expect("should create contract hash"); - let contract_hash = ContractPackageHash::new(contract_hash); - assert_eq!(&bytes, &contract_hash.as_bytes()); + let package_hash = HashAddr::try_from(&bytes[..]).expect("should create package hash"); + let package_hash = PackageHash::new(package_hash); + assert_eq!(&bytes, &package_hash.as_bytes()); } #[test] - fn contract_package_hash_from_str() { - let contract_package_hash = ContractPackageHash::new([3; 32]); - let encoded = contract_package_hash.to_formatted_string(); - let decoded = ContractPackageHash::from_formatted_str(&encoded).unwrap(); - assert_eq!(contract_package_hash, decoded); + fn package_hash_from_str() { + let package_hash = PackageHash::new([3; 32]); + let encoded = package_hash.to_formatted_string(); + let decoded = PackageHash::from_formatted_str(&encoded).unwrap(); + assert_eq!(package_hash, decoded); let invalid_prefix = "contract-package0000000000000000000000000000000000000000000000000000000000000000"; assert!(matches!( - ContractPackageHash::from_formatted_str(invalid_prefix).unwrap_err(), + PackageHash::from_formatted_str(invalid_prefix).unwrap_err(), FromStrError::InvalidPrefix )); let short_addr = "contract-package-00000000000000000000000000000000000000000000000000000000000000"; assert!(matches!( - ContractPackageHash::from_formatted_str(short_addr).unwrap_err(), + PackageHash::from_formatted_str(short_addr).unwrap_err(), FromStrError::Hash(_) )); let long_addr = "contract-package-000000000000000000000000000000000000000000000000000000000000000000"; assert!(matches!( - ContractPackageHash::from_formatted_str(long_addr).unwrap_err(), + PackageHash::from_formatted_str(long_addr).unwrap_err(), FromStrError::Hash(_) )); let invalid_hex = "contract-package-000000000000000000000000000000000000000000000000000000000000000g"; assert!(matches!( - ContractPackageHash::from_formatted_str(invalid_hex).unwrap_err(), + PackageHash::from_formatted_str(invalid_hex).unwrap_err(), FromStrError::Hex(_) )); } #[test] - fn contract_package_hash_from_legacy_str() { - let contract_package_hash = ContractPackageHash([3; 32]); - let hex_addr = contract_package_hash.to_string(); + fn package_hash_from_legacy_str() { + let package_hash = PackageHash([3; 32]); + let hex_addr = package_hash.to_string(); let legacy_encoded = format!("contract-package-wasm{}", hex_addr); - let decoded_from_legacy = ContractPackageHash::from_formatted_str(&legacy_encoded) + let decoded_from_legacy = PackageHash::from_formatted_str(&legacy_encoded) .expect("should accept legacy prefixed string"); assert_eq!( - contract_package_hash, decoded_from_legacy, + package_hash, decoded_from_legacy, "decoded_from_legacy should equal decoded" ); let invalid_prefix = "contract-packagewasm0000000000000000000000000000000000000000000000000000000000000000"; assert!(matches!( - ContractPackageHash::from_formatted_str(invalid_prefix).unwrap_err(), + PackageHash::from_formatted_str(invalid_prefix).unwrap_err(), FromStrError::InvalidPrefix )); let short_addr = "contract-package-wasm00000000000000000000000000000000000000000000000000000000000000"; assert!(matches!( - ContractPackageHash::from_formatted_str(short_addr).unwrap_err(), + PackageHash::from_formatted_str(short_addr).unwrap_err(), FromStrError::Hash(_) )); let long_addr = "contract-package-wasm000000000000000000000000000000000000000000000000000000000000000000"; assert!(matches!( - ContractPackageHash::from_formatted_str(long_addr).unwrap_err(), + PackageHash::from_formatted_str(long_addr).unwrap_err(), FromStrError::Hash(_) )); let invalid_hex = "contract-package-wasm000000000000000000000000000000000000000000000000000000000000000g"; assert!(matches!( - ContractPackageHash::from_formatted_str(invalid_hex).unwrap_err(), + PackageHash::from_formatted_str(invalid_hex).unwrap_err(), FromStrError::Hex(_) )); } @@ -1452,7 +1525,7 @@ mod prop_tests { proptest! { #[test] - fn test_value_contract_package(contract_pkg in gens::contract_package_arb()) { + fn test_value_contract_package(contract_pkg in gens::package_arb()) { bytesrepr::test_serialization_roundtrip(&contract_pkg); } } diff --git a/types/src/serde_helpers.rs b/types/src/serde_helpers.rs index 93f7605f3e..3daecce5b1 100644 --- a/types/src/serde_helpers.rs +++ b/types/src/serde_helpers.rs @@ -7,10 +7,10 @@ use crate::Digest; pub(crate) mod contract_hash_as_digest { use super::*; - use crate::ContractHash; + use crate::AddressableEntityHash; pub(crate) fn serialize( - contract_hash: &ContractHash, + contract_hash: &AddressableEntityHash, serializer: S, ) -> Result { Digest::from(contract_hash.value()).serialize(serializer) @@ -18,18 +18,18 @@ pub(crate) mod contract_hash_as_digest { pub(crate) fn deserialize<'de, D: Deserializer<'de>>( deserializer: D, - ) -> Result { + ) -> Result { let digest = Digest::deserialize(deserializer)?; - Ok(ContractHash::new(digest.value())) + Ok(AddressableEntityHash::new(digest.value())) } } pub(crate) mod contract_package_hash_as_digest { use super::*; - use crate::ContractPackageHash; + use crate::PackageHash; pub(crate) fn serialize( - contract_package_hash: &ContractPackageHash, + contract_package_hash: &PackageHash, serializer: S, ) -> Result { Digest::from(contract_package_hash.value()).serialize(serializer) @@ -37,9 +37,9 @@ pub(crate) mod contract_package_hash_as_digest { pub(crate) fn deserialize<'de, D: Deserializer<'de>>( deserializer: D, - ) -> Result { + ) -> Result { let digest = Digest::deserialize(deserializer)?; - Ok(ContractPackageHash::new(digest.value())) + Ok(PackageHash::new(digest.value())) } } diff --git a/types/src/stored_value.rs b/types/src/stored_value.rs index 2cc34a508d..1bc6b3e7c8 100644 --- a/types/src/stored_value.rs +++ b/types/src/stored_value.rs @@ -17,10 +17,11 @@ use serde_bytes::ByteBuf; use crate::{ account::Account, bytesrepr::{self, Error, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, - contracts::Contract, + contract_wasm::ContractWasm, + contracts::{Contract, ContractPackage}, package::Package, system::auction::{Bid, BidKind, EraInfo, UnbondingPurse, WithdrawPurse}, - AddressableEntity, CLValue, ContractWasm, DeployInfo, Transfer, + AddressableEntity, ByteCode, CLValue, DeployInfo, Transfer, }; pub use type_mismatch::TypeMismatch; @@ -40,6 +41,8 @@ enum Tag { Unbonding = 10, AddressableEntity = 11, BidKind = 12, + Package = 13, + ByteCode = 14, } /// A value stored in Global State. @@ -56,12 +59,12 @@ pub enum StoredValue { CLValue(CLValue), /// An account. Account(Account), - /// A contract Wasm. + /// Contract wasm. ContractWasm(ContractWasm), /// A contract. Contract(Contract), - /// A `Package`. - ContractPackage(Package), + /// A contract package. + ContractPackage(ContractPackage), /// A `Transfer`. Transfer(Transfer), /// Info about a deploy. @@ -78,6 +81,10 @@ pub enum StoredValue { AddressableEntity(AddressableEntity), /// Variant that stores [`BidKind`]. BidKind(BidKind), + /// A `Package`. + Package(Package), + /// A record of byte code. + ByteCode(ByteCode), } impl StoredValue { @@ -97,10 +104,10 @@ impl StoredValue { } } - /// Returns a reference to the wrapped `ContractWasm` if this is a `ContractWasm` variant. - pub fn as_contract_wasm(&self) -> Option<&ContractWasm> { + /// Returns a reference to the wrapped `ByteCode` if this is a `ByteCode` variant. + pub fn as_byte_code(&self) -> Option<&ByteCode> { match self { - StoredValue::ContractWasm(contract_wasm) => Some(contract_wasm), + StoredValue::ByteCode(byte_code) => Some(byte_code), _ => None, } } @@ -114,9 +121,9 @@ impl StoredValue { } /// Returns a reference to the wrapped `Package` if this is a `Package` variant. - pub fn as_contract_package(&self) -> Option<&Package> { + pub fn as_package(&self) -> Option<&Package> { match self { - StoredValue::ContractPackage(contract_package) => Some(contract_package), + StoredValue::Package(package) => Some(package), _ => None, } } @@ -220,7 +227,7 @@ impl StoredValue { } /// Returns the `Package` if this is a `Package` variant. - pub fn into_contract_package(self) -> Option { + pub fn into_contract_package(self) -> Option { match self { StoredValue::ContractPackage(contract_package) => Some(contract_package), _ => None, @@ -309,6 +316,8 @@ impl StoredValue { StoredValue::Unbonding(_) => "Unbonding".to_string(), StoredValue::AddressableEntity(_) => "AddressableEntity".to_string(), StoredValue::BidKind(_) => "BidKind".to_string(), + StoredValue::ByteCode(_) => "ByteCode".to_string(), + StoredValue::Package(_) => "Package".to_string(), } } @@ -317,8 +326,8 @@ impl StoredValue { StoredValue::CLValue(_) => Tag::CLValue, StoredValue::Account(_) => Tag::Account, StoredValue::ContractWasm(_) => Tag::ContractWasm, - StoredValue::Contract(_) => Tag::Contract, StoredValue::ContractPackage(_) => Tag::ContractPackage, + StoredValue::Contract(_) => Tag::Contract, StoredValue::Transfer(_) => Tag::Transfer, StoredValue::DeployInfo(_) => Tag::DeployInfo, StoredValue::EraInfo(_) => Tag::EraInfo, @@ -327,6 +336,8 @@ impl StoredValue { StoredValue::Unbonding(_) => Tag::Unbonding, StoredValue::AddressableEntity(_) => Tag::AddressableEntity, StoredValue::BidKind(_) => Tag::BidKind, + StoredValue::Package(_) => Tag::Package, + StoredValue::ByteCode(_) => Tag::ByteCode, } } } @@ -343,11 +354,17 @@ impl From for StoredValue { } impl From for StoredValue { - fn from(value: ContractWasm) -> StoredValue { + fn from(value: ContractWasm) -> Self { StoredValue::ContractWasm(value) } } +impl From for StoredValue { + fn from(value: ContractPackage) -> Self { + StoredValue::ContractPackage(value) + } +} + impl From for StoredValue { fn from(value: Contract) -> Self { StoredValue::Contract(value) @@ -361,7 +378,7 @@ impl From for StoredValue { } impl From for StoredValue { fn from(value: Package) -> StoredValue { - StoredValue::ContractPackage(value) + StoredValue::Package(value) } } @@ -377,6 +394,12 @@ impl From for StoredValue { } } +impl From for StoredValue { + fn from(value: ByteCode) -> StoredValue { + StoredValue::ByteCode(value) + } +} + impl TryFrom for CLValue { type Error = TypeMismatch; @@ -384,7 +407,7 @@ impl TryFrom for CLValue { let type_name = stored_value.type_name(); match stored_value { StoredValue::CLValue(cl_value) => Ok(cl_value), - StoredValue::ContractPackage(contract_package) => Ok(CLValue::from_t(contract_package) + StoredValue::Package(contract_package) => Ok(CLValue::from_t(contract_package) .map_err(|_error| TypeMismatch::new("ContractPackage".to_string(), type_name))?), _ => Err(TypeMismatch::new("CLValue".to_string(), type_name)), } @@ -419,6 +442,34 @@ impl TryFrom for ContractWasm { } } +impl TryFrom for ByteCode { + type Error = TypeMismatch; + + fn try_from(stored_value: StoredValue) -> Result { + match stored_value { + StoredValue::ByteCode(byte_code) => Ok(byte_code), + _ => Err(TypeMismatch::new( + "ByteCode".to_string(), + stored_value.type_name(), + )), + } + } +} + +impl TryFrom for ContractPackage { + type Error = TypeMismatch; + + fn try_from(value: StoredValue) -> Result { + match value { + StoredValue::ContractPackage(contract_package) => Ok(contract_package), + _ => Err(TypeMismatch::new( + "ContractPackage".to_string(), + value.type_name(), + )), + } + } +} + impl TryFrom for Contract { type Error = TypeMismatch; @@ -438,7 +489,7 @@ impl TryFrom for Package { fn try_from(stored_value: StoredValue) -> Result { match stored_value { - StoredValue::ContractPackage(contract_package) => Ok(contract_package), + StoredValue::Package(contract_package) => Ok(contract_package), _ => Err(TypeMismatch::new( "ContractPackage".to_string(), stored_value.type_name(), @@ -544,6 +595,8 @@ impl ToBytes for StoredValue { StoredValue::Unbonding(unbonding_purses) => unbonding_purses.serialized_length(), StoredValue::AddressableEntity(entity) => entity.serialized_length(), StoredValue::BidKind(bid_kind) => bid_kind.serialized_length(), + StoredValue::Package(package) => package.serialized_length(), + StoredValue::ByteCode(byte_code) => byte_code.serialized_length(), } } @@ -565,6 +618,8 @@ impl ToBytes for StoredValue { 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)?, }; Ok(()) } @@ -584,7 +639,7 @@ impl FromBytes for StoredValue { }) } tag if tag == Tag::ContractPackage as u8 => { - Package::from_bytes(remainder).map(|(contract_package, remainder)| { + ContractPackage::from_bytes(remainder).map(|(contract_package, remainder)| { (StoredValue::ContractPackage(contract_package), remainder) }) } @@ -612,6 +667,10 @@ impl FromBytes for StoredValue { } tag if tag == Tag::AddressableEntity as u8 => AddressableEntity::from_bytes(remainder) .map(|(entity, remainder)| (StoredValue::AddressableEntity(entity), remainder)), + tag if tag == Tag::Package as u8 => Package::from_bytes(remainder) + .map(|(package, remainder)| (StoredValue::Package(package), remainder)), + tag if tag == Tag::ByteCode as u8 => ByteCode::from_bytes(remainder) + .map(|(byte_code, remainder)| (StoredValue::ByteCode(byte_code), remainder)), _ => Err(Error::Formatting), } } @@ -626,12 +685,11 @@ mod serde_helpers { CLValue(&'a CLValue), /// An account. Account(&'a Account), - /// A contract Wasm. ContractWasm(&'a ContractWasm), /// A contract. Contract(&'a Contract), /// A `Package`. - ContractPackage(&'a Package), + ContractPackage(&'a ContractPackage), /// A `Transfer`. Transfer(&'a Transfer), /// Info about a deploy. @@ -648,6 +706,10 @@ mod serde_helpers { AddressableEntity(&'a AddressableEntity), /// Variant that stores [`BidKind`]. BidKind(&'a BidKind), + /// Package. + Package(&'a Package), + /// A record of byte code. + ByteCode(&'a ByteCode), } #[derive(Deserialize)] @@ -656,12 +718,12 @@ mod serde_helpers { CLValue(CLValue), /// An account. Account(Account), - /// A contract Wasm. + /// A contract wasm. ContractWasm(ContractWasm), /// A contract. Contract(Contract), /// A `Package`. - ContractPackage(Package), + ContractPackage(ContractPackage), /// A `Transfer`. Transfer(Transfer), /// Info about a deploy. @@ -678,6 +740,10 @@ mod serde_helpers { AddressableEntity(AddressableEntity), /// Variant that stores [`BidKind`]. BidKind(BidKind), + /// A record of a Package. + Package(Package), + /// A record of byte code. + ByteCode(ByteCode), } impl<'a> From<&'a StoredValue> for BinarySerHelper<'a> { @@ -698,6 +764,8 @@ mod serde_helpers { BinarySerHelper::AddressableEntity(payload) } StoredValue::BidKind(payload) => BinarySerHelper::BidKind(payload), + StoredValue::Package(payload) => BinarySerHelper::Package(payload), + StoredValue::ByteCode(payload) => BinarySerHelper::ByteCode(payload), } } } @@ -722,6 +790,8 @@ mod serde_helpers { StoredValue::AddressableEntity(payload) } BinaryDeserHelper::BidKind(payload) => StoredValue::BidKind(payload), + BinaryDeserHelper::ByteCode(payload) => StoredValue::ByteCode(payload), + BinaryDeserHelper::Package(payload) => StoredValue::Package(payload), } } } diff --git a/types/src/system.rs b/types/src/system.rs index cdae3f6f42..e742b4d385 100644 --- a/types/src/system.rs +++ b/types/src/system.rs @@ -9,6 +9,4 @@ mod system_contract_type; pub use call_stack_element::{CallStackElement, CallStackElementTag}; pub use error::Error; -pub use system_contract_type::{ - SystemContractType, AUCTION, HANDLE_PAYMENT, MINT, STANDARD_PAYMENT, -}; +pub use system_contract_type::{SystemEntityType, AUCTION, HANDLE_PAYMENT, MINT, STANDARD_PAYMENT}; diff --git a/types/src/system/auction/entry_points.rs b/types/src/system/auction/entry_points.rs index 6c5ac9619b..252550e548 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -34,7 +34,7 @@ pub fn auction_entry_points() -> EntryPoints { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -46,7 +46,7 @@ pub fn auction_entry_points() -> EntryPoints { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -59,7 +59,7 @@ pub fn auction_entry_points() -> EntryPoints { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -72,7 +72,7 @@ pub fn auction_entry_points() -> EntryPoints { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -86,7 +86,7 @@ pub fn auction_entry_points() -> EntryPoints { ], U512::cl_type(), EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -104,7 +104,7 @@ pub fn auction_entry_points() -> EntryPoints { vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -116,7 +116,7 @@ pub fn auction_entry_points() -> EntryPoints { )], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -125,7 +125,7 @@ pub fn auction_entry_points() -> EntryPoints { vec![], CLType::U64, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); diff --git a/types/src/system/call_stack_element.rs b/types/src/system/call_stack_element.rs index 253c9e5c49..df09eac361 100644 --- a/types/src/system/call_stack_element.rs +++ b/types/src/system/call_stack_element.rs @@ -6,8 +6,8 @@ use num_traits::FromPrimitive; use crate::{ account::AccountHash, bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, - package::ContractPackageHash, - CLType, CLTyped, ContractHash, + package::PackageHash, + AddressableEntityHash, CLType, CLTyped, }; /// Tag representing variants of CallStackElement for purposes of serialization. @@ -16,8 +16,6 @@ use crate::{ pub enum CallStackElementTag { /// Session tag. Session = 0, - /// StoredSession tag. - StoredSession, /// StoredContract tag. StoredContract, } @@ -30,21 +28,21 @@ pub enum CallStackElement { /// The account hash of the caller account_hash: AccountHash, }, - /// Effectively an EntryPointType::Session - stored access to a session. - StoredSession { - /// The account hash of the caller - account_hash: AccountHash, - /// The contract package hash - contract_package_hash: ContractPackageHash, - /// The contract hash - contract_hash: ContractHash, - }, - /// Contract - StoredContract { - /// The contract package hash - contract_package_hash: ContractPackageHash, - /// The contract hash - contract_hash: ContractHash, + // /// Effectively an EntryPointType::Session - stored access to a session. + // StoredSession { + // /// The account hash of the caller + // account_hash: AccountHash, + // /// The package hash + // package_hash: PackageHash, + // /// The contract hash + // contract_hash: AddressableEntityHash, + // }, + /// AddressableEntity + AddressableEntity { + /// The package hash + package_hash: PackageHash, + /// The entity hash + entity_hash: AddressableEntityHash, }, } @@ -58,44 +56,47 @@ impl CallStackElement { /// Creates a [`'CallStackElement::StoredContract`]. This represents a call into a contract with /// `EntryPointType::Contract`. pub fn stored_contract( - contract_package_hash: ContractPackageHash, - contract_hash: ContractHash, + package_hash: PackageHash, + contract_hash: AddressableEntityHash, ) -> Self { - CallStackElement::StoredContract { - contract_package_hash, - contract_hash, + CallStackElement::AddressableEntity { + package_hash, + entity_hash: contract_hash, } } - /// Creates a [`'CallStackElement::StoredSession`]. This represents a call into a contract with - /// `EntryPointType::Session`. - pub fn stored_session( - account_hash: AccountHash, - contract_package_hash: ContractPackageHash, - contract_hash: ContractHash, - ) -> Self { - CallStackElement::StoredSession { - account_hash, - contract_package_hash, - contract_hash, - } - } + // /// Creates a [`'CallStackElement::StoredSession`]. This represents a call into a contract + // with /// `EntryPointType::Session`. + // pub fn stored_session( + // account_hash: AccountHash, + // package_hash: PackageHash, + // contract_hash: AddressableEntityHash, + // ) -> Self { + // CallStackElement::StoredSession { + // account_hash, + // package_hash, + // contract_hash, + // } + // } /// Gets the tag from self. pub fn tag(&self) -> CallStackElementTag { match self { CallStackElement::Session { .. } => CallStackElementTag::Session, - CallStackElement::StoredSession { .. } => CallStackElementTag::StoredSession, - CallStackElement::StoredContract { .. } => CallStackElementTag::StoredContract, + + CallStackElement::AddressableEntity { .. } => CallStackElementTag::StoredContract, } } - /// Gets the [`ContractHash`] for both stored session and stored contract variants. - pub fn contract_hash(&self) -> Option<&ContractHash> { + /// Gets the [`AddressableEntityHash`] for both stored session and stored contract variants. + pub fn contract_hash(&self) -> Option<&AddressableEntityHash> { match self { CallStackElement::Session { .. } => None, - CallStackElement::StoredSession { contract_hash, .. } - | CallStackElement::StoredContract { contract_hash, .. } => Some(contract_hash), + + CallStackElement::AddressableEntity { + entity_hash: contract_hash, + .. + } => Some(contract_hash), } } } @@ -108,20 +109,12 @@ impl ToBytes for CallStackElement { CallStackElement::Session { account_hash } => { result.append(&mut account_hash.to_bytes()?) } - CallStackElement::StoredSession { - account_hash, - contract_package_hash, - contract_hash, - } => { - result.append(&mut account_hash.to_bytes()?); - result.append(&mut contract_package_hash.to_bytes()?); - result.append(&mut contract_hash.to_bytes()?); - } - CallStackElement::StoredContract { - contract_package_hash, - contract_hash, + + CallStackElement::AddressableEntity { + package_hash, + entity_hash: contract_hash, } => { - result.append(&mut contract_package_hash.to_bytes()?); + result.append(&mut package_hash.to_bytes()?); result.append(&mut contract_hash.to_bytes()?); } }; @@ -132,19 +125,10 @@ impl ToBytes for CallStackElement { U8_SERIALIZED_LENGTH + match self { CallStackElement::Session { account_hash } => account_hash.serialized_length(), - CallStackElement::StoredSession { - account_hash, - contract_package_hash, - contract_hash, - } => { - account_hash.serialized_length() - + contract_package_hash.serialized_length() - + contract_hash.serialized_length() - } - CallStackElement::StoredContract { - contract_package_hash, - contract_hash, - } => contract_package_hash.serialized_length() + contract_hash.serialized_length(), + CallStackElement::AddressableEntity { + package_hash, + entity_hash: contract_hash, + } => package_hash.serialized_length() + contract_hash.serialized_length(), } } } @@ -158,28 +142,13 @@ impl FromBytes for CallStackElement { let (account_hash, remainder) = AccountHash::from_bytes(remainder)?; Ok((CallStackElement::Session { account_hash }, remainder)) } - CallStackElementTag::StoredSession => { - let (account_hash, remainder) = AccountHash::from_bytes(remainder)?; - let (contract_package_hash, remainder) = - ContractPackageHash::from_bytes(remainder)?; - let (contract_hash, remainder) = ContractHash::from_bytes(remainder)?; - Ok(( - CallStackElement::StoredSession { - account_hash, - contract_package_hash, - contract_hash, - }, - remainder, - )) - } CallStackElementTag::StoredContract => { - let (contract_package_hash, remainder) = - ContractPackageHash::from_bytes(remainder)?; - let (contract_hash, remainder) = ContractHash::from_bytes(remainder)?; + let (package_hash, remainder) = PackageHash::from_bytes(remainder)?; + let (contract_hash, remainder) = AddressableEntityHash::from_bytes(remainder)?; Ok(( - CallStackElement::StoredContract { - contract_package_hash, - contract_hash, + CallStackElement::AddressableEntity { + package_hash, + entity_hash: contract_hash, }, remainder, )) diff --git a/types/src/system/handle_payment/entry_points.rs b/types/src/system/handle_payment/entry_points.rs index 9f5c032ec6..f07b09f58d 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::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(get_refund_purse); @@ -49,7 +49,7 @@ pub fn handle_payment_entry_points() -> EntryPoints { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(finalize_payment); @@ -58,7 +58,7 @@ pub fn handle_payment_entry_points() -> EntryPoints { vec![], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(distribute_accumulated_fees); diff --git a/types/src/system/mint/entry_points.rs b/types/src/system/mint/entry_points.rs index e8b2013e23..6002b3383b 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::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -43,7 +43,7 @@ pub fn mint_entry_points() -> EntryPoints { Parameters::new(), CLType::URef, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); @@ -79,7 +79,7 @@ pub fn mint_entry_points() -> EntryPoints { Parameters::new(), CLType::U512, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); 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::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(entry_point); diff --git a/types/src/system/system_contract_type.rs b/types/src/system/system_contract_type.rs index 52a78df157..0ad6551a7d 100644 --- a/types/src/system/system_contract_type.rs +++ b/types/src/system/system_contract_type.rs @@ -11,6 +11,11 @@ use core::{ #[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}; @@ -34,10 +39,12 @@ use super::{ /// /// Used by converting to a `u32` and passing as the `system_contract_index` argument of /// `ext_ffi::casper_get_system_contract()`. -#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, Copy)] +#[derive( + Debug, Clone, PartialEq, Eq, Default, PartialOrd, Ord, Hash, Serialize, Deserialize, Copy, +)] #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] -pub enum SystemContractType { +pub enum SystemEntityType { /// Mint contract. #[default] Mint, @@ -49,7 +56,7 @@ pub enum SystemContractType { Auction, } -impl ToBytes for SystemContractType { +impl ToBytes for SystemEntityType { fn to_bytes(&self) -> Result, Error> { let mut buffer = bytesrepr::allocate_buffer(self)?; self.write_bytes(&mut buffer)?; @@ -62,34 +69,47 @@ impl ToBytes for SystemContractType { fn write_bytes(&self, writer: &mut Vec) -> Result<(), Error> { match self { - SystemContractType::Mint => { + SystemEntityType::Mint => { writer.push(MINT_TAG); } - SystemContractType::HandlePayment => { + SystemEntityType::HandlePayment => { writer.push(HANDLE_PAYMENT_TAG); } - SystemContractType::StandardPayment => { + SystemEntityType::StandardPayment => { writer.push(STANDARD_PAYMENT_TAG); } - SystemContractType::Auction => writer.push(AUCTION_TAG), + SystemEntityType::Auction => writer.push(AUCTION_TAG), } Ok(()) } } -impl FromBytes for SystemContractType { +impl FromBytes for SystemEntityType { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> { let (tag, remainder) = u8::from_bytes(bytes)?; match tag { - MINT_TAG => Ok((SystemContractType::Mint, remainder)), - HANDLE_PAYMENT_TAG => Ok((SystemContractType::HandlePayment, remainder)), - STANDARD_PAYMENT_TAG => Ok((SystemContractType::StandardPayment, remainder)), - AUCTION_TAG => Ok((SystemContractType::Auction, remainder)), + MINT_TAG => Ok((SystemEntityType::Mint, remainder)), + HANDLE_PAYMENT_TAG => Ok((SystemEntityType::HandlePayment, remainder)), + STANDARD_PAYMENT_TAG => Ok((SystemEntityType::StandardPayment, remainder)), + AUCTION_TAG => Ok((SystemEntityType::Auction, remainder)), _ => Err(Error::Formatting), } } } +#[cfg(any(feature = "testing", test))] +impl Distribution for Standard { + fn sample(&self, rng: &mut R) -> SystemEntityType { + match rng.gen_range(0..=3) { + 0 => SystemEntityType::Mint, + 1 => SystemEntityType::Auction, + 2 => SystemEntityType::StandardPayment, + 3 => SystemEntityType::HandlePayment, + _ => unreachable!(), + } + } +} + /// Name of mint system contract pub const MINT: &str = "mint"; /// Name of handle payment system contract @@ -99,61 +119,61 @@ pub const STANDARD_PAYMENT: &str = "standard payment"; /// Name of auction system contract pub const AUCTION: &str = "auction"; -impl SystemContractType { +impl SystemEntityType { /// Returns the name of the system contract. pub fn contract_name(&self) -> String { match self { - SystemContractType::Mint => MINT.to_string(), - SystemContractType::HandlePayment => HANDLE_PAYMENT.to_string(), - SystemContractType::StandardPayment => STANDARD_PAYMENT.to_string(), - SystemContractType::Auction => AUCTION.to_string(), + SystemEntityType::Mint => MINT.to_string(), + SystemEntityType::HandlePayment => HANDLE_PAYMENT.to_string(), + SystemEntityType::StandardPayment => STANDARD_PAYMENT.to_string(), + SystemEntityType::Auction => AUCTION.to_string(), } } /// Returns the entrypoint of the system contract. pub fn contract_entry_points(&self) -> EntryPoints { match self { - SystemContractType::Mint => mint_entry_points(), - SystemContractType::HandlePayment => handle_payment_entry_points(), - SystemContractType::StandardPayment => standard_payment_entry_points(), - SystemContractType::Auction => auction_entry_points(), + SystemEntityType::Mint => mint_entry_points(), + SystemEntityType::HandlePayment => handle_payment_entry_points(), + SystemEntityType::StandardPayment => standard_payment_entry_points(), + SystemEntityType::Auction => auction_entry_points(), } } } -impl From for u32 { - fn from(system_contract_type: SystemContractType) -> u32 { +impl From for u32 { + fn from(system_contract_type: SystemEntityType) -> u32 { match system_contract_type { - SystemContractType::Mint => 0, - SystemContractType::HandlePayment => 1, - SystemContractType::StandardPayment => 2, - SystemContractType::Auction => 3, + SystemEntityType::Mint => 0, + SystemEntityType::HandlePayment => 1, + SystemEntityType::StandardPayment => 2, + SystemEntityType::Auction => 3, } } } // This conversion is not intended to be used by third party crates. #[doc(hidden)] -impl TryFrom for SystemContractType { +impl TryFrom for SystemEntityType { type Error = ApiError; - fn try_from(value: u32) -> Result { + fn try_from(value: u32) -> Result { match value { - 0 => Ok(SystemContractType::Mint), - 1 => Ok(SystemContractType::HandlePayment), - 2 => Ok(SystemContractType::StandardPayment), - 3 => Ok(SystemContractType::Auction), + 0 => Ok(SystemEntityType::Mint), + 1 => Ok(SystemEntityType::HandlePayment), + 2 => Ok(SystemEntityType::StandardPayment), + 3 => Ok(SystemEntityType::Auction), _ => Err(ApiError::InvalidSystemContract), } } } -impl Display for SystemContractType { +impl Display for SystemEntityType { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match *self { - SystemContractType::Mint => write!(f, "{}", MINT), - SystemContractType::HandlePayment => write!(f, "{}", HANDLE_PAYMENT), - SystemContractType::StandardPayment => write!(f, "{}", STANDARD_PAYMENT), - SystemContractType::Auction => write!(f, "{}", AUCTION), + SystemEntityType::Mint => write!(f, "{}", MINT), + SystemEntityType::HandlePayment => write!(f, "{}", HANDLE_PAYMENT), + SystemEntityType::StandardPayment => write!(f, "{}", STANDARD_PAYMENT), + SystemEntityType::Auction => write!(f, "{}", AUCTION), } } } @@ -166,67 +186,64 @@ mod tests { #[test] fn get_index_of_mint_contract() { - let index: u32 = SystemContractType::Mint.into(); + let index: u32 = SystemEntityType::Mint.into(); assert_eq!(index, 0u32); - assert_eq!(SystemContractType::Mint.to_string(), MINT); + assert_eq!(SystemEntityType::Mint.to_string(), MINT); } #[test] fn get_index_of_handle_payment_contract() { - let index: u32 = SystemContractType::HandlePayment.into(); + let index: u32 = SystemEntityType::HandlePayment.into(); assert_eq!(index, 1u32); - assert_eq!( - SystemContractType::HandlePayment.to_string(), - HANDLE_PAYMENT - ); + assert_eq!(SystemEntityType::HandlePayment.to_string(), HANDLE_PAYMENT); } #[test] fn get_index_of_standard_payment_contract() { - let index: u32 = SystemContractType::StandardPayment.into(); + let index: u32 = SystemEntityType::StandardPayment.into(); assert_eq!(index, 2u32); assert_eq!( - SystemContractType::StandardPayment.to_string(), + SystemEntityType::StandardPayment.to_string(), STANDARD_PAYMENT ); } #[test] fn get_index_of_auction_contract() { - let index: u32 = SystemContractType::Auction.into(); + let index: u32 = SystemEntityType::Auction.into(); assert_eq!(index, 3u32); - assert_eq!(SystemContractType::Auction.to_string(), AUCTION); + assert_eq!(SystemEntityType::Auction.to_string(), AUCTION); } #[test] fn create_mint_variant_from_int() { - let mint = SystemContractType::try_from(0).ok().unwrap(); - assert_eq!(mint, SystemContractType::Mint); + let mint = SystemEntityType::try_from(0).ok().unwrap(); + assert_eq!(mint, SystemEntityType::Mint); } #[test] fn create_handle_payment_variant_from_int() { - let handle_payment = SystemContractType::try_from(1).ok().unwrap(); - assert_eq!(handle_payment, SystemContractType::HandlePayment); + let handle_payment = SystemEntityType::try_from(1).ok().unwrap(); + assert_eq!(handle_payment, SystemEntityType::HandlePayment); } #[test] fn create_standard_payment_variant_from_int() { - let handle_payment = SystemContractType::try_from(2).ok().unwrap(); - assert_eq!(handle_payment, SystemContractType::StandardPayment); + let handle_payment = SystemEntityType::try_from(2).ok().unwrap(); + assert_eq!(handle_payment, SystemEntityType::StandardPayment); } #[test] fn create_auction_variant_from_int() { - let auction = SystemContractType::try_from(3).ok().unwrap(); - assert_eq!(auction, SystemContractType::Auction); + let auction = SystemEntityType::try_from(3).ok().unwrap(); + assert_eq!(auction, SystemEntityType::Auction); } #[test] fn create_unknown_system_contract_variant() { - assert!(SystemContractType::try_from(4).is_err()); - assert!(SystemContractType::try_from(5).is_err()); - assert!(SystemContractType::try_from(10).is_err()); - assert!(SystemContractType::try_from(u32::max_value()).is_err()); + assert!(SystemEntityType::try_from(4).is_err()); + assert!(SystemEntityType::try_from(5).is_err()); + assert!(SystemEntityType::try_from(10).is_err()); + assert!(SystemEntityType::try_from(u32::max_value()).is_err()); } } diff --git a/types/src/transaction.rs b/types/src/transaction.rs index 493d52d266..ba5239d992 100644 --- a/types/src/transaction.rs +++ b/types/src/transaction.rs @@ -33,10 +33,10 @@ use crate::{account::ACCOUNT_HASH_LENGTH, SecretKey, TimeDiff, URef}; #[cfg(any(feature = "std", test))] use account_and_secret_key::AccountAndSecretKey; pub use deploy::{ - runtime_args, ContractIdentifier, ContractPackageIdentifier, Deploy, DeployApproval, - DeployApprovalsHash, DeployConfigurationFailure, DeployDecodeFromJsonError, DeployError, - DeployExcessiveSizeError, DeployFootprint, DeployHash, DeployHeader, DeployId, - ExecutableDeployItem, ExecutableDeployItemIdentifier, TransferTarget, + runtime_args, Deploy, DeployApproval, DeployApprovalsHash, DeployConfigurationFailure, + DeployDecodeFromJsonError, DeployError, DeployExcessiveSizeError, DeployFootprint, DeployHash, + DeployHeader, DeployId, EntityIdentifier, ExecutableDeployItem, ExecutableDeployItemIdentifier, + PackageIdentifier, TransferTarget, }; #[cfg(any(feature = "std", test))] pub use deploy::{DeployBuilder, DeployBuilderError}; diff --git a/types/src/transaction/deploy.rs b/types/src/transaction/deploy.rs index b3b92014e0..34740a0b2a 100644 --- a/types/src/transaction/deploy.rs +++ b/types/src/transaction/deploy.rs @@ -37,7 +37,7 @@ use { ARG_PUBLIC_KEY as ARG_AUCTION_PUBLIC_KEY, ARG_VALIDATOR, METHOD_DELEGATE, METHOD_REDELEGATE, METHOD_UNDELEGATE, METHOD_WITHDRAW_BID, }, - ContractHash, + AddressableEntityHash, {system::mint::ARG_AMOUNT, TransactionConfig, U512}, {testing::TestRng, DEFAULT_MAX_PAYMENT_MOTES, DEFAULT_MIN_TRANSFER_MOTES}, }, @@ -65,8 +65,8 @@ pub use error::{ Error as DeployError, ExcessiveSizeError as DeployExcessiveSizeError, }; pub use executable_deploy_item::{ - ContractIdentifier, ContractPackageIdentifier, ExecutableDeployItem, - ExecutableDeployItemIdentifier, TransferTarget, + EntityIdentifier, ExecutableDeployItem, ExecutableDeployItemIdentifier, PackageIdentifier, + TransferTarget, }; pub use runtime_args::RuntimeArgs; @@ -944,7 +944,7 @@ impl Deploy { #[cfg(any(all(feature = "std", feature = "testing"), test))] pub fn withdraw_bid( chain_name: String, - auction_contract_hash: ContractHash, + auction_contract_hash: AddressableEntityHash, public_key: PublicKey, amount: U512, timestamp: Timestamp, @@ -980,7 +980,7 @@ impl Deploy { #[cfg(any(all(feature = "std", feature = "testing"), test))] pub fn delegate( chain_name: String, - auction_contract_hash: ContractHash, + auction_contract_hash: AddressableEntityHash, validator_public_key: PublicKey, delegator_public_key: PublicKey, amount: U512, @@ -1018,7 +1018,7 @@ impl Deploy { #[cfg(any(all(feature = "std", feature = "testing"), test))] pub fn undelegate( chain_name: String, - auction_contract_hash: ContractHash, + auction_contract_hash: AddressableEntityHash, validator_public_key: PublicKey, delegator_public_key: PublicKey, amount: U512, @@ -1057,7 +1057,7 @@ impl Deploy { #[allow(clippy::too_many_arguments)] pub fn redelegate( chain_name: String, - auction_contract_hash: ContractHash, + auction_contract_hash: AddressableEntityHash, validator_public_key: PublicKey, delegator_public_key: PublicKey, redelegate_validator_public_key: PublicKey, diff --git a/types/src/transaction/deploy/executable_deploy_item.rs b/types/src/transaction/deploy/executable_deploy_item.rs index 0441409af9..535acfdc19 100644 --- a/types/src/transaction/deploy/executable_deploy_item.rs +++ b/types/src/transaction/deploy/executable_deploy_item.rs @@ -21,16 +21,14 @@ use crate::{ account::AccountHash, addressable_entity::DEFAULT_ENTRY_POINT_NAME, bytesrepr::{self, Bytes, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, - package::{ContractPackageHash, ContractVersion}, + package::{EntityVersion, PackageHash}, runtime_args, serde_helpers, system::mint::ARG_AMOUNT, - ContractHash, Gas, Motes, Phase, PublicKey, RuntimeArgs, URef, U512, + AddressableEntityHash, Gas, Motes, Phase, PublicKey, RuntimeArgs, URef, U512, }; #[cfg(any(feature = "testing", test))] use crate::{testing::TestRng, CLValue}; -pub use identifiers::{ - ContractIdentifier, ContractPackageIdentifier, ExecutableDeployItemIdentifier, -}; +pub use identifiers::{EntityIdentifier, ExecutableDeployItemIdentifier, PackageIdentifier}; const TAG_LENGTH: usize = U8_SERIALIZED_LENGTH; const MODULE_BYTES_TAG: u8 = 0; @@ -62,7 +60,7 @@ pub enum ExecutableDeployItem { /// Runtime arguments. args: RuntimeArgs, }, - /// Stored contract referenced by its [`ContractHash`], entry point and an instance of + /// Stored contract referenced by its [`AddressableEntityHash`], entry point and an instance of /// [`RuntimeArgs`]. StoredContractByHash { /// Contract hash. @@ -71,7 +69,7 @@ pub enum ExecutableDeployItem { feature = "json-schema", schemars(with = "String", description = "Hex-encoded contract hash.") )] - hash: ContractHash, + hash: AddressableEntityHash, /// Name of an entry point. entry_point: String, /// Runtime arguments. @@ -87,7 +85,7 @@ pub enum ExecutableDeployItem { /// Runtime arguments. args: RuntimeArgs, }, - /// Stored versioned contract referenced by its [`ContractPackageHash`], entry point and an + /// Stored versioned contract referenced by its [`PackageHash`], entry point and an /// instance of [`RuntimeArgs`]. StoredVersionedContractByHash { /// Contract package hash @@ -96,10 +94,10 @@ pub enum ExecutableDeployItem { feature = "json-schema", schemars(with = "String", description = "Hex-encoded contract package hash.") )] - hash: ContractPackageHash, + 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, + version: Option, /// Entry point name. entry_point: String, /// Runtime arguments. @@ -112,7 +110,7 @@ pub enum ExecutableDeployItem { 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, + version: Option, /// Entry point name. entry_point: String, /// Runtime arguments. @@ -144,7 +142,7 @@ impl ExecutableDeployItem { /// Returns a new `ExecutableDeployItem::StoredContractByHash`. pub fn new_stored_contract_by_hash( - hash: ContractHash, + hash: AddressableEntityHash, entry_point: String, args: RuntimeArgs, ) -> Self { @@ -170,8 +168,8 @@ impl ExecutableDeployItem { /// Returns a new `ExecutableDeployItem::StoredVersionedContractByHash`. pub fn new_stored_versioned_contract_by_hash( - hash: ContractPackageHash, - version: Option, + hash: PackageHash, + version: Option, entry_point: String, args: RuntimeArgs, ) -> Self { @@ -186,7 +184,7 @@ impl ExecutableDeployItem { /// Returns a new `ExecutableDeployItem::StoredVersionedContractByName`. pub fn new_stored_versioned_contract_by_name( name: String, - version: Option, + version: Option, entry_point: String, args: RuntimeArgs, ) -> Self { @@ -252,19 +250,21 @@ impl ExecutableDeployItem { match self { ExecutableDeployItem::ModuleBytes { .. } => ExecutableDeployItemIdentifier::Module, ExecutableDeployItem::StoredContractByHash { hash, .. } => { - ExecutableDeployItemIdentifier::Contract(ContractIdentifier::Hash(*hash)) + ExecutableDeployItemIdentifier::AddressableEntity(EntityIdentifier::Hash(*hash)) } ExecutableDeployItem::StoredContractByName { name, .. } => { - ExecutableDeployItemIdentifier::Contract(ContractIdentifier::Name(name.clone())) + ExecutableDeployItemIdentifier::AddressableEntity(EntityIdentifier::Name( + name.clone(), + )) } ExecutableDeployItem::StoredVersionedContractByHash { hash, version, .. } => { - ExecutableDeployItemIdentifier::Package(ContractPackageIdentifier::Hash { - contract_package_hash: *hash, + ExecutableDeployItemIdentifier::Package(PackageIdentifier::Hash { + package_hash: *hash, version: *version, }) } ExecutableDeployItem::StoredVersionedContractByName { name, version, .. } => { - ExecutableDeployItemIdentifier::Package(ContractPackageIdentifier::Name { + ExecutableDeployItemIdentifier::Package(PackageIdentifier::Name { name: name.clone(), version: *version, }) @@ -274,23 +274,23 @@ impl ExecutableDeployItem { } /// Returns the identifier of the contract in the deploy item, if present. - pub fn contract_identifier(&self) -> Option { + pub fn contract_identifier(&self) -> Option { match self { ExecutableDeployItem::ModuleBytes { .. } | ExecutableDeployItem::StoredVersionedContractByHash { .. } | ExecutableDeployItem::StoredVersionedContractByName { .. } | ExecutableDeployItem::Transfer { .. } => None, ExecutableDeployItem::StoredContractByHash { hash, .. } => { - Some(ContractIdentifier::Hash(*hash)) + Some(EntityIdentifier::Hash(*hash)) } ExecutableDeployItem::StoredContractByName { name, .. } => { - Some(ContractIdentifier::Name(name.clone())) + Some(EntityIdentifier::Name(name.clone())) } } } /// Returns the identifier of the contract package in the deploy item, if present. - pub fn contract_package_identifier(&self) -> Option { + pub fn contract_package_identifier(&self) -> Option { match self { ExecutableDeployItem::ModuleBytes { .. } | ExecutableDeployItem::StoredContractByHash { .. } @@ -298,13 +298,13 @@ impl ExecutableDeployItem { | ExecutableDeployItem::Transfer { .. } => None, ExecutableDeployItem::StoredVersionedContractByHash { hash, version, .. } => { - Some(ContractPackageIdentifier::Hash { - contract_package_hash: *hash, + Some(PackageIdentifier::Hash { + package_hash: *hash, version: *version, }) } ExecutableDeployItem::StoredVersionedContractByName { name, version, .. } => { - Some(ContractPackageIdentifier::Name { + Some(PackageIdentifier::Name { name: name.clone(), version: *version, }) @@ -532,7 +532,7 @@ impl FromBytes for ExecutableDeployItem { )) } STORED_CONTRACT_BY_HASH_TAG => { - let (hash, remainder) = ContractHash::from_bytes(remainder)?; + let (hash, remainder) = AddressableEntityHash::from_bytes(remainder)?; let (entry_point, remainder) = String::from_bytes(remainder)?; let (args, remainder) = RuntimeArgs::from_bytes(remainder)?; Ok(( @@ -558,8 +558,8 @@ impl FromBytes for ExecutableDeployItem { )) } STORED_VERSIONED_CONTRACT_BY_HASH_TAG => { - let (hash, remainder) = ContractPackageHash::from_bytes(remainder)?; - let (version, remainder) = Option::::from_bytes(remainder)?; + 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(( @@ -574,7 +574,7 @@ impl FromBytes for ExecutableDeployItem { } STORED_VERSIONED_CONTRACT_BY_NAME_TAG => { let (name, remainder) = String::from_bytes(remainder)?; - let (version, remainder) = Option::::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(( @@ -743,7 +743,7 @@ impl Distribution for Standard { args, }, 1 => ExecutableDeployItem::StoredContractByHash { - hash: ContractHash::new(rng.gen()), + hash: AddressableEntityHash::new(rng.gen()), entry_point: random_string(rng), args, }, @@ -753,7 +753,7 @@ impl Distribution for Standard { args, }, 3 => ExecutableDeployItem::StoredVersionedContractByHash { - hash: ContractPackageHash::new(rng.gen()), + hash: PackageHash::new(rng.gen()), version: rng.gen(), entry_point: random_string(rng), args, diff --git a/types/src/transaction/deploy/executable_deploy_item/identifiers.rs b/types/src/transaction/deploy/executable_deploy_item/identifiers.rs index 83232d6838..d12c5905e9 100644 --- a/types/src/transaction/deploy/executable_deploy_item/identifiers.rs +++ b/types/src/transaction/deploy/executable_deploy_item/identifiers.rs @@ -1,6 +1,14 @@ use alloc::{string::String, vec::Vec}; use core::fmt::{self, Display, Formatter}; +#[cfg(any(feature = "testing", test))] +use crate::testing::TestRng; +use crate::{ + bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, + AddressableEntityHash, EntityVersion, PackageHash, +}; +#[cfg(doc)] +use crate::{DirectCallV1, ExecutableDeployItem}; #[cfg(feature = "datasize")] use datasize::DataSize; use hex_fmt::HexFmt; @@ -10,15 +18,6 @@ use rand::Rng; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -#[cfg(any(feature = "testing", test))] -use crate::testing::TestRng; -use crate::{ - bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, - ContractHash, ContractPackageHash, ContractVersion, -}; -#[cfg(doc)] -use crate::{DirectCallV1, ExecutableDeployItem}; - const CONTRACT_PACKAGE_ID_HASH_TAG: u8 = 0; const CONTRACT_PACKAGE_ID_NAME_TAG: u8 = 1; @@ -28,68 +27,69 @@ pub enum ExecutableDeployItemIdentifier { /// The deploy item is of the type [`ExecutableDeployItem::ModuleBytes`] Module, /// The deploy item is a variation of a stored contract. - Contract(ContractIdentifier), + AddressableEntity(EntityIdentifier), /// The deploy item is a variation of a stored contract package. - Package(ContractPackageIdentifier), + Package(PackageIdentifier), /// The deploy item is a native transfer. Transfer, } /// Identifier for the contract object within a [`DirectCallV1`] or an [`ExecutableDeployItem`]. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub enum ContractIdentifier { - /// The contract object within the deploy item is identified by its hash. - Hash(ContractHash), - /// The contract object within the deploy item is identified by name. +pub enum EntityIdentifier { + /// The entity object within the deploy item is identified by its hash. + Hash(AddressableEntityHash), + /// The entity object within the deploy item is identified by name. Name(String), } -/// Identifier for the contract package object within a [`DirectCallV1`] or an +/// Identifier for the package object within a [`DirectCallV1`] or an /// [`ExecutableDeployItem`]. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Debug)] #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr( feature = "json-schema", derive(JsonSchema), - schemars(description = "Identifier for a contract package.") + schemars(description = "Identifier for a package.") )] -pub enum ContractPackageIdentifier { +pub enum PackageIdentifier { /// The stored contract package within the deploy item is identified by its hash. Hash { /// Hash of the contract package. - contract_package_hash: ContractPackageHash, + package_hash: PackageHash, /// The version specified in the deploy item. - version: Option, + version: Option, }, /// The stored contract package within the deploy item is identified by name. Name { /// Name of the contract package. name: String, /// The version specified in the deploy item. - version: Option, + version: Option, }, } -impl ContractPackageIdentifier { +impl PackageIdentifier { /// Returns the version of the contract package specified in the deploy item. - pub fn version(&self) -> Option { + pub fn version(&self) -> Option { match self { - ContractPackageIdentifier::Hash { version, .. } - | ContractPackageIdentifier::Name { version, .. } => *version, + PackageIdentifier::Hash { version, .. } | PackageIdentifier::Name { version, .. } => { + *version + } } } /// Returns a random `ContractPackageIdentifier`. #[cfg(any(feature = "testing", test))] pub fn random(rng: &mut TestRng) -> Self { - let version = rng.gen::().then(|| rng.gen::()); + let version = rng.gen::().then(|| rng.gen::()); if rng.gen() { - ContractPackageIdentifier::Hash { - contract_package_hash: ContractPackageHash::new(rng.gen()), + PackageIdentifier::Hash { + package_hash: PackageHash::new(rng.gen()), version, } } else { - ContractPackageIdentifier::Name { + PackageIdentifier::Name { name: rng.random_string(1..21), version, } @@ -97,11 +97,11 @@ impl ContractPackageIdentifier { } } -impl Display for ContractPackageIdentifier { +impl Display for PackageIdentifier { fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { match self { - ContractPackageIdentifier::Hash { - contract_package_hash, + PackageIdentifier::Hash { + package_hash: contract_package_hash, version: Some(ver), } => write!( formatter, @@ -109,15 +109,15 @@ impl Display for ContractPackageIdentifier { HexFmt(contract_package_hash), ver ), - ContractPackageIdentifier::Hash { - contract_package_hash, + PackageIdentifier::Hash { + package_hash: contract_package_hash, .. } => write!( formatter, "contract-package-id(hash: {}, version: latest)", HexFmt(contract_package_hash), ), - ContractPackageIdentifier::Name { + PackageIdentifier::Name { name, version: Some(ver), } => write!( @@ -125,7 +125,7 @@ impl Display for ContractPackageIdentifier { "contract-package-id(name: {}, version: {})", name, ver ), - ContractPackageIdentifier::Name { name, .. } => write!( + PackageIdentifier::Name { name, .. } => write!( formatter, "contract-package-id(name: {}, version: latest)", name @@ -134,18 +134,18 @@ impl Display for ContractPackageIdentifier { } } -impl ToBytes for ContractPackageIdentifier { +impl ToBytes for PackageIdentifier { fn write_bytes(&self, writer: &mut Vec) -> Result<(), bytesrepr::Error> { match self { - ContractPackageIdentifier::Hash { - contract_package_hash, + PackageIdentifier::Hash { + package_hash: contract_package_hash, version, } => { CONTRACT_PACKAGE_ID_HASH_TAG.write_bytes(writer)?; contract_package_hash.write_bytes(writer)?; version.write_bytes(writer) } - ContractPackageIdentifier::Name { name, version } => { + PackageIdentifier::Name { name, version } => { CONTRACT_PACKAGE_ID_NAME_TAG.write_bytes(writer)?; name.write_bytes(writer)?; version.write_bytes(writer) @@ -162,35 +162,34 @@ impl ToBytes for ContractPackageIdentifier { fn serialized_length(&self) -> usize { U8_SERIALIZED_LENGTH + match self { - ContractPackageIdentifier::Hash { - contract_package_hash, + PackageIdentifier::Hash { + package_hash: contract_package_hash, version, } => contract_package_hash.serialized_length() + version.serialized_length(), - ContractPackageIdentifier::Name { name, version } => { + PackageIdentifier::Name { name, version } => { name.serialized_length() + version.serialized_length() } } } } -impl FromBytes for ContractPackageIdentifier { +impl FromBytes for PackageIdentifier { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { let (tag, remainder) = u8::from_bytes(bytes)?; match tag { CONTRACT_PACKAGE_ID_HASH_TAG => { - let (contract_package_hash, remainder) = - ContractPackageHash::from_bytes(remainder)?; - let (version, remainder) = Option::::from_bytes(remainder)?; - let id = ContractPackageIdentifier::Hash { - contract_package_hash, + let (contract_package_hash, remainder) = PackageHash::from_bytes(remainder)?; + let (version, remainder) = Option::::from_bytes(remainder)?; + let id = PackageIdentifier::Hash { + package_hash: contract_package_hash, version, }; Ok((id, remainder)) } CONTRACT_PACKAGE_ID_NAME_TAG => { let (name, remainder) = String::from_bytes(remainder)?; - let (version, remainder) = Option::::from_bytes(remainder)?; - let id = ContractPackageIdentifier::Name { name, version }; + let (version, remainder) = Option::::from_bytes(remainder)?; + let id = PackageIdentifier::Name { name, version }; Ok((id, remainder)) } _ => Err(bytesrepr::Error::Formatting), @@ -205,6 +204,6 @@ mod tests { #[test] fn bytesrepr_roundtrip() { let rng = &mut TestRng::new(); - bytesrepr::test_serialization_roundtrip(&ContractPackageIdentifier::random(rng)); + bytesrepr::test_serialization_roundtrip(&PackageIdentifier::random(rng)); } } diff --git a/types/src/transaction/transaction_v1/direct_call_v1.rs b/types/src/transaction/transaction_v1/direct_call_v1.rs index 8f650997e5..2c22941278 100644 --- a/types/src/transaction/transaction_v1/direct_call_v1.rs +++ b/types/src/transaction/transaction_v1/direct_call_v1.rs @@ -17,8 +17,8 @@ use crate::testing::TestRng; use crate::{ bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, system::mint::ARG_AMOUNT, - ContractHash, ContractIdentifier, ContractPackageHash, ContractPackageIdentifier, - ContractVersion, Gas, Motes, RuntimeArgs, U512, + AddressableEntityHash, EntityIdentifier, EntityVersion, Gas, Motes, PackageHash, + PackageIdentifier, RuntimeArgs, U512, }; const STORED_CONTRACT_BY_HASH_TAG: u8 = 0; @@ -39,7 +39,7 @@ pub enum DirectCallV1 { /// Stored contract referenced by its hash. StoredContractByHash { /// Contract hash. - hash: ContractHash, + hash: AddressableEntityHash, /// Name of the entry point. entry_point: String, /// Runtime arguments. @@ -57,9 +57,9 @@ pub enum DirectCallV1 { /// Stored versioned contract referenced by its hash. StoredVersionedContractByHash { /// Contract package hash. - hash: ContractPackageHash, + hash: PackageHash, /// Version of the contract to call; defaults to highest enabled version if unspecified. - version: Option, + version: Option, /// Name of the entry point. entry_point: String, /// Runtime arguments. @@ -71,7 +71,7 @@ pub enum DirectCallV1 { /// Name of the named key. name: String, /// Version of the contract to call; defaults to highest enabled version if unspecified. - version: Option, + version: Option, /// Name of the entry point. entry_point: String, /// Runtime arguments. @@ -82,7 +82,7 @@ pub enum DirectCallV1 { impl DirectCallV1 { /// Returns a new `DirectCallV1::StoredContractByHash`. pub fn new_stored_contract_by_hash( - hash: ContractHash, + hash: AddressableEntityHash, entry_point: String, args: RuntimeArgs, ) -> Self { @@ -108,8 +108,8 @@ impl DirectCallV1 { /// Returns a new `DirectCallV1::StoredVersionedContractByHash`. pub fn new_stored_versioned_contract_by_hash( - hash: ContractPackageHash, - version: Option, + hash: PackageHash, + version: Option, entry_point: String, args: RuntimeArgs, ) -> Self { @@ -124,7 +124,7 @@ impl DirectCallV1 { /// Returns a new `DirectCallV1::StoredVersionedContractByName`. pub fn new_stored_versioned_contract_by_name( name: String, - version: Option, + version: Option, entry_point: String, args: RuntimeArgs, ) -> Self { @@ -147,32 +147,30 @@ impl DirectCallV1 { } /// Returns the identifier of the contract, if present. - pub fn contract_identifier(&self) -> Option { + pub fn contract_identifier(&self) -> Option { match self { DirectCallV1::StoredVersionedContractByHash { .. } | DirectCallV1::StoredVersionedContractByName { .. } => None, - DirectCallV1::StoredContractByHash { hash, .. } => { - Some(ContractIdentifier::Hash(*hash)) - } + DirectCallV1::StoredContractByHash { hash, .. } => Some(EntityIdentifier::Hash(*hash)), DirectCallV1::StoredContractByName { name, .. } => { - Some(ContractIdentifier::Name(name.clone())) + Some(EntityIdentifier::Name(name.clone())) } } } /// Returns the identifier of the contract package, if present. - pub fn contract_package_identifier(&self) -> Option { + pub fn contract_package_identifier(&self) -> Option { match self { DirectCallV1::StoredContractByHash { .. } | DirectCallV1::StoredContractByName { .. } => None, DirectCallV1::StoredVersionedContractByHash { hash, version, .. } => { - Some(ContractPackageIdentifier::Hash { - contract_package_hash: *hash, + Some(PackageIdentifier::Hash { + package_hash: *hash, version: *version, }) } DirectCallV1::StoredVersionedContractByName { name, version, .. } => { - Some(ContractPackageIdentifier::Name { + Some(PackageIdentifier::Name { name: name.clone(), version: *version, }) @@ -213,7 +211,7 @@ impl DirectCallV1 { let args = RuntimeArgs::random(rng); match rng.gen_range(0..4) { 0 => DirectCallV1::StoredContractByHash { - hash: ContractHash::new(rng.gen()), + hash: AddressableEntityHash::new(rng.gen()), entry_point, args, }, @@ -223,7 +221,7 @@ impl DirectCallV1 { args, }, 2 => DirectCallV1::StoredVersionedContractByHash { - hash: ContractPackageHash::new(rng.gen()), + hash: PackageHash::new(rng.gen()), version: rng.gen(), entry_point, args, @@ -457,7 +455,7 @@ impl FromBytes for DirectCallV1 { let (tag, remainder) = u8::from_bytes(bytes)?; match tag { STORED_CONTRACT_BY_HASH_TAG => { - let (hash, remainder) = ContractHash::from_bytes(remainder)?; + let (hash, remainder) = AddressableEntityHash::from_bytes(remainder)?; let (entry_point, remainder) = String::from_bytes(remainder)?; let (args, remainder) = RuntimeArgs::from_bytes(remainder)?; Ok(( @@ -483,8 +481,8 @@ impl FromBytes for DirectCallV1 { )) } STORED_VERSIONED_CONTRACT_BY_HASH_TAG => { - let (hash, remainder) = ContractPackageHash::from_bytes(remainder)?; - let (version, remainder) = Option::::from_bytes(remainder)?; + 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(( @@ -499,7 +497,7 @@ impl FromBytes for DirectCallV1 { } STORED_VERSIONED_CONTRACT_BY_NAME_TAG => { let (name, remainder) = String::from_bytes(remainder)?; - let (version, remainder) = Option::::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(( diff --git a/types/src/transaction/transaction_v1/transaction_v1_kind.rs b/types/src/transaction/transaction_v1/transaction_v1_kind.rs index 20438cc529..b651528f30 100644 --- a/types/src/transaction/transaction_v1/transaction_v1_kind.rs +++ b/types/src/transaction/transaction_v1/transaction_v1_kind.rs @@ -20,8 +20,8 @@ use crate::{ account::AccountHash, bytesrepr::{self, Bytes, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, transaction::{AuctionTransactionV1, DirectCallV1}, - CLTyped, CLValueError, ContractHash, ContractPackageHash, ContractPackageIdentifier, - ContractVersion, PublicKey, RuntimeArgs, URef, U512, + AddressableEntityHash, CLTyped, CLValueError, EntityVersion, PackageHash, PackageIdentifier, + PublicKey, RuntimeArgs, URef, U512, }; const NATIVE_TAG: u8 = 0; @@ -148,7 +148,7 @@ impl TransactionV1Kind { /// Returns a new upgrader transaction body. pub fn new_upgrader( - contract_package_id: ContractPackageIdentifier, + contract_package_id: PackageIdentifier, module_bytes: Bytes, args: RuntimeArgs, ) -> Self { @@ -158,7 +158,7 @@ impl TransactionV1Kind { /// Returns a new stored-contract-by-hash transaction body. pub fn new_stored_contract_by_hash( - hash: ContractHash, + hash: AddressableEntityHash, entry_point: String, args: RuntimeArgs, ) -> Self { @@ -178,8 +178,8 @@ impl TransactionV1Kind { /// Returns a new stored-versioned-contract-by-hash transaction body. pub fn new_stored_versioned_contract_by_hash( - hash: ContractPackageHash, - version: Option, + hash: PackageHash, + version: Option, entry_point: String, args: RuntimeArgs, ) -> Self { @@ -191,7 +191,7 @@ impl TransactionV1Kind { /// Returns a new stored-versioned-contract-by-name transaction body. pub fn new_stored_versioned_contract_by_name( name: String, - version: Option, + version: Option, entry_point: String, args: RuntimeArgs, ) -> Self { diff --git a/types/src/transaction/transaction_v1/userland_transaction_v1.rs b/types/src/transaction/transaction_v1/userland_transaction_v1.rs index 46d2daa5a1..d7dd26fd13 100644 --- a/types/src/transaction/transaction_v1/userland_transaction_v1.rs +++ b/types/src/transaction/transaction_v1/userland_transaction_v1.rs @@ -19,7 +19,7 @@ use crate::{ DEFAULT_ENTRY_POINT_NAME, INSTALL_ENTRY_POINT_NAME, UPGRADE_ENTRY_POINT_NAME, }, bytesrepr::{self, Bytes, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, - ContractPackageIdentifier, RuntimeArgs, + PackageIdentifier, RuntimeArgs, }; const STANDARD_TAG: u8 = 0; @@ -48,7 +48,7 @@ pub enum UserlandTransactionV1 { /// An installer or upgrader for a stored contract. InstallerUpgrader { /// If `Some`, this is an upgrade for the given contract, otherwise it is an installer. - contract_package_id: Option, + contract_package_id: Option, /// Raw Wasm module bytes with 'call' exported as an entrypoint. module_bytes: Bytes, /// Runtime arguments. @@ -89,7 +89,7 @@ impl UserlandTransactionV1 { /// Returns a new `UserlandTransactionV1::InstallerUpgrader` for upgrading. pub fn new_upgrader( - contract_package_id: ContractPackageIdentifier, + contract_package_id: PackageIdentifier, module_bytes: Bytes, args: RuntimeArgs, ) -> Self { @@ -175,9 +175,7 @@ impl UserlandTransactionV1 { args: RuntimeArgs::random(rng), }, 1 => { - let contract_package = rng - .gen::() - .then(|| ContractPackageIdentifier::random(rng)); + let contract_package = rng.gen::().then(|| PackageIdentifier::random(rng)); UserlandTransactionV1::InstallerUpgrader { contract_package_id: contract_package, module_bytes: random_bytes(rng), @@ -299,7 +297,7 @@ impl FromBytes for UserlandTransactionV1 { } INSTALLER_UPGRADER_TAG => { let (contract_package, remainder) = - Option::::from_bytes(remainder)?; + Option::::from_bytes(remainder)?; let (module_bytes, remainder) = Bytes::from_bytes(remainder)?; let (args, remainder) = RuntimeArgs::from_bytes(remainder)?; let txn = UserlandTransactionV1::InstallerUpgrader { diff --git a/utils/global-state-update-gen/src/generic/state_reader.rs b/utils/global-state-update-gen/src/generic/state_reader.rs index 993f48822f..bf407e80c8 100644 --- a/utils/global-state-update-gen/src/generic/state_reader.rs +++ b/utils/global-state-update-gen/src/generic/state_reader.rs @@ -1,6 +1,7 @@ use casper_engine_test_support::LmdbWasmTestBuilder; use casper_types::{ account::AccountHash, + contracts::ContractHash, system::{ auction::{BidKind, UnbondingPurses, WithdrawPurses, SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY}, mint::TOTAL_SUPPLY_KEY, @@ -79,7 +80,10 @@ impl StateReader for LmdbWasmTestBuilder { .copied() .expect("total_supply should exist in mint named keys") } else { - self.get_legacy_contract(mint_contract_hash) + let mint_legacy_contract_hash: ContractHash = + ContractHash::new(mint_contract_hash.value()); + + self.get_legacy_contract(mint_legacy_contract_hash) .expect("mint should exist") .named_keys() .get(TOTAL_SUPPLY_KEY) @@ -99,7 +103,9 @@ impl StateReader for LmdbWasmTestBuilder { .copied() .expect("seigniorage_recipients_snapshot should exist in auction named keys") } else { - self.get_legacy_contract(auction_contract_hash) + let auction_legacy_contract_hash = ContractHash::new(auction_contract_hash.value()); + + self.get_legacy_contract(auction_legacy_contract_hash) .expect("auction should exist") .named_keys() .get(SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY) @@ -127,10 +133,12 @@ impl StateReader for LmdbWasmTestBuilder { fn get_protocol_version(&mut self) -> ProtocolVersion { let mint_contract_hash = self.get_system_mint_hash(); + let mint_legacy_contract_hash: ContractHash = ContractHash::new(mint_contract_hash.value()); + if let Some(entity) = self.get_addressable_entity(mint_contract_hash) { entity.protocol_version() } else { - self.get_legacy_contract(mint_contract_hash) + self.get_legacy_contract(mint_legacy_contract_hash) .expect("mint should exist") .protocol_version() } 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 eec3465d51..412fcefaaa 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, NamedKeys, Weight}, - package::{ContractPackageKind, ContractPackageStatus, ContractVersions, Groups}, + package::{EntityVersions, Groups, PackageKind, PackageKindTag, PackageStatus}, system::auction::{BidAddr, BidKind, BidsExt, SeigniorageRecipientsSnapshot, UnbondingPurse}, - AccessRights, AddressableEntity, CLValue, ContractHash, ContractPackageHash, ContractWasmHash, - EntryPoints, Key, Package, ProtocolVersion, PublicKey, StoredValue, URef, U512, + AccessRights, AddressableEntity, AddressableEntityHash, ByteCodeHash, CLValue, EntryPoints, + Key, Package, PackageHash, ProtocolVersion, PublicKey, StoredValue, URef, U512, }; use super::{config::Transfer, state_reader::StateReader}; @@ -161,14 +161,14 @@ impl StateTracker { let mut rng = rand::thread_rng(); - let contract_hash = ContractHash::new(rng.gen()); - let contract_package_hash = ContractPackageHash::new(rng.gen()); - let contract_wasm_hash = ContractWasmHash::new([0u8; 32]); + let entity_hash = AddressableEntityHash::new(rng.gen()); + let package_hash = PackageHash::new(rng.gen()); + let contract_wasm_hash = ByteCodeHash::new([0u8; 32]); let associated_keys = AssociatedKeys::new(account_hash, Weight::new(1)); let addressable_entity = AddressableEntity::new( - contract_package_hash, + package_hash, contract_wasm_hash, NamedKeys::default(), EntryPoints::new(), @@ -180,29 +180,28 @@ impl StateTracker { let mut contract_package = Package::new( URef::new(rng.gen(), AccessRights::READ_ADD_WRITE), - ContractVersions::default(), + EntityVersions::default(), BTreeSet::default(), Groups::default(), - ContractPackageStatus::Locked, - ContractPackageKind::Account(account_hash), + PackageStatus::Locked, + PackageKind::Account(account_hash), ); - contract_package - .insert_contract_version(self.protocol_version.value().major, contract_hash); + contract_package.insert_entity_version(self.protocol_version.value().major, entity_hash); self.write_entry( - contract_package_hash.into(), - StoredValue::ContractPackage(contract_package.clone()), + package_hash.into(), + StoredValue::Package(contract_package.clone()), ); + let entity_key = Key::addressable_entity_key(PackageKindTag::Account, entity_hash); + self.write_entry( - contract_hash.into(), + entity_key, StoredValue::AddressableEntity(addressable_entity.clone()), ); - let addressable_entity_by_account_hash = { - let contract_key: Key = contract_hash.into(); - CLValue::from_t(contract_key).expect("must convert to cl_value") - }; + let addressable_entity_by_account_hash = + { CLValue::from_t(entity_key).expect("must convert to cl_value") }; self.accounts_cache .insert(account_hash, addressable_entity.clone()); diff --git a/utils/global-state-update-gen/src/generic/testing.rs b/utils/global-state-update-gen/src/generic/testing.rs index d6969c13ce..6657b59ca2 100644 --- a/utils/global-state-update-gen/src/generic/testing.rs +++ b/utils/global-state-update-gen/src/generic/testing.rs @@ -12,8 +12,8 @@ use casper_types::{ WithdrawPurse, WithdrawPurses, }, testing::TestRng, - AccessRights, AddressableEntity, CLValue, ContractPackageHash, ContractWasmHash, EntryPoints, - EraId, Key, ProtocolVersion, PublicKey, StoredValue, URef, URefAddr, U512, + AccessRights, AddressableEntity, ByteCodeHash, CLValue, EntryPoints, EraId, Key, PackageHash, + ProtocolVersion, PublicKey, StoredValue, URef, URefAddr, U512, }; use super::{ @@ -60,8 +60,8 @@ impl MockStateReader { ) -> Self { let main_purse = URef::new(rng.gen(), AccessRights::READ_ADD_WRITE); let entity = AddressableEntity::new( - ContractPackageHash::new(rng.gen()), - ContractWasmHash::new(rng.gen()), + PackageHash::new(rng.gen()), + ByteCodeHash::new(rng.gen()), NamedKeys::new(), EntryPoints::new(), self.protocol_version, diff --git a/utils/global-state-update-gen/src/system_contract_registry.rs b/utils/global-state-update-gen/src/system_contract_registry.rs index 5f1c526209..c3d133dced 100644 --- a/utils/global-state-update-gen/src/system_contract_registry.rs +++ b/utils/global-state-update-gen/src/system_contract_registry.rs @@ -8,7 +8,7 @@ use casper_execution_engine::engine_state::SystemContractRegistry; use casper_types::{ bytesrepr::FromBytes, system::{AUCTION, HANDLE_PAYMENT, MINT, STANDARD_PAYMENT}, - CLValue, ContractHash, Key, StoredValue, KEY_HASH_LENGTH, + AddressableEntityHash, CLValue, Key, StoredValue, KEY_HASH_LENGTH, }; use crate::utils::{hash_from_str, print_entry}; @@ -62,32 +62,34 @@ fn generate_system_contract_registry_using_protocol_data(data_dir: &Path) { .len() .saturating_sub(4 * KEY_HASH_LENGTH); let remainder = &serialized_protocol_data[start_index..]; - let (mint_hash, remainder) = ContractHash::from_bytes(remainder).unwrap_or_else(|error| { - panic!( - "failed to parse mint hash: {:?}\nraw_bytes: {:?}", - error, serialized_protocol_data - ) - }); - let (handle_payment_hash, remainder) = - ContractHash::from_bytes(remainder).unwrap_or_else(|error| { + let (mint_hash, remainder) = + AddressableEntityHash::from_bytes(remainder).unwrap_or_else(|error| { + panic!( + "failed to parse mint hash: {:?}\nraw_bytes: {:?}", + error, serialized_protocol_data + ) + }); + let (handle_payment_hash, remainder) = AddressableEntityHash::from_bytes(remainder) + .unwrap_or_else(|error| { panic!( "failed to parse handle_payment hash: {:?}\nraw_bytes: {:?}", error, serialized_protocol_data ) }); - let (standard_payment_hash, remainder) = - ContractHash::from_bytes(remainder).unwrap_or_else(|error| { + let (standard_payment_hash, remainder) = AddressableEntityHash::from_bytes(remainder) + .unwrap_or_else(|error| { panic!( "failed to parse standard_payment hash: {:?}\nraw_bytes: {:?}", error, serialized_protocol_data ) }); - let (auction_hash, remainder) = ContractHash::from_bytes(remainder).unwrap_or_else(|error| { - panic!( - "failed to parse auction hash: {:?}\nraw_bytes: {:?}", - error, serialized_protocol_data - ) - }); + let (auction_hash, remainder) = + AddressableEntityHash::from_bytes(remainder).unwrap_or_else(|error| { + panic!( + "failed to parse auction hash: {:?}\nraw_bytes: {:?}", + error, serialized_protocol_data + ) + }); assert!(remainder.is_empty()); let mut registry = SystemContractRegistry::new(); @@ -108,13 +110,11 @@ fn generate_system_contract_registry_using_global_state(data_dir: &Path, state_h let mint_hash = builder.get_system_mint_hash(); let handle_payment_hash = builder.get_system_handle_payment_hash(); - let standard_payment_hash = builder.get_system_standard_payment_hash(); let auction_hash = builder.get_system_auction_hash(); let mut registry = SystemContractRegistry::new(); registry.insert(MINT.to_string(), mint_hash); registry.insert(HANDLE_PAYMENT.to_string(), handle_payment_hash); - registry.insert(STANDARD_PAYMENT.to_string(), standard_payment_hash); registry.insert(AUCTION.to_string(), auction_hash); print_entry( diff --git a/utils/validation/Cargo.toml b/utils/validation/Cargo.toml index 2411c87c42..60bbeef48a 100644 --- a/utils/validation/Cargo.toml +++ b/utils/validation/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [dependencies] anyhow = "1" base16 = "0.2.1" -casper-types = { path = "../../types", features = ["testing"] } +casper-types = { path = "../../types", features = ["testing", "std"] } clap = { version ="3.0.0-rc.0", features = ["derive"] } derive_more = "0.99.13" hex = { version = "0.4.2", features = ["serde"] } diff --git a/utils/validation/src/generators.rs b/utils/validation/src/generators.rs index 00dae3f3a7..37da42d868 100644 --- a/utils/validation/src/generators.rs +++ b/utils/validation/src/generators.rs @@ -9,15 +9,15 @@ use casper_types::{ AssociatedKeys as AccountAssociatedKeys, Weight as AccountWeight, }, addressable_entity::{ActionThresholds, AddressableEntity, AssociatedKeys, NamedKeys}, - package::{ContractPackageKind, ContractPackageStatus, ContractVersions, Groups, Package}, + package::{EntityVersions, Groups, Package, PackageKind, PackageStatus}, system::auction::{ Bid, BidAddr, BidKind, Delegator, EraInfo, SeigniorageAllocation, UnbondingPurse, ValidatorBid, WithdrawPurse, }, - AccessRights, CLType, CLTyped, CLValue, ContractHash, ContractPackageHash, ContractVersionKey, - ContractWasm, ContractWasmHash, DeployHash, DeployInfo, EntryPoint, EntryPointAccess, - EntryPointType, EntryPoints, EraId, Group, Key, Parameter, ProtocolVersion, PublicKey, - SecretKey, StoredValue, Transfer, TransferAddr, URef, U512, + 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, }; use casper_validation::{ abi::{ABIFixture, ABITestCase}, @@ -332,11 +332,11 @@ pub fn make_abi_test_fixtures() -> Result { ABITestCase::from_inputs(vec![StoredValue::Account(account).into()])?, ); - let contract_wasm = ContractWasm::new(DO_NOTHING_BYTES.to_vec()); + let byte_code = ByteCode::new(ByteCodeKind::V1CasperWasm, DO_NOTHING_BYTES.to_vec()); stored_value.insert( - "ContractWasm".to_string(), - ABITestCase::from_inputs(vec![StoredValue::ContractWasm(contract_wasm).into()])?, + "ByteCode".to_string(), + ABITestCase::from_inputs(vec![StoredValue::ByteCode(byte_code).into()])?, ); let contract_named_keys = { @@ -359,7 +359,7 @@ pub fn make_abi_test_fixtures() -> Result { ], CLType::Unit, EntryPointAccess::Public, - EntryPointType::Contract, + EntryPointType::AddressableEntity, ); entry_points.add_entry_point(public_contract_entry_point); @@ -368,8 +368,8 @@ pub fn make_abi_test_fixtures() -> Result { }; let entity = AddressableEntity::new( - ContractPackageHash::new([100; 32]), - ContractWasmHash::new([101; 32]), + PackageHash::new([100; 32]), + ByteCodeHash::new([101; 32]), contract_named_keys, entry_points, ProtocolVersion::V1_0_0, @@ -383,12 +383,12 @@ pub fn make_abi_test_fixtures() -> Result { ); let mut active_versions = BTreeMap::new(); - let v1_hash = ContractHash::new([99; 32]); - let v2_hash = ContractHash::new([100; 32]); - active_versions.insert(ContractVersionKey::new(1, 2), v1_hash); - let v1 = ContractVersionKey::new(1, 1); + let v1_hash = AddressableEntityHash::new([99; 32]); + let v2_hash = AddressableEntityHash::new([100; 32]); + active_versions.insert(EntityVersionKey::new(1, 2), v1_hash); + let v1 = EntityVersionKey::new(1, 1); active_versions.insert(v1, v2_hash); - let active_versions = ContractVersions::from(active_versions); + let active_versions = EntityVersions::from(active_versions); let mut disabled_versions = BTreeSet::new(); disabled_versions.insert(v1); @@ -400,18 +400,18 @@ pub fn make_abi_test_fixtures() -> Result { BTreeSet::from_iter(vec![URef::new([55; 32], AccessRights::READ)]), ); - let contract_package = Package::new( + let package = Package::new( URef::new([39; 32], AccessRights::READ), active_versions, disabled_versions, groups, - ContractPackageStatus::Locked, - ContractPackageKind::Wasm, + PackageStatus::Locked, + PackageKind::SmartContract, ); stored_value.insert( - "ContractPackage".to_string(), - ABITestCase::from_inputs(vec![StoredValue::ContractPackage(contract_package).into()])?, + "Package".to_string(), + ABITestCase::from_inputs(vec![StoredValue::Package(package).into()])?, ); stored_value.insert( diff --git a/utils/validation/tests/fixtures/ABI/stored_value.json b/utils/validation/tests/fixtures/ABI/stored_value.json index b27040d127..8a4a8bd1b9 100644 --- a/utils/validation/tests/fixtures/ABI/stored_value.json +++ b/utils/validation/tests/fixtures/ABI/stored_value.json @@ -6,27 +6,27 @@ "value": { "Account": { "account_hash": "account-hash-306633f962155a7d46658adb36143f28668f530454fe788c927cecf62e5964a1", - "action_thresholds": { - "deployment": 1, - "key_management": 1 - }, - "associated_keys": [ + "named_keys": [ { - "account_hash": "account-hash-306633f962155a7d46658adb36143f28668f530454fe788c927cecf62e5964a1", - "weight": 1 + "name": "hash", + "key": "hash-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a" + }, + { + "name": "uref", + "key": "uref-1010101010101010101010101010101010101010101010101010101010101010-007" } ], "main_purse": "uref-1111111111111111111111111111111111111111111111111111111111111111-002", - "named_keys": [ - { - "key": "hash-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a", - "name": "hash" - }, + "associated_keys": [ { - "key": "uref-1010101010101010101010101010101010101010101010101010101010101010-007", - "name": "uref" + "account_hash": "account-hash-306633f962155a7d46658adb36143f28668f530454fe788c927cecf62e5964a1", + "weight": 1 } - ] + ], + "action_thresholds": { + "deployment": 1, + "key_management": 1 + } } } } @@ -39,51 +39,52 @@ "type": "StoredValue", "value": { "AddressableEntity": { - "action_thresholds": { - "deployment": 1, - "key_management": 1 - }, - "associated_keys": [], - "contract_package_hash": "contract-package-6464646464646464646464646464646464646464646464646464646464646464", - "contract_wasm_hash": "contract-wasm-6565656565656565656565656565656565656565656565656565656565656565", + "package_hash": "contract-package-6464646464646464646464646464646464646464646464646464646464646464", + "byte_code_hash": "contract-wasm-6565656565656565656565656565656565656565656565656565656565656565", + "named_keys": [ + { + "name": "hash", + "key": "hash-2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b" + }, + { + "name": "uref", + "key": "uref-1111111111111111111111111111111111111111111111111111111111111111-007" + } + ], "entry_points": [ { + "name": "public_entry_point_func", "entry_point": { - "access": "Public", + "name": "public_entry_point_func", "args": [ { - "cl_type": "U512", - "name": "param1" + "name": "param1", + "cl_type": "U512" }, { - "cl_type": "String", - "name": "param2" + "name": "param2", + "cl_type": "String" } ], - "entry_point_type": "Contract", - "name": "public_entry_point_func", - "ret": "Unit" - }, - "name": "public_entry_point_func" + "ret": "Unit", + "access": "Public", + "entry_point_type": "AddressableEntity" + } } ], + "protocol_version": "1.0.0", "main_purse": "uref-0000000000000000000000000000000000000000000000000000000000000000-000", - "named_keys": [ - { - "key": "hash-2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b", - "name": "hash" - }, - { - "key": "uref-1111111111111111111111111111111111111111111111111111111111111111-007", - "name": "uref" - } - ], - "protocol_version": "1.0.0" + "associated_keys": [], + "action_thresholds": { + "deployment": 1, + "upgrade_management": 1, + "key_management": 1 + } } } } ], - "output": "0b64646464646464646464646464646464646464646464646464646464646464646565656565656565656565656565656565656565656565656565656565656565020000000400000068617368012b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b04000000757265660211111111111111111111111111111111111111111111111111111111111111110701000000170000007075626c69635f656e7472795f706f696e745f66756e63170000007075626c69635f656e7472795f706f696e745f66756e630200000006000000706172616d310806000000706172616d320a090101010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101" + "output": "0b64646464646464646464646464646464646464646464646464646464646464646565656565656565656565656565656565656565656565656565656565656565020000000400000068617368012b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b04000000757265660211111111111111111111111111111111111111111111111111111111111111110701000000170000007075626c69635f656e7472795f706f696e745f66756e63170000007075626c69635f656e7472795f706f696e745f66756e630200000006000000706172616d310806000000706172616d320a09010101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010101" }, "Bid": { "input": [ @@ -91,112 +92,64 @@ "type": "StoredValue", "value": { "Bid": { + "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", "bonding_purse": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007", + "staked_amount": "50000000000", "delegation_rate": 100, + "vesting_schedule": { + "initial_release_timestamp_millis": 18446744073709551615, + "locked_amounts": null + }, "delegators": [ { + "delegator_public_key": "0202bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f2", "delegator": { - "bonding_purse": "uref-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b-007", "delegator_public_key": "0202bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f2", "staked_amount": "1000000000", + "bonding_purse": "uref-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b-007", "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", "vesting_schedule": { "initial_release_timestamp_millis": 18446744073709551615, "locked_amounts": null } - }, - "delegator_public_key": "0202bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f2" + } } ], - "inactive": false, - "staked_amount": "50000000000", - "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", - "vesting_schedule": { - "initial_release_timestamp_millis": 18446744073709551615, - "locked_amounts": null - } + "inactive": false } } } ], "output": "0801197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d610a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a070500743ba40b6401ffffffffffffffff00010000000202bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f20202bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f20400ca9a3b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0701197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d6101ffffffffffffffff0000" }, - "CLValue": { + "ByteCode": { "input": [ { "type": "StoredValue", "value": { - "CLValue": { - "bytes": "0d00000048656c6c6f2c20776f726c6421", - "cl_type": "String", - "parsed": "Hello, world!" - } - } - } - ], - "output": "00110000000d00000048656c6c6f2c20776f726c64210a" - }, - "ContractPackage": { - "input": [ - { - "type": "StoredValue", - "value": { - "ContractPackage": { - "access_key": "uref-2727272727272727272727272727272727272727272727272727272727272727-001", - "contract_package_kind": "Wasm", - "disabled_versions": [ - { - "contract_version": 1, - "protocol_version_major": 1 - } - ], - "groups": [ - { - "group_name": "Empty", - "group_users": [] - }, - { - "group_name": "Single", - "group_users": [ - "uref-3737373737373737373737373737373737373737373737373737373737373737-001" - ] - } - ], - "lock_status": "Locked", - "versions": [ - { - "contract_hash": "contract-6464646464646464646464646464646464646464646464646464646464646464", - "contract_version_key": { - "contract_version": 1, - "protocol_version_major": 1 - } - }, - { - "contract_hash": "contract-6363636363636363636363636363636363636363636363636363636363636363", - "contract_version_key": { - "contract_version": 2, - "protocol_version_major": 1 - } - } - ] + "ByteCode": { + "byte_code_kind": "V1CasperWasm", + "bytes": "0061736d010000000104016000000302010005030100010708010463616c6c00000a040102000b" } } } ], - "output": "042727272727272727272727272727272727272727272727272727272727272727010200000001000000010000006464646464646464646464646464646464646464646464646464646464646464010000000200000063636363636363636363636363636363636363636363636363636363636363630100000001000000010000000200000005000000456d707479000000000600000053696e676c65010000003737373737373737373737373737373737373737373737373737373737373737010100" + "output": "0e01270000000061736d010000000104016000000302010005030100010708010463616c6c00000a040102000b" }, - "ContractWasm": { + "CLValue": { "input": [ { "type": "StoredValue", "value": { - "ContractWasm": { - "bytes": "0061736d010000000104016000000302010005030100010708010463616c6c00000a040102000b" + "CLValue": { + "cl_type": "String", + "bytes": "0d00000048656c6c6f2c20776f726c6421", + "parsed": "Hello, world!" } } } ], - "output": "02270000000061736d010000000104016000000302010005030100010708010463616c6c00000a040102000b" + "output": "00110000000d00000048656c6c6f2c20776f726c64210a" }, "DelegatorBid": { "input": [ @@ -205,9 +158,9 @@ "value": { "BidKind": { "Delegator": { - "bonding_purse": "uref-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b-007", "delegator_public_key": "0202bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f2", "staked_amount": "1000000000", + "bonding_purse": "uref-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b-007", "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", "vesting_schedule": { "initial_release_timestamp_millis": 18446744073709551615, @@ -227,13 +180,13 @@ "value": { "DeployInfo": { "deploy_hash": "3737373737373737373737373737373737373737373737373737373737373737", - "from": "account-hash-6464646464646464646464646464646464646464646464646464646464646464", - "gas": "2500000000", - "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007", "transfers": [ "transfer-0101010101010101010101010101010101010101010101010101010101010101", "transfer-0202020202020202020202020202020202020202020202020202020202020202" - ] + ], + "from": "account-hash-6464646464646464646464646464646464646464646464646464646464646464", + "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007", + "gas": "2500000000" } } } @@ -249,15 +202,15 @@ "seigniorage_allocations": [ { "Validator": { - "amount": "1000000000", - "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61" + "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", + "amount": "1000000000" } }, { "Delegator": { - "amount": "1000000000", "delegator_public_key": "0202bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f2", - "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61" + "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", + "amount": "1000000000" } } ] @@ -267,20 +220,69 @@ ], "output": "07020000000001197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d610400ca9a3b010202bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f201197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d610400ca9a3b" }, + "Package": { + "input": [ + { + "type": "StoredValue", + "value": { + "Package": { + "access_key": "uref-2727272727272727272727272727272727272727272727272727272727272727-001", + "versions": [ + { + "entity_version_key": { + "protocol_version_major": 1, + "entity_version": 1 + }, + "addressable_entity_hash": "addressable-entity-6464646464646464646464646464646464646464646464646464646464646464" + }, + { + "entity_version_key": { + "protocol_version_major": 1, + "entity_version": 2 + }, + "addressable_entity_hash": "addressable-entity-6363636363636363636363636363636363636363636363636363636363636363" + } + ], + "disabled_versions": [ + { + "protocol_version_major": 1, + "entity_version": 1 + } + ], + "groups": [ + { + "group_name": "Empty", + "group_users": [] + }, + { + "group_name": "Single", + "group_users": [ + "uref-3737373737373737373737373737373737373737373737373737373737373737-001" + ] + } + ], + "lock_status": "Locked", + "package_kind": "SmartContract" + } + } + } + ], + "output": "0d2727272727272727272727272727272727272727272727272727272727272727010200000001000000010000006464646464646464646464646464646464646464646464646464646464646464010000000200000063636363636363636363636363636363636363636363636363636363636363630100000001000000010000000200000005000000456d707479000000000600000053696e676c65010000003737373737373737373737373737373737373737373737373737373737373737010102" + }, "Transfer": { "input": [ { "type": "StoredValue", "value": { "Transfer": { - "amount": "15000000000", "deploy_hash": "2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c", "from": "account-hash-6464646464646464646464646464646464646464646464646464646464646464", - "gas": "2500000000", - "id": 1, + "to": "account-hash-6565656565656565656565656565656565656565656565656565656565656565", "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-002", "target": "uref-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b-002", - "to": "account-hash-6565656565656565656565656565656565656565656565656565656565656565" + "amount": "15000000000", + "gas": "2500000000", + "id": 1 } } } @@ -294,20 +296,20 @@ "value": { "Unbonding": [ { - "amount": "60000000000", "bonding_purse": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-001", - "era_of_creation": 41, - "new_validator": null, + "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", "unbonder_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", - "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61" + "era_of_creation": 41, + "amount": "60000000000", + "new_validator": null }, { - "amount": "50000000000", "bonding_purse": "uref-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b-001", - "era_of_creation": 42, - "new_validator": null, + "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", "unbonder_public_key": "0202bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f2", - "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61" + "era_of_creation": 42, + "amount": "50000000000", + "new_validator": null } ] } @@ -322,30 +324,30 @@ "value": { "BidKind": { "Unified": { + "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", "bonding_purse": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007", + "staked_amount": "50000000000", "delegation_rate": 100, + "vesting_schedule": { + "initial_release_timestamp_millis": 18446744073709551615, + "locked_amounts": null + }, "delegators": [ { + "delegator_public_key": "0202bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f2", "delegator": { - "bonding_purse": "uref-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b-007", "delegator_public_key": "0202bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f2", "staked_amount": "1000000000", + "bonding_purse": "uref-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b-007", "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", "vesting_schedule": { "initial_release_timestamp_millis": 18446744073709551615, "locked_amounts": null } - }, - "delegator_public_key": "0202bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f2" + } } ], - "inactive": false, - "staked_amount": "50000000000", - "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", - "vesting_schedule": { - "initial_release_timestamp_millis": 18446744073709551615, - "locked_amounts": null - } + "inactive": false } } } @@ -360,15 +362,15 @@ "value": { "BidKind": { "Validator": { + "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", "bonding_purse": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007", - "delegation_rate": 100, - "inactive": false, "staked_amount": "50000000000", - "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", + "delegation_rate": 100, "vesting_schedule": { "initial_release_timestamp_millis": 18446744073709551615, "locked_amounts": null - } + }, + "inactive": false } } } @@ -383,18 +385,18 @@ "value": { "Withdraw": [ { - "amount": "60000000000", "bonding_purse": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-001", - "era_of_creation": 41, + "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", "unbonder_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", - "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61" + "era_of_creation": 41, + "amount": "60000000000" }, { - "amount": "50000000000", "bonding_purse": "uref-0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b-001", - "era_of_creation": 42, + "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61", "unbonder_public_key": "0202bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f2", - "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61" + "era_of_creation": 42, + "amount": "50000000000" } ] }