diff --git a/execution_engine/Cargo.toml b/execution_engine/Cargo.toml index f49a27c2b4..6b303a6953 100644 --- a/execution_engine/Cargo.toml +++ b/execution_engine/Cargo.toml @@ -17,7 +17,7 @@ bincode = "1.3.1" blake2 = { version = "0.10.6", default-features = false } blake3 = { version = "1.5.0", default-features = false, features = ["pure"] } sha2 = { version = "0.10.8", default-features = false } -casper-storage = { version = "2.0.0", path = "../storage" } +casper-storage = { version = "2.0.0", path = "../storage", default-features = true } casper-types = { version = "5.0.0", path = "../types", default-features = false, features = ["datasize", "gens", "json-schema", "std"] } casper-wasm = { version = "0.46.0", default-features = false, features = ["sign_ext"] } casper-wasm-utils = { version = "3.0.0", default-features = false, features = ["sign_ext"] } diff --git a/execution_engine/src/engine_state/mod.rs b/execution_engine/src/engine_state/mod.rs index 96714f4501..31e198bce0 100644 --- a/execution_engine/src/engine_state/mod.rs +++ b/execution_engine/src/engine_state/mod.rs @@ -106,7 +106,7 @@ impl ExecutionEngineV1 { &authorization_keys, &self.config().administrative_accounts, ) { - Ok((addressable_entity, entity_hash)) => (addressable_entity, entity_hash), + Ok((runtime_footprint, entity_hash)) => (runtime_footprint, entity_hash), Err(tce) => { return WasmV1Result::precondition_failure(gas_limit, Error::TrackingCopy(tce)) } diff --git a/execution_engine/src/runtime/mint_internal.rs b/execution_engine/src/runtime/mint_internal.rs index f240a5e596..7248004fb5 100644 --- a/execution_engine/src/runtime/mint_internal.rs +++ b/execution_engine/src/runtime/mint_internal.rs @@ -86,12 +86,8 @@ where self.context.subtract_amount_spent(transferred); } - fn get_main_purse(&self) -> URef { - self.context - .runtime_footprint() - .borrow() - .main_purse() - .expect("did not have purse in mint internal") + fn get_main_purse(&self) -> Option { + self.context.runtime_footprint().borrow().main_purse() } fn is_administrator(&self, account_hash: &AccountHash) -> bool { diff --git a/execution_engine/src/runtime_context/tests.rs b/execution_engine/src/runtime_context/tests.rs index ff2366f8a1..8001b7203e 100644 --- a/execution_engine/src/runtime_context/tests.rs +++ b/execution_engine/src/runtime_context/tests.rs @@ -7,6 +7,8 @@ use casper_storage::{ AddressGenerator, TrackingCopy, }; +use super::{AllowInstallUpgrade, ExecError, RuntimeContext}; +use crate::engine_state::{BlockInfo, EngineConfig, EngineConfigBuilder}; use casper_types::{ account::{ AccountHash, AddKeyFailure, RemoveKeyFailure, SetThresholdFailure, ACCOUNT_HASH_LENGTH, @@ -24,9 +26,6 @@ use casper_types::{ }; use tempfile::TempDir; -use super::{AllowInstallUpgrade, ExecError, RuntimeContext}; -use crate::engine_state::{BlockInfo, EngineConfig, EngineConfigBuilder}; - const TXN_HASH_RAW: [u8; 32] = [1u8; 32]; const PHASE: Phase = Phase::Session; const GAS_LIMIT: u64 = 500_000_000_000_000u64; diff --git a/storage/src/lib.rs b/storage/src/lib.rs index cd180a895b..9b6dca2b6d 100644 --- a/storage/src/lib.rs +++ b/storage/src/lib.rs @@ -23,12 +23,11 @@ pub mod tracking_copy; pub use address_generator::{AddressGenerator, AddressGeneratorBuilder}; pub use data_access_layer::KeyPrefix; +#[cfg(test)] +pub use tracking_copy::new_temporary_tracking_copy; pub use tracking_copy::TrackingCopy; pub use block_store::{ lmdb::{DbTableId, UnknownDbTableId}, DbRawBytesSpec, }; - -#[cfg(test)] -pub use self::tracking_copy::new_temporary_tracking_copy; diff --git a/storage/src/system/mint.rs b/storage/src/system/mint.rs index 310bd824cd..dbc2e5d6d0 100644 --- a/storage/src/system/mint.rs +++ b/storage/src/system/mint.rs @@ -17,7 +17,7 @@ use casper_types::{ mint::{Error, ROUND_SEIGNIORAGE_RATE_KEY, TOTAL_SUPPLY_KEY}, Caller, }, - Key, PublicKey, SystemHashRegistry, URef, U512, + Key, PublicKey, URef, U512, }; use crate::system::mint::{ @@ -112,7 +112,7 @@ pub trait Mint: RuntimeProvider + StorageProvider + SystemProvider { if !self.allow_unrestricted_transfers() { let registry = self .get_system_entity_registry() - .unwrap_or_else(|_| SystemHashRegistry::new()); + .map_err(|_| Error::UnableToGetSystemRegistry)?; let immediate_caller = self.get_immediate_caller(); match immediate_caller { Some(Caller::Entity { entity_addr, .. }) @@ -239,9 +239,11 @@ pub trait Mint: RuntimeProvider + StorageProvider + SystemProvider { if self.available_balance(target)?.is_none() { return Err(Error::DestNotFound); } - if self.get_caller() != PublicKey::System.to_account_hash() - && self.get_main_purse().addr() == source.addr() - { + let addr = match self.get_main_purse() { + None => return Err(Error::InvalidURef), + Some(uref) => uref.addr(), + }; + if self.get_caller() != PublicKey::System.to_account_hash() && addr == source.addr() { if amount > self.get_approved_spending_limit() { return Err(Error::UnapprovedSpendingAmount); } diff --git a/storage/src/system/mint/mint_native.rs b/storage/src/system/mint/mint_native.rs index 9c7cfc867b..a722ab0149 100644 --- a/storage/src/system/mint/mint_native.rs +++ b/storage/src/system/mint/mint_native.rs @@ -91,10 +91,8 @@ where } } - fn get_main_purse(&self) -> URef { - self.runtime_footprint() - .main_purse() - .expect("tried to get main purse") + fn get_main_purse(&self) -> Option { + self.runtime_footprint().main_purse() } fn is_administrator(&self, account_hash: &AccountHash) -> bool { diff --git a/storage/src/system/mint/runtime_provider.rs b/storage/src/system/mint/runtime_provider.rs index 5570d1c92b..58a7cccf19 100644 --- a/storage/src/system/mint/runtime_provider.rs +++ b/storage/src/system/mint/runtime_provider.rs @@ -37,7 +37,7 @@ pub trait RuntimeProvider { fn sub_approved_spending_limit(&mut self, amount: U512); /// Returns main purse of the sender account. - fn get_main_purse(&self) -> URef; + fn get_main_purse(&self) -> Option; /// Returns `true` if the account hash belongs to an administrator account, otherwise `false`. fn is_administrator(&self, account_hash: &AccountHash) -> bool; diff --git a/storage/src/tracking_copy/ext_entity.rs b/storage/src/tracking_copy/ext_entity.rs index ee62f784a9..88a3d14adb 100644 --- a/storage/src/tracking_copy/ext_entity.rs +++ b/storage/src/tracking_copy/ext_entity.rs @@ -388,7 +388,7 @@ where authorization_keys: &BTreeSet, administrative_accounts: &BTreeSet, ) -> Result<(RuntimeFootprint, EntityAddr), Self::Error> { - let (entity_addr, entity_record) = + let (entity_addr, footprint) = self.runtime_footprint_by_account_hash(protocol_version, account_hash)?; if !administrative_accounts.is_empty() @@ -398,20 +398,20 @@ where .is_some() { // Exit early if there's at least a single signature coming from an admin. - return Ok((entity_record, entity_addr)); + return Ok((footprint, entity_addr)); } // Authorize using provided authorization keys - if !entity_record.can_authorize(authorization_keys) { + if !footprint.can_authorize(authorization_keys) { return Err(Self::Error::Authorization); } // Check total key weight against deploy threshold - if !entity_record.can_deploy_with(authorization_keys) { + if !footprint.can_deploy_with(authorization_keys) { return Err(Self::Error::DeploymentAuthorizationFailure); } - Ok((entity_record, entity_addr)) + Ok((footprint, entity_addr)) } fn authorized_runtime_footprint_with_access_rights( diff --git a/types/src/addressable_entity.rs b/types/src/addressable_entity.rs index f43bdf6c58..628b3867f6 100644 --- a/types/src/addressable_entity.rs +++ b/types/src/addressable_entity.rs @@ -1767,6 +1767,16 @@ mod tests { let encoded = entity_addr.to_formatted_string(); let decoded = EntityAddr::from_formatted_str(&encoded).expect("must get entity addr"); assert_eq!(decoded, entity_addr); + + let entity_addr = EntityAddr::SmartContract([5; 32]); + let encoded = entity_addr.to_formatted_string(); + let decoded = EntityAddr::from_formatted_str(&encoded).expect("must get entity addr"); + assert_eq!(decoded, entity_addr); + + let entity_addr = EntityAddr::System([5; 32]); + let encoded = entity_addr.to_formatted_string(); + let decoded = EntityAddr::from_formatted_str(&encoded).expect("must get entity addr"); + assert_eq!(decoded, entity_addr); } #[test] diff --git a/types/src/execution/execution_result.rs b/types/src/execution/execution_result.rs index 2ac76f3411..111cf3f493 100644 --- a/types/src/execution/execution_result.rs +++ b/types/src/execution/execution_result.rs @@ -177,6 +177,7 @@ mod tests { let execution_result = ExecutionResult::from(ExecutionResultV2::random(rng)); let serialized = serde_json::to_string(&execution_result).unwrap(); + println!("{:#}", serialized); let deserialized = serde_json::from_str(&serialized).unwrap(); assert_eq!(execution_result, deserialized); } diff --git a/types/src/key.rs b/types/src/key.rs index a3aa9ce8d9..79c6cd4c7e 100644 --- a/types/src/key.rs +++ b/types/src/key.rs @@ -909,6 +909,14 @@ impl Key { } } + // if let Some(contract_entity_hash) = input.strip_prefix(STATE_PREFIX) { + // let addr = match EntityAddr::from_formatted_str(contract_entity_hash) { + // Ok(ret) => ret, + // Err(err) => panic!("{err}"), + // }; + // return Ok(Key::State(addr)); + // } + Err(FromStrError::UnknownPrefix) } @@ -1993,6 +2001,7 @@ mod tests { // const STATE_KEY: Key = Key::State(EntityAddr::new_contract_entity_addr([42; 32])); const BALANCE_HOLD: Key = Key::BalanceHold(BalanceHoldAddr::new_gas([42; 32], BlockTime::new(100))); + const STATE_KEY: Key = Key::State(EntityAddr::new_smart_contract([42; 32])); const KEYS: &[Key] = &[ ACCOUNT_KEY, HASH_KEY, @@ -2024,6 +2033,7 @@ mod tests { BLOCK_TIME_KEY, BLOCK_MESSAGE_COUNT_KEY, BALANCE_HOLD, + STATE_KEY, ]; const HEX_STRING: &str = "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"; const TOPIC_NAME_HEX_STRING: &str = @@ -2200,13 +2210,13 @@ mod tests { ) ); - // assert_eq!( - // format!("{}", STATE_KEY), - // format!( - // "Key::State(addressable-entity-contract-{})", - // base16::encode_lower(&[42; 32]) - // ) - // ); + assert_eq!( + format!("{}", STATE_KEY), + format!( + "Key::State(entity-contract-{})", + base16::encode_lower(&[42; 32]) + ) + ); assert_eq!( format!("{}", BLOCK_TIME_KEY), format!( @@ -2613,7 +2623,7 @@ mod tests { bytesrepr::test_serialization_roundtrip(&MESSAGE_TOPIC_KEY); bytesrepr::test_serialization_roundtrip(&MESSAGE_KEY); bytesrepr::test_serialization_roundtrip(&NAMED_KEY); - // bytesrepr::test_serialization_roundtrip(&STATE_KEY); + bytesrepr::test_serialization_roundtrip(&STATE_KEY); } #[test] @@ -2662,6 +2672,7 @@ mod tests { round_trip(&Key::BlockGlobal(BlockGlobalAddr::BlockTime)); round_trip(&Key::BlockGlobal(BlockGlobalAddr::MessageCount)); round_trip(&Key::BalanceHold(BalanceHoldAddr::default())); + round_trip(&Key::State(EntityAddr::new_system(zeros))); } #[test] diff --git a/types/src/system/mint/error.rs b/types/src/system/mint/error.rs index 25670f8e58..35280dff56 100644 --- a/types/src/system/mint/error.rs +++ b/types/src/system/mint/error.rs @@ -159,6 +159,16 @@ pub enum Error { /// # use casper_types::system::mint::Error; /// assert_eq!(23, Error::ForgedReference as u8); ForgedReference = 23, + /// Available balance can never be greater than total balance. + /// ``` + /// # use casper_types::system::mint::Error; + /// assert_eq!(24, Error::InconsistentBalances as u8); + InconsistentBalances = 24, + /// Unable to get the system registry. + /// ``` + /// # use casper_types::system::mint::Error; + /// assert_eq!(25, Error::UnableToGetSystemRegistry as u8); + UnableToGetSystemRegistry = 25, #[cfg(test)] #[doc(hidden)] @@ -216,6 +226,10 @@ impl TryFrom for Error { Ok(Error::DisabledUnrestrictedTransfers) } d if d == Error::ForgedReference as u8 => Ok(Error::ForgedReference), + d if d == Error::InconsistentBalances as u8 => Ok(Error::InconsistentBalances), + d if d == Error::UnableToGetSystemRegistry as u8 => { + Ok(Error::UnableToGetSystemRegistry) + } _ => Err(TryFromU8ForError(())), } } @@ -277,6 +291,12 @@ impl Display for Error { formatter.write_str("Disabled unrestricted transfers") } Error::ForgedReference => formatter.write_str("Forged reference"), + Error::InconsistentBalances => { + formatter.write_str("Available balance can never be greater than total balance") + } + Error::UnableToGetSystemRegistry => { + formatter.write_str("Unable to get the system registry") + } #[cfg(test)] Error::Sentinel => formatter.write_str("Sentinel error"), }