diff --git a/execution_engine/src/execution/error.rs b/execution_engine/src/execution/error.rs index c76a2ef64e..624a399469 100644 --- a/execution_engine/src/execution/error.rs +++ b/execution_engine/src/execution/error.rs @@ -9,7 +9,7 @@ use casper_types::{ bytesrepr, execution::TransformError, system, AccessRights, AddressableEntityHash, ApiError, ByteCodeHash, CLType, CLValueError, - EntityVersionKey, Key, PackageHash, StoredValueTypeMismatch, URef, + EntityVersionKey, Key, PackageHash, StoredValueTypeMismatch, TransactionRuntime, URef, }; use casper_wasm::elements; @@ -189,6 +189,9 @@ pub enum Error { /// Invalid string encoding. #[error("Invalid UTF-8 string encoding: {0}")] InvalidUtf8Encoding(Utf8Error), + /// Incompatible transaction runtime. + #[error("Incompatible runtime: {0}")] + IncompatibleRuntime(TransactionRuntime), } impl From<PreprocessingError> for Error { diff --git a/execution_engine/src/runtime/mod.rs b/execution_engine/src/runtime/mod.rs index a3df8b951e..d7781b84b5 100644 --- a/execution_engine/src/runtime/mod.rs +++ b/execution_engine/src/runtime/mod.rs @@ -49,10 +49,10 @@ use casper_types::{ }, AccessRights, ApiError, BlockGlobalAddr, BlockTime, ByteCode, ByteCodeAddr, ByteCodeHash, ByteCodeKind, CLTyped, CLValue, ContextAccessRights, EntityAddr, EntityKind, EntityVersion, - EntityVersionKey, EntityVersions, Gas, GrantedAccess, Group, Groups, HostFunction, - HostFunctionCost, InitiatorAddr, Key, NamedArg, Package, PackageHash, PackageStatus, Phase, - PublicKey, RuntimeArgs, StoredValue, Tagged, Transfer, TransferResult, TransferV2, - TransferredTo, URef, DICTIONARY_ITEM_KEY_MAX_LENGTH, U512, + EntityVersionKey, EntityVersions, EntryPointAddr, EntryPointValue, Gas, GrantedAccess, Group, + Groups, HostFunction, HostFunctionCost, InitiatorAddr, Key, NamedArg, Package, PackageHash, + PackageStatus, Phase, PublicKey, RuntimeArgs, StoredValue, TransactionRuntime, Transfer, + TransferResult, TransferV2, TransferredTo, URef, DICTIONARY_ITEM_KEY_MAX_LENGTH, U512, }; use crate::{ @@ -1158,18 +1158,18 @@ where entry_point_name: &str, args: RuntimeArgs, ) -> Result<CLValue, ExecError> { - let (entity, entity_hash, package) = match identifier { + let (entity, entity_addr, 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(EntityKindTag::System, entity_hash) + let entity_addr = if self.context.is_system_addressable_entity(&entity_hash)? { + EntityAddr::new_system(entity_hash.value()) } else { - Key::contract_entity_key(entity_hash) + EntityAddr::new_smart_contract(entity_hash.value()) }; let entity = if let Some(StoredValue::AddressableEntity(entity)) = - self.context.read_gs(&entity_key)? + self.context.read_gs(&Key::AddressableEntity(entity_addr))? { entity } else { @@ -1190,7 +1190,7 @@ where return Err(ExecError::DisabledEntity(entity_hash)); } - (entity, entity_hash, package) + (entity, entity_addr, package) } CallContractIdentifier::ContractPackage { contract_package_hash, @@ -1224,21 +1224,21 @@ where .copied() .ok_or(ExecError::MissingEntityVersion(entity_version_key))?; - let entity_key = if self.context.is_system_addressable_entity(&entity_hash)? { - Key::addressable_entity_key(EntityKindTag::System, entity_hash) + let entity_addr = if self.context.is_system_addressable_entity(&entity_hash)? { + EntityAddr::new_system(entity_hash.value()) } else { - Key::contract_entity_key(entity_hash) + EntityAddr::new_smart_contract(entity_hash.value()) }; let entity = if let Some(StoredValue::AddressableEntity(entity)) = - self.context.read_gs(&entity_key)? + self.context.read_gs(&Key::AddressableEntity(entity_addr))? { entity } else { self.migrate_contract_and_contract_package(entity_hash)? }; - (entity, entity_hash, package) + (entity, entity_addr, package) } }; @@ -1256,10 +1256,27 @@ where }); } - let entry_point = entity - .entry_point(entry_point_name) - .cloned() - .ok_or_else(|| ExecError::NoSuchMethod(entry_point_name.to_owned()))?; + // First check if we can fetch the discrete record + // if not use the method on the tracking copy to fetch the + // full set which also peeks the cache. + let entry_point = { + let entry_point_addr = + EntryPointAddr::new_v1_entry_point_addr(entity_addr, entry_point_name)?; + match self.context.read_gs(&Key::EntryPoint(entry_point_addr))? { + Some(StoredValue::EntryPoint(EntryPointValue::V1CasperVm(entry_point))) => { + entry_point + } + Some(_) | None => { + let entry_points = self + .context + .get_casper_vm_v1_entry_point(Key::AddressableEntity(entity_addr))?; + entry_points + .get(entry_point_name) + .cloned() + .ok_or_else(|| ExecError::NoSuchMethod(entry_point_name.to_owned()))? + } + } + }; let entry_point_type = entry_point.entry_point_type(); @@ -1302,6 +1319,8 @@ where } } + let entity_hash = AddressableEntityHash::new(entity_addr.value()); + if !self .context .engine_config() @@ -1363,8 +1382,6 @@ where all_urefs }; - let entity_addr = entity.entity_addr(entity_hash); - let entity_named_keys = self .context .state() @@ -1425,9 +1442,12 @@ where EntityKind::System(_) | EntityKind::Account(_) => { Key::ByteCode(ByteCodeAddr::Empty) } - EntityKind::SmartContract => { + EntityKind::SmartContract(TransactionRuntime::VmCasperV1) => { Key::ByteCode(ByteCodeAddr::new_wasm_addr(byte_code_addr)) } + EntityKind::SmartContract(runtime @ TransactionRuntime::VmCasperV2) => { + return Err(ExecError::IncompatibleRuntime(runtime)) + } }; let byte_code: ByteCode = match self.context.read_gs(&byte_code_key)? { @@ -1439,11 +1459,9 @@ where casper_wasm::deserialize_buffer(byte_code.bytes())? }; - let entity_tag = entity.kind().tag(); - let mut named_keys = entity_named_keys; - let context_entity_key = Key::addressable_entity_key(entity_tag, entity_hash); + let context_entity_key = Key::AddressableEntity(entity_addr); let context = self.context.new_from_self( context_entity_key, @@ -1748,9 +1766,9 @@ where return Ok(Err(ApiError::NotAllowedToAddContractVersion)); } - if entry_points.contains_stored_session() { - return Err(ExecError::InvalidEntryPointType); - } + // if entry_points.contains_stored_session() { + // return Err(ExecError::InvalidEntryPointType); + // } let mut package = self.context.get_package(package_hash)?; @@ -1820,16 +1838,17 @@ where named_keys.append(previous_named_keys); self.context.write_named_keys(entity_addr, named_keys)?; + self.context.write_entry_points(entity_addr, entry_points)?; + let entity = AddressableEntity::new( package_hash, byte_code_hash.into(), - entry_points, protocol_version, main_purse, associated_keys, action_thresholds, previous_message_topics.clone(), - EntityKind::SmartContract, + EntityKind::SmartContract(TransactionRuntime::VmCasperV1), ); self.context.metered_write_gs_unsafe(entity_key, entity)?; @@ -2487,13 +2506,11 @@ where 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 entry_points = EntryPoints::new(); let message_topics = MessageTopics::default(); let entity = AddressableEntity::new( package_hash, byte_code_hash, - entry_points, protocol_version, main_purse, associated_keys, @@ -2970,12 +2987,10 @@ where let versions = package.versions(); for entity_hash in versions.contract_hashes() { let entry_points = { - let entity: AddressableEntity = self - .context - .read_gs_typed(&Key::contract_entity_key(*entity_hash))?; - entity.entry_points().clone().take_entry_points() + self.context + .get_casper_vm_v1_entry_point(Key::contract_entity_key(*entity_hash))? }; - for entry_point in entry_points { + for entry_point in entry_points.take_entry_points() { match entry_point.access() { EntryPointAccess::Public | EntryPointAccess::Template => { continue; diff --git a/execution_engine/src/runtime_context/mod.rs b/execution_engine/src/runtime_context/mod.rs index 77a6152e48..cb601fe77a 100644 --- a/execution_engine/src/runtime_context/mod.rs +++ b/execution_engine/src/runtime_context/mod.rs @@ -33,10 +33,11 @@ use casper_types::{ handle_stored_dictionary_value, system::auction::EraInfo, AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, CLType, CLValue, - CLValueDictionary, ContextAccessRights, EntityAddr, EntryPointType, Gas, GrantedAccess, Key, - KeyTag, Motes, Package, PackageHash, Phase, ProtocolVersion, PublicKey, RuntimeArgs, - StoredValue, StoredValueTypeMismatch, SystemEntityRegistry, TransactionHash, Transfer, URef, - URefAddr, DICTIONARY_ITEM_KEY_MAX_LENGTH, KEY_HASH_LENGTH, U512, + CLValueDictionary, ContextAccessRights, EntityAddr, EntryPointAddr, EntryPointType, + EntryPointValue, EntryPoints, Gas, GrantedAccess, Key, KeyTag, Motes, Package, PackageHash, + Phase, ProtocolVersion, PublicKey, RuntimeArgs, StoredValue, StoredValueTypeMismatch, + SystemEntityRegistry, TransactionHash, Transfer, URef, URefAddr, + DICTIONARY_ITEM_KEY_MAX_LENGTH, KEY_HASH_LENGTH, U512, }; use crate::{engine_state::EngineConfig, execution::ExecError}; @@ -419,6 +420,42 @@ where .map_err(Into::into) } + pub(crate) fn write_entry_points( + &mut self, + entity_addr: EntityAddr, + entry_points: EntryPoints, + ) -> Result<(), ExecError> { + if entry_points.is_empty() { + return Ok(()); + } + + for entry_point in entry_points.take_entry_points() { + let entry_point_addr = + EntryPointAddr::new_v1_entry_point_addr(entity_addr, entry_point.name())?; + let entry_point_value = + StoredValue::EntryPoint(EntryPointValue::V1CasperVm(entry_point)); + self.metered_write_gs_unsafe(Key::EntryPoint(entry_point_addr), entry_point_value)?; + } + + Ok(()) + } + + pub(crate) fn get_casper_vm_v1_entry_point( + &mut self, + entity_key: Key, + ) -> Result<EntryPoints, ExecError> { + let entity_addr = if let Key::AddressableEntity(entity_addr) = entity_key { + entity_addr + } else { + return Err(ExecError::UnexpectedKeyVariant(entity_key)); + }; + + self.tracking_copy + .borrow_mut() + .get_v1_entry_points(entity_addr) + .map_err(Into::into) + } + #[cfg(test)] pub(crate) fn get_entity(&self) -> AddressableEntity { self.entity.clone() @@ -676,7 +713,8 @@ where | StoredValue::ContractWasm(_) | StoredValue::MessageTopic(_) | StoredValue::Message(_) - | StoredValue::Reservation(_) => Ok(()), + | StoredValue::Reservation(_) + | StoredValue::EntryPoint(_) => Ok(()), } } diff --git a/execution_engine/src/runtime_context/tests.rs b/execution_engine/src/runtime_context/tests.rs index 3eef5ce83a..3bc019bc10 100644 --- a/execution_engine/src/runtime_context/tests.rs +++ b/execution_engine/src/runtime_context/tests.rs @@ -18,9 +18,9 @@ use casper_types::{ execution::TransformKindV2, system::{AUCTION, HANDLE_PAYMENT, MINT, STANDARD_PAYMENT}, AccessRights, AddressableEntity, AddressableEntityHash, BlockGlobalAddr, BlockTime, - ByteCodeHash, CLValue, ContextAccessRights, EntityAddr, EntityKind, EntryPointType, - EntryPoints, Gas, Key, PackageHash, Phase, ProtocolVersion, PublicKey, RuntimeArgs, SecretKey, - StoredValue, SystemEntityRegistry, Tagged, Timestamp, TransactionHash, TransactionV1Hash, URef, + ByteCodeHash, CLValue, ContextAccessRights, EntityAddr, EntityKind, EntryPointType, Gas, Key, + PackageHash, Phase, ProtocolVersion, PublicKey, RuntimeArgs, SecretKey, StoredValue, + SystemEntityRegistry, Tagged, Timestamp, TransactionHash, TransactionV1Hash, URef, KEY_HASH_LENGTH, U256, U512, }; use tempfile::TempDir; @@ -65,7 +65,6 @@ fn new_addressable_entity_with_purse( let entity = AddressableEntity::new( PackageHash::default(), ByteCodeHash::default(), - EntryPoints::new_with_default_entry_point(), ProtocolVersion::V1_0_0, URef::new(purse, AccessRights::READ_ADD_WRITE), associated_keys, 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 fafd7115df..512ac2ef75 100644 --- a/execution_engine_testing/test_support/src/wasm_test_builder.rs +++ b/execution_engine_testing/test_support/src/wasm_test_builder.rs @@ -64,9 +64,9 @@ use casper_types::{ }, AccessRights, AddressableEntity, AddressableEntityHash, AuctionCosts, BlockGlobalAddr, BlockTime, ByteCode, ByteCodeAddr, ByteCodeHash, CLTyped, CLValue, Contract, Digest, - EntityAddr, EraId, Gas, HandlePaymentCosts, HoldBalanceHandling, InitiatorAddr, Key, KeyTag, - MintCosts, Motes, Package, PackageHash, Phase, ProtocolUpgradeConfig, ProtocolVersion, - PublicKey, RefundHandling, StoredValue, SystemEntityRegistry, TransactionHash, + EntityAddr, EntryPoints, EraId, Gas, HandlePaymentCosts, HoldBalanceHandling, InitiatorAddr, + Key, KeyTag, MintCosts, Motes, Package, PackageHash, Phase, ProtocolUpgradeConfig, + ProtocolVersion, PublicKey, RefundHandling, StoredValue, SystemEntityRegistry, TransactionHash, TransactionV1Hash, URef, OS_PAGE_SIZE, U512, }; @@ -1661,6 +1661,21 @@ where reader.keys_with_prefix(&[tag as u8]) } + /// Gets all entry points for a given entity + pub fn get_entry_points(&self, entity_addr: EntityAddr) -> EntryPoints { + let state_root_hash = self.get_post_state_hash(); + + let mut tracking_copy = self + .data_access_layer + .tracking_copy(state_root_hash) + .unwrap() + .unwrap(); + + tracking_copy + .get_v1_entry_points(entity_addr) + .expect("must get entry points") + } + /// Gets a stored value from a contract's named keys. pub fn get_value<T>(&mut self, entity_addr: EntityAddr, name: &str) -> T where 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 index 58f215e5a9..f0ccb90f6f 100644 Binary files a/execution_engine_testing/tests/fixtures/call_stack_fixture/global_state/data.lmdb 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 index aa22a60985..8895627f68 100644 Binary files a/execution_engine_testing/tests/fixtures/call_stack_fixture/global_state/data.lmdb-lock 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 index 7cd638af7d..9eac419a40 100644 --- a/execution_engine_testing/tests/fixtures/call_stack_fixture/state.json +++ b/execution_engine_testing/tests/fixtures/call_stack_fixture/state.json @@ -2,5 +2,5 @@ "genesis_request": { "protocol_version": "2.0.0" }, - "post_state_hash": "9e58f96c2051b314545821d2bec3e8ed7679b46f9664a97402affafd0e91bf73" + "post_state_hash": "142b11d6b28f64826957efb079aed265004964f6c0a70c1bbe813cb752918b9c" } \ 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 index 7cb0fa39ff..65200b43c1 100644 Binary files a/execution_engine_testing/tests/fixtures/groups/global_state/data.lmdb 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 index 4f9c943b5c..01ff3b5378 100644 Binary files a/execution_engine_testing/tests/fixtures/groups/global_state/data.lmdb-lock 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 index 31c9a7e7cd..723261d4c6 100644 --- a/execution_engine_testing/tests/fixtures/groups/state.json +++ b/execution_engine_testing/tests/fixtures/groups/state.json @@ -2,5 +2,5 @@ "genesis_request": { "protocol_version": "2.0.0" }, - "post_state_hash": "373e18a37b361d454f61ed423fc128d7d7d5191e866639822996fa5915815ce2" + "post_state_hash": "f20f7ce0bb0b1f42605b58a488d87f0beaf17e6eeb6e63fafdcee1ea638e118f" } \ No newline at end of file diff --git a/execution_engine_testing/tests/src/test/explorer/faucet.rs b/execution_engine_testing/tests/src/test/explorer/faucet.rs index b651b2ebfa..c9bf2390de 100644 --- a/execution_engine_testing/tests/src/test/explorer/faucet.rs +++ b/execution_engine_testing/tests/src/test/explorer/faucet.rs @@ -926,10 +926,10 @@ fn faucet_costs() { // This test will fail if execution costs vary. The expected costs should not be updated // without understanding why the cost has changed. If the costs do change, it should be // reflected in the "Costs by Entry Point" section of the faucet crate's README.md. - const EXPECTED_FAUCET_INSTALL_COST: u64 = 89_201_674_240; - const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 111_263_840; - const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_750_259_320; - const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_619_720_120; + const EXPECTED_FAUCET_INSTALL_COST: u64 = 91_712_843_810; + const EXPECTED_FAUCET_SET_VARIABLES_COST: u64 = 111_285_530; + const EXPECTED_FAUCET_CALL_BY_INSTALLER_COST: u64 = 2_747_759_050; + const EXPECTED_FAUCET_CALL_BY_USER_COST: u64 = 2_619_760_730; let installer_account = AccountHash::new([1u8; 32]); let user_account: AccountHash = AccountHash::new([2u8; 32]); diff --git a/execution_engine_testing/tests/src/test/regression/regression_20220303.rs b/execution_engine_testing/tests/src/test/regression/regression_20220303.rs index 60aaef2892..bd8f60d18a 100644 --- a/execution_engine_testing/tests/src/test/regression/regression_20220303.rs +++ b/execution_engine_testing/tests/src/test/regression/regression_20220303.rs @@ -7,8 +7,8 @@ use casper_engine_test_support::{LmdbWasmTestBuilder, UpgradeRequestBuilder}; use casper_types::{ contracts::ContractHash, system::{self, mint}, - AccessRights, ByteCodeHash, CLValue, Digest, EraId, Key, ProtocolVersion, StoredValue, - SystemEntityRegistry, URef, + AccessRights, ByteCodeHash, CLValue, Digest, EntityAddr, EntryPoints, EraId, Key, + ProtocolVersion, StoredValue, SystemEntityRegistry, URef, }; use rand::Rng; @@ -62,10 +62,10 @@ fn test_upgrade(major_bump: u32, minor_bump: u32, patch_bump: u32, upgrade_entri let legacy_mint_hash = ContractHash::new(mint_contract_hash.value()); - let old_contract = builder + let old_mint_contract = builder .get_legacy_contract(legacy_mint_hash) .expect("should have mint contract"); - assert_eq!(old_contract.protocol_version(), old_protocol_version); + assert_eq!(old_mint_contract.protocol_version(), old_protocol_version); let new_protocol_version = ProtocolVersion::from_parts( old_protocol_version.value().major + major_bump, old_protocol_version.value().minor + minor_bump, @@ -106,16 +106,18 @@ 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().value(), + old_mint_contract.contract_package_hash().value(), new_contract.package_hash().value() ); assert_eq!( ByteCodeHash::default().value(), new_contract.byte_code_hash().value() ); - assert_ne!(old_contract.entry_points(), new_contract.entry_points()); + let new_entry_points = builder.get_entry_points(EntityAddr::System(mint_contract_hash.value())); + let old_entry_points = EntryPoints::from(old_mint_contract.entry_points().clone()); + assert_ne!(&old_entry_points, &new_entry_points); assert_eq!( - new_contract.entry_points(), + &new_entry_points, &mint::mint_entry_points(), "should have new entrypoints written" ); diff --git a/node/src/components/contract_runtime.rs b/node/src/components/contract_runtime.rs index 57fa0e35a3..d67557a147 100644 --- a/node/src/components/contract_runtime.rs +++ b/node/src/components/contract_runtime.rs @@ -29,9 +29,9 @@ use tracing::{debug, error, info, trace}; use casper_execution_engine::engine_state::{EngineConfigBuilder, ExecutionEngineV1}; use casper_storage::{ data_access_layer::{ - AddressableEntityRequest, BlockStore, DataAccessLayer, ExecutionResultsChecksumRequest, - FlushRequest, FlushResult, GenesisRequest, GenesisResult, ProtocolUpgradeRequest, - ProtocolUpgradeResult, TrieRequest, + AddressableEntityRequest, BlockStore, DataAccessLayer, EntryPointsRequest, + ExecutionResultsChecksumRequest, FlushRequest, FlushResult, GenesisRequest, GenesisResult, + ProtocolUpgradeRequest, ProtocolUpgradeResult, TrieRequest, }, global_state::{ state::{lmdb::LmdbGlobalState, CommitProvider, StateProvider}, @@ -394,6 +394,24 @@ impl ContractRuntime { } .ignore() } + ContractRuntimeRequest::GetEntryPoint { + state_root_hash, + key, + responder, + } => { + trace!(?state_root_hash, "get entry point"); + let metrics = Arc::clone(&self.metrics); + let data_access_layer = Arc::clone(&self.data_access_layer); + async move { + let start = Instant::now(); + let request = EntryPointsRequest::new(state_root_hash, key); + let result = data_access_layer.entry_point(request); + metrics.entry_points.observe(start.elapsed().as_secs_f64()); + trace!(?result, "get addressable entity"); + responder.respond(result).await + } + .ignore() + } ContractRuntimeRequest::GetTaggedValues { request: tagged_values_request, responder, diff --git a/node/src/components/contract_runtime/metrics.rs b/node/src/components/contract_runtime/metrics.rs index 439c265cc6..40ef5748ed 100644 --- a/node/src/components/contract_runtime/metrics.rs +++ b/node/src/components/contract_runtime/metrics.rs @@ -68,6 +68,9 @@ const EXECUTION_RESULTS_CHECKSUM_HELP: &str = "contract_runtime_execution_result const ADDRESSABLE_ENTITY_NAME: &str = "contract_runtime_addressable_entity"; const ADDRESSABLE_ENTITY_HELP: &str = "contract_runtime_addressable_entity"; +const ENTRY_POINT_NAME: &str = "contract_runtime_entry_point"; +const ENTRY_POINT_HELP: &str = "contract_runtime_entry_point"; + const PUT_TRIE_NAME: &str = "contract_runtime_put_trie"; const PUT_TRIE_HELP: &str = "time in seconds to put a trie"; @@ -87,12 +90,18 @@ const EXEC_QUEUE_SIZE_HELP: &str = /// Metrics for the contract runtime component. #[derive(Debug)] pub struct Metrics { - pub(super) exec_block_pre_processing: Histogram, // elapsed before tnx processing - pub(super) exec_block_tnx_processing: Histogram, // tnx processing elapsed - pub(super) exec_wasm_v1: Histogram, // ee_v1 execution elapsed - pub(super) exec_block_step_processing: Histogram, // step processing elapsed - pub(super) exec_block_post_processing: Histogram, // elapsed after tnx processing - pub(super) exec_block_total: Histogram, // total elapsed + pub(super) exec_block_pre_processing: Histogram, + // elapsed before tnx processing + pub(super) exec_block_tnx_processing: Histogram, + // tnx processing elapsed + pub(super) exec_wasm_v1: Histogram, + // ee_v1 execution elapsed + pub(super) exec_block_step_processing: Histogram, + // step processing elapsed + pub(super) exec_block_post_processing: Histogram, + // elapsed after tnx processing + pub(super) exec_block_total: Histogram, + // total elapsed pub(super) commit_genesis: Histogram, pub(super) commit_upgrade: Histogram, pub(super) run_query: Histogram, @@ -104,6 +113,7 @@ pub struct Metrics { pub(super) get_all_values: Histogram, pub(super) execution_results_checksum: Histogram, pub(super) addressable_entity: Histogram, + pub(super) entry_points: Histogram, pub(super) put_trie: Histogram, pub(super) get_trie: Histogram, pub(super) latest_commit_step: Gauge, @@ -233,6 +243,12 @@ impl Metrics { registry, ADDRESSABLE_ENTITY_NAME, ADDRESSABLE_ENTITY_HELP, + common_buckets.clone(), + )?, + entry_points: utils::register_histogram_metric( + registry, + ENTRY_POINT_NAME, + ENTRY_POINT_HELP, common_buckets, )?, get_trie: utils::register_histogram_metric( @@ -276,5 +292,6 @@ impl Drop for Metrics { unregister_metric!(self.registry, self.get_trie); unregister_metric!(self.registry, self.latest_commit_step); unregister_metric!(self.registry, self.exec_queue_size); + unregister_metric!(self.registry, self.entry_points); } } diff --git a/node/src/components/transaction_acceptor.rs b/node/src/components/transaction_acceptor.rs index d5bc26a75a..bcbdbee2ba 100644 --- a/node/src/components/transaction_acceptor.rs +++ b/node/src/components/transaction_acceptor.rs @@ -15,10 +15,10 @@ use casper_storage::data_access_layer::{balance::BalanceHandling, BalanceRequest use casper_types::{ account::AccountHash, addressable_entity::AddressableEntity, contracts::ContractHash, system::auction::ARG_AMOUNT, AddressableEntityHash, AddressableEntityIdentifier, BlockHeader, - Chainspec, EntityAddr, EntityVersion, EntityVersionKey, ExecutableDeployItem, - ExecutableDeployItemIdentifier, InitiatorAddr, Key, Package, PackageAddr, PackageHash, - PackageIdentifier, Transaction, TransactionEntryPoint, TransactionInvocationTarget, - TransactionTarget, U512, + Chainspec, EntityAddr, EntityVersion, EntityVersionKey, EntryPoint, EntryPointAddr, + ExecutableDeployItem, ExecutableDeployItemIdentifier, InitiatorAddr, Key, Package, PackageAddr, + PackageHash, PackageIdentifier, Transaction, TransactionEntryPoint, + TransactionInvocationTarget, TransactionTarget, U512, }; use crate::{ @@ -557,26 +557,25 @@ impl TransactionAcceptor { contract_hash: AddressableEntityHash, maybe_contract: Option<AddressableEntity>, ) -> Effects<Event> { - let entity = match maybe_contract { - Some(contract) => contract, - None => { - let error = Error::parameter_failure( - &block_header, - ParameterFailure::NoSuchContractAtHash { contract_hash }, - ); - return self.reject_transaction(effect_builder, *event_metadata, error); - } - }; + if maybe_contract.is_none() { + let error = Error::parameter_failure( + &block_header, + ParameterFailure::NoSuchContractAtHash { contract_hash }, + ); + return self.reject_transaction(effect_builder, *event_metadata, error); + } let maybe_entry_point_name = match &event_metadata.transaction { - Transaction::Deploy(deploy) if is_payment => Some(deploy.payment().entry_point_name()), - Transaction::Deploy(deploy) => Some(deploy.session().entry_point_name()), + Transaction::Deploy(deploy) if is_payment => { + Some(deploy.payment().entry_point_name().to_string()) + } + Transaction::Deploy(deploy) => Some(deploy.session().entry_point_name().to_string()), Transaction::V1(_) if is_payment => { error!("should not fetch a contract to validate payment logic for transaction v1s"); None } Transaction::V1(txn) => match txn.entry_point() { - TransactionEntryPoint::Custom(name) => Some(name.as_str()), + TransactionEntryPoint::Custom(name) => Some(name.clone()), TransactionEntryPoint::Transfer | TransactionEntryPoint::AddBid | TransactionEntryPoint::WithdrawBid @@ -588,17 +587,69 @@ impl TransactionAcceptor { }, }; - if let Some(entry_point_name) = maybe_entry_point_name { - if !entity.entry_points().has_entry_point(entry_point_name) { + match maybe_entry_point_name { + Some(entry_point_name) => { + match EntryPointAddr::new_v1_entry_point_addr( + EntityAddr::SmartContract(contract_hash.value()), + &entry_point_name, + ) { + Ok(entry_point_addr) => effect_builder + .get_entry_point_value( + *block_header.state_root_hash(), + Key::EntryPoint(entry_point_addr), + ) + .event(move |entry_point_result| Event::GetEntryPointResult { + event_metadata, + block_header, + is_payment, + entry_point_name, + maybe_entry_point: entry_point_result.into_v1_entry_point(), + }), + Err(_) => { + let error = Error::parameter_failure( + &block_header, + ParameterFailure::NoSuchEntryPoint { entry_point_name }, + ); + return self.reject_transaction(effect_builder, *event_metadata, error); + } + } + } + None => { + if is_payment { + return self.verify_body(effect_builder, event_metadata, block_header); + } + self.validate_transaction_cryptography(effect_builder, event_metadata) + } + } + } + + fn handle_get_entry_point_result<REv: ReactorEventT>( + &self, + effect_builder: EffectBuilder<REv>, + event_metadata: Box<EventMetadata>, + block_header: Box<BlockHeader>, + is_payment: bool, + entry_point_name: String, + maybe_entry_point: Option<EntryPoint>, + ) -> Effects<Event> { + let entry_point = match maybe_entry_point { + Some(entry_point) => entry_point, + None => { let error = Error::parameter_failure( &block_header, - ParameterFailure::NoSuchEntryPoint { - entry_point_name: entry_point_name.to_string(), - }, + ParameterFailure::NoSuchEntryPoint { entry_point_name }, ); return self.reject_transaction(effect_builder, *event_metadata, error); } - } + }; + + if entry_point_name != *entry_point.name() { + let error = Error::parameter_failure( + &block_header, + ParameterFailure::NoSuchEntryPoint { entry_point_name }, + ); + return self.reject_transaction(effect_builder, *event_metadata, error); + }; if is_payment { return self.verify_body(effect_builder, event_metadata, block_header); @@ -900,6 +951,20 @@ impl<REv: ReactorEventT> Component<REv> for TransactionAcceptor { maybe_package_version, maybe_package, ), + Event::GetEntryPointResult { + event_metadata, + block_header, + is_payment, + entry_point_name, + maybe_entry_point, + } => self.handle_get_entry_point_result( + effect_builder, + event_metadata, + block_header, + is_payment, + entry_point_name, + maybe_entry_point, + ), Event::PutToStorageResult { event_metadata, is_new, diff --git a/node/src/components/transaction_acceptor/event.rs b/node/src/components/transaction_acceptor/event.rs index a9102325ac..459608144f 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::{ - AddressableEntity, AddressableEntityHash, BlockHeader, EntityVersion, Package, PackageHash, - Timestamp, Transaction, U512, + AddressableEntity, AddressableEntityHash, BlockHeader, EntityVersion, EntryPoint, Package, + PackageHash, Timestamp, Transaction, U512, }; use super::{Error, Source}; @@ -91,6 +91,14 @@ pub(crate) enum Event { maybe_package_version: Option<EntityVersion>, maybe_package: Option<Box<Package>>, }, + /// The result of querying global state for an `EntryPoint` to verify the executable logic. + GetEntryPointResult { + event_metadata: Box<EventMetadata>, + block_header: Box<BlockHeader>, + is_payment: bool, + entry_point_name: String, + maybe_entry_point: Option<EntryPoint>, + }, } impl Display for Event { @@ -186,6 +194,18 @@ impl Display for Event { block_header.state_root_hash() ) } + Event::GetEntryPointResult { + event_metadata, + block_header, + .. + } => { + write!( + formatter, + "verifying entry point to validate transaction with hash {} with state hash {}", + event_metadata.transaction.hash(), + block_header.state_root_hash(), + ) + } } } } diff --git a/node/src/components/transaction_acceptor/tests.rs b/node/src/components/transaction_acceptor/tests.rs index 31d9a7ee81..2e893e22ce 100644 --- a/node/src/components/transaction_acceptor/tests.rs +++ b/node/src/components/transaction_acceptor/tests.rs @@ -23,7 +23,8 @@ use tokio::time; use casper_execution_engine::engine_state::MAX_PAYMENT_AMOUNT; use casper_storage::{ data_access_layer::{ - AddressableEntityResult, BalanceIdentifier, BalanceResult, ProofsResult, QueryResult, + AddressableEntityResult, BalanceIdentifier, BalanceResult, EntryPointsResult, ProofsResult, + QueryResult, }, tracking_copy::TrackingCopyError, }; @@ -33,10 +34,11 @@ use casper_types::{ bytesrepr::Bytes, global_state::TrieMerkleProof, testing::TestRng, - Block, BlockV2, CLValue, Chainspec, ChainspecRawBytes, Contract, Deploy, EraId, HashAddr, - InvalidDeploy, InvalidTransaction, InvalidTransactionV1, Package, PricingMode, ProtocolVersion, - PublicKey, SecretKey, StoredValue, TestBlockBuilder, TimeDiff, Timestamp, Transaction, - TransactionConfig, TransactionSessionKind, TransactionV1, TransactionV1Builder, URef, U512, + Block, BlockV2, CLValue, Chainspec, ChainspecRawBytes, Contract, Deploy, EntryPointValue, + EraId, HashAddr, InvalidDeploy, InvalidTransaction, InvalidTransactionV1, Package, PricingMode, + ProtocolVersion, PublicKey, SecretKey, StoredValue, TestBlockBuilder, TimeDiff, Timestamp, + Transaction, TransactionConfig, TransactionSessionKind, TransactionV1, TransactionV1Builder, + URef, U512, }; use super::*; @@ -633,6 +635,18 @@ impl TestScenario { | TestScenario::FromPeerRepeatedValidTransaction(_) ) } + + fn contract_scenario(&self) -> Option<ContractScenario> { + match self { + TestScenario::FromPeerCustomPaymentContract(contract_scenario) + | TestScenario::FromPeerSessionContract(_, contract_scenario) + | TestScenario::FromClientCustomPaymentContract(contract_scenario) + | TestScenario::FromClientSessionContract(_, contract_scenario) => { + Some(*contract_scenario) + } + _ => None, + } + } } fn create_account(account_hash: AccountHash, test_scenario: TestScenario) -> Account { @@ -892,6 +906,27 @@ impl reactor::Reactor for Reactor { }; responder.respond(result).ignore() } + ContractRuntimeRequest::GetEntryPoint { + state_root_hash: _, + responder, + .. + } => { + let contract_scenario = self + .test_scenario + .contract_scenario() + .expect("must get contract scenario"); + let result = match contract_scenario { + ContractScenario::Valid => EntryPointsResult::Success { + entry_point: EntryPointValue::V1CasperVm(EntryPoint::default()), + }, + ContractScenario::MissingContractAtHash + | ContractScenario::MissingContractAtName + | ContractScenario::MissingEntryPoint => { + EntryPointsResult::ValueNotFound("entry point not found".to_string()) + } + }; + responder.respond(result).ignore() + } _ => panic!("should not receive {:?}", event), }, Event::NetworkRequest(_) => panic!("test does not handle network requests"), diff --git a/node/src/effect.rs b/node/src/effect.rs index 922827529c..7c40a41889 100644 --- a/node/src/effect.rs +++ b/node/src/effect.rs @@ -166,6 +166,7 @@ use announcements::{ PeerBehaviorAnnouncement, QueueDumpFormat, TransactionAcceptorAnnouncement, TransactionBufferAnnouncement, UnexecutedBlockAnnouncement, UpgradeWatcherAnnouncement, }; +use casper_storage::data_access_layer::EntryPointsResult; use diagnostics_port::DumpConsensusStateRequest; use requests::{ AcceptTransactionRequest, BeginGossipRequest, BlockAccumulatorRequest, @@ -2032,6 +2033,26 @@ impl<REv> EffectBuilder<REv> { .await } + /// Retrieves an `EntryPointValue` from under the given key in global state if present. + pub(crate) async fn get_entry_point_value( + self, + state_root_hash: Digest, + key: Key, + ) -> EntryPointsResult + where + REv: From<ContractRuntimeRequest>, + { + self.make_request( + |responder| ContractRuntimeRequest::GetEntryPoint { + state_root_hash, + key, + responder, + }, + QueueKind::ContractRuntime, + ) + .await + } + /// Retrieves a `Package` from under the given key in global state if present. pub(crate) async fn get_package(self, state_root_hash: Digest, key: Key) -> Option<Box<Package>> where diff --git a/node/src/effect/requests.rs b/node/src/effect/requests.rs index 706f96afb5..02ac13cddb 100644 --- a/node/src/effect/requests.rs +++ b/node/src/effect/requests.rs @@ -22,9 +22,9 @@ use casper_storage::{ block_store::types::ApprovalsHashes, data_access_layer::{ tagged_values::{TaggedValuesRequest, TaggedValuesResult}, - AddressableEntityResult, BalanceRequest, BalanceResult, EraValidatorsRequest, - EraValidatorsResult, ExecutionResultsChecksumResult, PutTrieRequest, PutTrieResult, - QueryRequest, QueryResult, TrieRequest, TrieResult, + AddressableEntityResult, BalanceRequest, BalanceResult, EntryPointsResult, + EraValidatorsRequest, EraValidatorsResult, ExecutionResultsChecksumResult, PutTrieRequest, + PutTrieResult, QueryRequest, QueryResult, TrieRequest, TrieResult, }, DbRawBytesSpec, }; @@ -808,6 +808,13 @@ pub(crate) enum ContractRuntimeRequest { key: Key, responder: Responder<AddressableEntityResult>, }, + /// Returns a singular entry point based under the given state root hash and entry + /// point key. + GetEntryPoint { + state_root_hash: Digest, + key: Key, + responder: Responder<EntryPointsResult>, + }, /// Get a trie or chunk by its ID. GetTrie { /// A request for a trie element. @@ -913,6 +920,17 @@ impl Display for ContractRuntimeRequest { ContractRuntimeRequest::GetEraGasPrice { era_id, .. } => { write!(formatter, "Get gas price for era {}", era_id) } + ContractRuntimeRequest::GetEntryPoint { + state_root_hash, + key, + .. + } => { + write!( + formatter, + "get entry point {} under {}", + key, state_root_hash + ) + } } } } diff --git a/resources/test/sse_data_schema.json b/resources/test/sse_data_schema.json index 485df92a33..2000e25c28 100644 --- a/resources/test/sse_data_schema.json +++ b/resources/test/sse_data_schema.json @@ -1975,6 +1975,13 @@ "enum": [ "VmCasperV1" ] + }, + { + "description": "The Casper Version 2 Virtual Machine.", + "type": "string", + "enum": [ + "VmCasperV2" + ] } ] }, @@ -3042,42 +3049,6 @@ }, "additionalProperties": false }, - "Bridge": { - "description": "A bridge record pointing to a new `ValidatorBid` after the public key was changed.", - "type": "object", - "required": [ - "era_id", - "new_validator_public_key", - "old_validator_public_key" - ], - "properties": { - "old_validator_public_key": { - "description": "Previous validator public key associated with the bid.", - "allOf": [ - { - "$ref": "#/definitions/PublicKey" - } - ] - }, - "new_validator_public_key": { - "description": "New validator public key associated with the bid.", - "allOf": [ - { - "$ref": "#/definitions/PublicKey" - } - ] - }, - "era_id": { - "description": "Era when bridge record was created.", - "allOf": [ - { - "$ref": "#/definitions/EraId" - } - ] - } - }, - "additionalProperties": false - }, "WithdrawPurse": { "description": "A withdraw purse, a legacy structure.", "type": "object", @@ -3348,6 +3319,42 @@ }, "additionalProperties": false }, + "Bridge": { + "description": "A bridge record pointing to a new `ValidatorBid` after the public key was changed.", + "type": "object", + "required": [ + "era_id", + "new_validator_public_key", + "old_validator_public_key" + ], + "properties": { + "old_validator_public_key": { + "description": "Previous validator public key associated with the bid.", + "allOf": [ + { + "$ref": "#/definitions/PublicKey" + } + ] + }, + "new_validator_public_key": { + "description": "New validator public key associated with the bid.", + "allOf": [ + { + "$ref": "#/definitions/PublicKey" + } + ] + }, + "era_id": { + "description": "Era when bridge record was created.", + "allOf": [ + { + "$ref": "#/definitions/EraId" + } + ] + } + }, + "additionalProperties": false + }, "ExecutionResultV2": { "description": "The result of executing a single transaction.", "type": "object", @@ -3982,6 +3989,19 @@ } }, "additionalProperties": false + }, + { + "description": "An entrypoint record.", + "type": "object", + "required": [ + "EntryPoint" + ], + "properties": { + "EntryPoint": { + "$ref": "#/definitions/EntryPointValue" + } + }, + "additionalProperties": false } ] }, @@ -4431,7 +4451,6 @@ "associated_keys", "byte_code_hash", "entity_kind", - "entry_points", "main_purse", "message_topics", "package_hash", @@ -4453,9 +4472,6 @@ "main_purse": { "$ref": "#/definitions/URef" }, - "entry_points": { - "$ref": "#/definitions/Array_of_NamedEntryPoint" - }, "associated_keys": { "$ref": "#/definitions/EntityAssociatedKeys" }, @@ -4498,10 +4514,16 @@ }, { "description": "Packages associated with Wasm stored on chain.", - "type": "string", - "enum": [ + "type": "object", + "required": [ "SmartContract" - ] + ], + "properties": { + "SmartContract": { + "$ref": "#/definitions/TransactionRuntime" + } + }, + "additionalProperties": false } ] }, @@ -4851,6 +4873,120 @@ } } }, + "EntryPointValue": { + "description": "The encaspulated representation of entrypoints.", + "oneOf": [ + { + "description": "Entrypoints to be executed against the V1 Casper VM.", + "type": "object", + "required": [ + "V1CasperVm" + ], + "properties": { + "V1CasperVm": { + "$ref": "#/definitions/EntryPoint2" + } + }, + "additionalProperties": false + }, + { + "description": "Entrypoints to be executed against the V2 Casper VM.", + "type": "object", + "required": [ + "V2CasperVm" + ], + "properties": { + "V2CasperVm": { + "$ref": "#/definitions/EntryPointV2" + } + }, + "additionalProperties": false + } + ] + }, + "EntryPoint2": { + "description": "Type signature of a method. Order of arguments matter since can be referenced by index as well as name.", + "type": "object", + "required": [ + "access", + "args", + "entry_point_payment", + "entry_point_type", + "name", + "ret" + ], + "properties": { + "name": { + "type": "string" + }, + "args": { + "type": "array", + "items": { + "$ref": "#/definitions/Parameter" + } + }, + "ret": { + "$ref": "#/definitions/CLType" + }, + "access": { + "$ref": "#/definitions/EntryPointAccess" + }, + "entry_point_type": { + "$ref": "#/definitions/EntryPointType" + }, + "entry_point_payment": { + "$ref": "#/definitions/EntryPointPayment" + } + } + }, + "EntryPointPayment": { + "description": "An enum specifying who pays for the invocation and execution of the entrypoint.", + "oneOf": [ + { + "description": "The caller must cover cost", + "type": "string", + "enum": [ + "Caller" + ] + }, + { + "description": "Will cover cost to execute self but not cost of any subsequent invoked contracts", + "type": "string", + "enum": [ + "SelfOnly" + ] + }, + { + "description": "will cover cost to execute self and the cost of any subsequent invoked contracts", + "type": "string", + "enum": [ + "SelfOnward" + ] + } + ] + }, + "EntryPointV2": { + "description": "The entry point for the V2 Casper VM.", + "type": "object", + "required": [ + "flags", + "function_index" + ], + "properties": { + "function_index": { + "description": "The selector.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "flags": { + "description": "The flags.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + } + }, "TransformError": { "description": "Error type for applying and combining transforms.\n\nA `TypeMismatch` occurs when a transform cannot be applied because the types are not compatible (e.g. trying to add a number to a string).", "oneOf": [ diff --git a/smart_contracts/contracts/explorer/faucet-stored/src/main.rs b/smart_contracts/contracts/explorer/faucet-stored/src/main.rs index ba33a0c867..5c2971bcef 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, Key, Parameter, PublicKey, URef, U512, + addressable_entity::NamedKeys, ApiError, CLType, EntryPoint, EntryPointAccess, + EntryPointPayment, EntryPointType, EntryPoints, Key, Parameter, PublicKey, URef, U512, }; #[repr(u16)] @@ -115,6 +115,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let set_variables = EntryPoint::new( @@ -136,6 +137,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let authorize_to = EntryPoint::new( @@ -147,6 +149,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(faucet); diff --git a/smart_contracts/contracts/profiling/host-function-metrics/src/lib.rs b/smart_contracts/contracts/profiling/host-function-metrics/src/lib.rs index edafa474b0..81c28ca07f 100644 --- a/smart_contracts/contracts/profiling/host-function-metrics/src/lib.rs +++ b/smart_contracts/contracts/profiling/host-function-metrics/src/lib.rs @@ -16,7 +16,8 @@ use casper_types::{ addressable_entity::{ActionType, NamedKeys, Weight}, bytesrepr::Bytes, runtime_args, AddressableEntityHash, ApiError, BlockTime, CLType, CLValue, EntityVersion, - EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, Phase, U512, + EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints, Key, Parameter, + Phase, U512, }; const MIN_FUNCTION_NAME_LENGTH: usize = 1; @@ -229,6 +230,7 @@ fn store_function( CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -238,428 +240,1068 @@ fn store_function( storage::new_contract(entry_points, named_keys, None, None, None) } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn s() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn sss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn sssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn sssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn sssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn sssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn sssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn sssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn sssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn sssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn sssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn sssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn sssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn sssssssssssssssssssssssssss() { small_function() -} -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn s() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssss() { + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssss() { + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssss() { + small_function() +} + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn sssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssss() { + small_function() +} + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn sssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssss() { small_function() } + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn sssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssss() { + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] + +#[rustfmt::skip] +#[no_mangle] pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssss() { small_function() } + #[rustfmt:: -skip] #[no_mangle] pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssss() { + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssss() { + small_function() +} + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssss() { + small_function() +} + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssss() { + small_function() +} + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssss() { + small_function() +} + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssss() { + small_function() +} + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { + small_function() +} + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } + #[rustfmt:: -skip] #[no_mangle] pub extern "C" fn +skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } + #[rustfmt:: -skip] #[no_mangle] pub extern "C" fn +skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } + #[rustfmt:: -skip] #[no_mangle] pub extern "C" fn +skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } + #[rustfmt:: -skip] #[no_mangle] pub extern "C" fn +skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } + #[rustfmt:: -skip] #[no_mangle] pub extern "C" fn +skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn -sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn +sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { + small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn -ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn +ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { + small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { -small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + small_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss() { small_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn l() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn ll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn lll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn llll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn lllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn llllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn lllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn llllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn lllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn llllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn lllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn llllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn lllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn llllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn lllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn llllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn lllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn llllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn lllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn llllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn lllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn llllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn lllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn llllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn lllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn llllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn lllllllllllllllllllllllllll() { large_function() -} -#[rustfmt::skip] #[no_mangle] pub extern "C" fn llllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn l() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn ll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllll() { + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllll() { + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllll() { + large_function() +} + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn lllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn llllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllll() { large_function() } + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn lllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn llllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllll() { + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllll() { + large_function() +} + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn lllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn llllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] + +#[rustfmt::skip] +#[no_mangle] pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllll() { large_function() } + #[rustfmt:: -skip] #[no_mangle] pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllll() { + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllll() { + large_function() +} + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllll() { + large_function() +} + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllll() { + large_function() +} + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllll() { + large_function() +} + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllll() { + large_function() +} + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { + large_function() +} + #[rustfmt::skip] -#[no_mangle] pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } + #[rustfmt:: -skip] #[no_mangle] pub extern "C" fn +skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } + #[rustfmt:: -skip] #[no_mangle] pub extern "C" fn +skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } + #[rustfmt:: -skip] #[no_mangle] pub extern "C" fn +skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } + #[rustfmt:: -skip] #[no_mangle] pub extern "C" fn +skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } + #[rustfmt:: -skip] #[no_mangle] pub extern "C" fn +skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn -lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn +lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { + large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn -llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn +llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { + large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { -large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + large_function() +} + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } -#[rustfmt::skip] #[no_mangle] pub extern "C" fn + +#[rustfmt::skip] +#[no_mangle] +pub extern "C" fn llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll() { large_function() } 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 070cfa079f..6be0fb7a61 100644 --- a/smart_contracts/contracts/test/add-gas-subcall/src/main.rs +++ b/smart_contracts/contracts/test/add-gas-subcall/src/main.rs @@ -10,7 +10,7 @@ use casper_contract::contract_api::{runtime, storage}; use casper_types::{ runtime_args, AddressableEntityHash, ApiError, CLType, EntityVersion, EntryPoint, - EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, + EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints, Key, Parameter, }; const SUBCALL_NAME: &str = "add_gas"; @@ -56,6 +56,7 @@ fn store() -> (AddressableEntityHash, EntityVersion) { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/contract-context/src/main.rs b/smart_contracts/contracts/test/contract-context/src/main.rs index 4aeb4bc26a..4db7e9178d 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}, - runtime_args, AddressableEntityHash, CLType, EntityVersion, Key, PackageHash, - ENTITY_INITIAL_VERSION, + runtime_args, AddressableEntityHash, CLType, EntityVersion, EntryPointPayment, Key, + PackageHash, ENTITY_INITIAL_VERSION, }; const PACKAGE_HASH_KEY: &str = "package_hash_key"; @@ -98,6 +98,7 @@ fn create_entrypoints_1() -> EntryPoints { CLType::I32, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(contract_code_test); @@ -107,6 +108,7 @@ fn create_entrypoints_1() -> EntryPoints { CLType::I32, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(session_code_caller_as_contract); diff --git a/smart_contracts/contracts/test/contract-funds/src/main.rs b/smart_contracts/contracts/test/contract-funds/src/main.rs index 70c28afe37..9126cb40ee 100644 --- a/smart_contracts/contracts/test/contract-funds/src/main.rs +++ b/smart_contracts/contracts/test/contract-funds/src/main.rs @@ -13,7 +13,7 @@ use casper_contract::{ use casper_types::{ account::AccountHash, addressable_entity::{EntryPoint, EntryPointAccess, EntryPointType, NamedKeys, Parameter}, - CLTyped, CLValue, EntryPoints, Key, URef, + CLTyped, CLValue, EntryPointPayment, EntryPoints, Key, URef, }; const GET_PAYMENT_PURSE_NAME: &str = "get_payment_purse"; @@ -46,6 +46,7 @@ pub extern "C" fn call() { URef::cl_type(), EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(faucet_entrypoint); diff --git a/smart_contracts/contracts/test/contract-messages-emitter/src/main.rs b/smart_contracts/contracts/test/contract-messages-emitter/src/main.rs index 9d010d1a79..594a80c832 100644 --- a/smart_contracts/contracts/test/contract-messages-emitter/src/main.rs +++ b/smart_contracts/contracts/test/contract-messages-emitter/src/main.rs @@ -3,6 +3,7 @@ #[macro_use] extern crate alloc; + use alloc::{ collections::BTreeMap, string::{String, ToString}, @@ -18,7 +19,7 @@ use casper_types::{ addressable_entity::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys}, api_error::ApiError, contract_messages::MessageTopicOperation, - CLType, CLTyped, Parameter, RuntimeArgs, + CLType, CLTyped, EntryPointPayment, Parameter, RuntimeArgs, }; const ENTRY_POINT_INIT: &str = "init"; @@ -92,6 +93,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); emitter_entry_points.add_entry_point(EntryPoint::new( ENTRY_POINT_EMIT_MESSAGE, @@ -99,6 +101,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); emitter_entry_points.add_entry_point(EntryPoint::new( ENTRY_POINT_ADD_TOPIC, @@ -106,6 +109,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); emitter_entry_points.add_entry_point(EntryPoint::new( ENTRY_POINT_EMIT_MULTIPLE_MESSAGES, @@ -113,6 +117,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); if register_topic_with_init { diff --git a/smart_contracts/contracts/test/contract-messages-upgrader/src/main.rs b/smart_contracts/contracts/test/contract-messages-upgrader/src/main.rs index 4b884466fb..e8379a26d4 100644 --- a/smart_contracts/contracts/test/contract-messages-upgrader/src/main.rs +++ b/smart_contracts/contracts/test/contract-messages-upgrader/src/main.rs @@ -3,6 +3,7 @@ #[macro_use] extern crate alloc; + use alloc::{ collections::BTreeMap, string::{String, ToString}, @@ -18,7 +19,7 @@ use casper_types::{ addressable_entity::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys}, api_error::ApiError, contract_messages::MessageTopicOperation, - runtime_args, CLType, CLTyped, PackageHash, Parameter, RuntimeArgs, + runtime_args, CLType, CLTyped, EntryPointPayment, PackageHash, Parameter, RuntimeArgs, }; const ENTRY_POINT_INIT: &str = "init"; @@ -106,6 +107,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); emitter_entry_points.add_entry_point(EntryPoint::new( ENTRY_POINT_EMIT_MESSAGE, @@ -113,6 +115,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); emitter_entry_points.add_entry_point(EntryPoint::new( ENTRY_POINT_EMIT_MESSAGE_FROM_EACH_VERSION, @@ -120,6 +123,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); let message_emitter_package_hash: PackageHash = runtime::get_key(PACKAGE_HASH_KEY_NAME) diff --git a/smart_contracts/contracts/test/counter-factory/src/main.rs b/smart_contracts/contracts/test/counter-factory/src/main.rs index fab271c793..df93793622 100644 --- a/smart_contracts/contracts/test/counter-factory/src/main.rs +++ b/smart_contracts/contracts/test/counter-factory/src/main.rs @@ -12,7 +12,8 @@ use casper_contract::{ use casper_types::{ addressable_entity::{EntryPoint, EntryPoints, NamedKeys, Parameters}, bytesrepr::FromBytes, - ApiError, CLType, CLTyped, EntryPointAccess, EntryPointType, Key, URef, U512, + ApiError, CLType, CLTyped, EntryPointAccess, EntryPointPayment, EntryPointType, Key, URef, + U512, }; const ACCESS_KEY_NAME: &str = "factory_access"; @@ -86,6 +87,7 @@ fn installer(name: String, initial_value: U512) { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); let entry_point: EntryPoint = EntryPoint::new( @@ -94,6 +96,7 @@ fn installer(name: String, initial_value: U512) { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -123,6 +126,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Factory, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); let entry_point: EntryPoint = EntryPoint::new( @@ -131,6 +135,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Factory, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); let entry_point: EntryPoint = EntryPoint::new( @@ -139,6 +144,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Template, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); let entry_point: EntryPoint = EntryPoint::new( @@ -147,6 +153,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Template, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/deserialize-error/src/main.rs b/smart_contracts/contracts/test/deserialize-error/src/main.rs index 5836be1174..158a338a50 100644 --- a/smart_contracts/contracts/test/deserialize-error/src/main.rs +++ b/smart_contracts/contracts/test/deserialize-error/src/main.rs @@ -8,7 +8,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, AddressableEntityHash, CLType, - EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, RuntimeArgs, + EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints, RuntimeArgs, }; #[no_mangle] @@ -82,6 +82,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/dictionary/src/lib.rs b/smart_contracts/contracts/test/dictionary/src/lib.rs index 79e0cfa84d..97945d20c7 100644 --- a/smart_contracts/contracts/test/dictionary/src/lib.rs +++ b/smart_contracts/contracts/test/dictionary/src/lib.rs @@ -16,8 +16,8 @@ use casper_types::{ addressable_entity::{EntityKindTag, NamedKeys}, api_error, bytesrepr::ToBytes, - AccessRights, ApiError, CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Key, URef, + AccessRights, ApiError, CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointPayment, + EntryPointType, EntryPoints, Key, URef, }; pub const DICTIONARY_NAME: &str = "local"; @@ -184,6 +184,7 @@ pub fn delegate() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); entry_points.add_entry_point(EntryPoint::new( SHARE_RO_ENTRYPOINT, @@ -191,6 +192,7 @@ pub fn delegate() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); entry_points.add_entry_point(EntryPoint::new( SHARE_W_ENTRYPOINT, @@ -198,6 +200,7 @@ pub fn delegate() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); entry_points.add_entry_point(EntryPoint::new( INVALID_PUT_DICTIONARY_ITEM_KEY_ENTRYPOINT, @@ -205,6 +208,7 @@ pub fn delegate() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); entry_points.add_entry_point(EntryPoint::new( INVALID_GET_DICTIONARY_ITEM_KEY_ENTRYPOINT, @@ -212,6 +216,7 @@ pub fn delegate() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); let named_keys = { let uref = { diff --git a/smart_contracts/contracts/test/do-nothing-stored-upgrader/src/main.rs b/smart_contracts/contracts/test/do-nothing-stored-upgrader/src/main.rs index e5d18a1a34..694505660d 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 @@ -16,7 +16,7 @@ use core::convert::TryInto; use casper_types::{ addressable_entity::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys}, - CLType, CLTyped, Key, PackageHash, Parameter, URef, + CLType, CLTyped, EntryPointPayment, Key, PackageHash, Parameter, URef, }; const ENTRY_FUNCTION_NAME: &str = "delegate"; @@ -43,6 +43,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(delegate); diff --git a/smart_contracts/contracts/test/do-nothing-stored/src/main.rs b/smart_contracts/contracts/test/do-nothing-stored/src/main.rs index 401982ae38..58c94bdb53 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, Key, + CLType, EntryPointAccess, EntryPointPayment, EntryPointType, Key, }; const ENTRY_FUNCTION_NAME: &str = "delegate"; @@ -28,6 +28,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); entry_points diff --git a/smart_contracts/contracts/test/ee-1071-regression/src/main.rs b/smart_contracts/contracts/test/ee-1071-regression/src/main.rs index 90ff40021a..99b45f202f 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, Key, + addressable_entity::Parameters, CLType, EntryPoint, EntryPointAccess, EntryPointPayment, + EntryPointType, EntryPoints, Key, }; const CONTRACT_HASH_NAME: &str = "contract"; @@ -27,6 +27,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/ee-1129-regression/src/main.rs b/smart_contracts/contracts/test/ee-1129-regression/src/main.rs index a8340814a1..ed323426da 100644 --- a/smart_contracts/contracts/test/ee-1129-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-1129-regression/src/main.rs @@ -7,8 +7,8 @@ use alloc::string::ToString; use casper_contract::contract_api::{runtime, storage, system}; use casper_types::{ - addressable_entity::Parameters, CLType, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Key, + addressable_entity::Parameters, CLType, EntryPoint, EntryPointAccess, EntryPointPayment, + EntryPointType, EntryPoints, Key, }; const ENTRY_POINT_NAME: &str = "create_purse"; @@ -34,6 +34,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/ee-1217-regression/src/main.rs b/smart_contracts/contracts/test/ee-1217-regression/src/main.rs index c23cb4a107..6feec17cc9 100644 --- a/smart_contracts/contracts/test/ee-1217-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-1217-regression/src/main.rs @@ -8,8 +8,8 @@ use alloc::{string::ToString, vec}; // casper_contract is required for it's [global_alloc] as well as handlers (such as panic_handler) use casper_contract::contract_api::{runtime, storage, system}; use casper_types::{ - runtime_args, system::auction, CLType, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, PublicKey, U512, + runtime_args, system::auction, CLType, EntryPoint, EntryPointAccess, EntryPointPayment, + EntryPointType, EntryPoints, PublicKey, U512, }; const PACKAGE_NAME: &str = "call_auction"; @@ -142,6 +142,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let add_bid_contract_entry_point = EntryPoint::new( METHOD_ADD_BID_CONTRACT_NAME.to_string(), @@ -149,6 +150,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let withdraw_bid_session_entry_point = EntryPoint::new( METHOD_WITHDRAW_BID_SESSION_NAME.to_string(), @@ -156,6 +158,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let withdraw_bid_contract_entry_point = EntryPoint::new( METHOD_WITHDRAW_BID_CONTRACT_NAME.to_string(), @@ -163,6 +166,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let delegate_session_entry_point = EntryPoint::new( METHOD_DELEGATE_SESSION_NAME.to_string(), @@ -170,6 +174,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let delegate_contract_entry_point = EntryPoint::new( METHOD_DELEGATE_CONTRACT_NAME.to_string(), @@ -177,6 +182,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let undelegate_session_entry_point = EntryPoint::new( METHOD_UNDELEGATE_SESSION_NAME.to_string(), @@ -184,6 +190,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let undelegate_contract_entry_point = EntryPoint::new( METHOD_UNDELEGATE_CONTRACT_NAME.to_string(), @@ -191,6 +198,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let activate_bid_session_entry_point = EntryPoint::new( METHOD_ACTIVATE_BID_SESSION_NAME.to_string(), @@ -198,6 +206,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let activate_bid_contract_entry_point = EntryPoint::new( METHOD_ACTIVATE_BID_CONTRACT_NAME.to_string(), @@ -205,6 +214,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(add_bid_session_entry_point); entry_points.add_entry_point(add_bid_contract_entry_point); diff --git a/smart_contracts/contracts/test/ee-401-regression/src/main.rs b/smart_contracts/contracts/test/ee-401-regression/src/main.rs index b1b6bcff70..714383f9fd 100644 --- a/smart_contracts/contracts/test/ee-401-regression/src/main.rs +++ b/smart_contracts/contracts/test/ee-401-regression/src/main.rs @@ -10,8 +10,8 @@ use casper_contract::{ unwrap_or_revert::UnwrapOrRevert, }; use casper_types::{ - addressable_entity::Parameters, CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Key, URef, + addressable_entity::Parameters, CLType, CLValue, EntryPoint, EntryPointAccess, + EntryPointPayment, EntryPointType, EntryPoints, Key, URef, }; const HELLO_EXT: &str = "hello_ext"; @@ -36,6 +36,7 @@ pub extern "C" fn call() { CLType::URef, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/ee-441-rng-state/src/main.rs b/smart_contracts/contracts/test/ee-441-rng-state/src/main.rs index e328ce8505..0a5bdf0c6a 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 @@ -10,8 +10,8 @@ use casper_contract::{ unwrap_or_revert::UnwrapOrRevert, }; use casper_types::{ - addressable_entity::Parameters, CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Key, RuntimeArgs, URef, U512, + addressable_entity::Parameters, CLType, CLValue, EntryPoint, EntryPointAccess, + EntryPointPayment, EntryPointType, EntryPoints, Key, RuntimeArgs, URef, U512, }; const ARG_FLAG: &str = "flag"; @@ -45,6 +45,7 @@ pub extern "C" fn call() { CLType::String, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(do_nothing_entry_point); @@ -55,6 +56,7 @@ pub extern "C" fn call() { CLType::URef, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); 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 92ee1dbc00..c50dd77d5c 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, Key, URef, + EntryPointPayment, EntryPointType, EntryPoints, Key, URef, }; const DATA: &str = "data"; @@ -35,6 +35,7 @@ pub extern "C" fn call() { CLType::URef, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/ee-599-regression/src/main.rs b/smart_contracts/contracts/test/ee-599-regression/src/main.rs index 31e4a54773..ed409bf6e6 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}, - AddressableEntityHash, ApiError, CLType, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Key, RuntimeArgs, URef, U512, + AddressableEntityHash, ApiError, CLType, EntryPoint, EntryPointAccess, EntryPointPayment, + EntryPointType, EntryPoints, Key, RuntimeArgs, URef, U512, }; const DONATION_AMOUNT: u64 = 1; @@ -133,6 +133,7 @@ fn delegate() -> Result<(), ApiError> { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point_1); @@ -143,6 +144,7 @@ fn delegate() -> Result<(), ApiError> { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point_2); @@ -153,6 +155,7 @@ fn delegate() -> Result<(), ApiError> { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point_3); @@ -163,6 +166,7 @@ fn delegate() -> Result<(), ApiError> { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point_4); diff --git a/smart_contracts/contracts/test/ee-771-regression/src/main.rs b/smart_contracts/contracts/test/ee-771-regression/src/main.rs index 21328e8658..b5eb78cabd 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}, - AddressableEntityHash, CLType, EntityVersion, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Key, RuntimeArgs, + AddressableEntityHash, CLType, EntityVersion, EntryPoint, EntryPointAccess, EntryPointPayment, + EntryPointType, EntryPoints, Key, RuntimeArgs, }; const ENTRY_POINT_NAME: &str = "contract_ext"; @@ -40,6 +40,7 @@ pub extern "C" fn contract_ext() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -62,6 +63,7 @@ fn store(named_keys: NamedKeys) -> (AddressableEntityHash, EntityVersion) { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/expensive-calculation/src/main.rs b/smart_contracts/contracts/test/expensive-calculation/src/main.rs index 3f8607975c..f32ecc2251 100644 --- a/smart_contracts/contracts/test/expensive-calculation/src/main.rs +++ b/smart_contracts/contracts/test/expensive-calculation/src/main.rs @@ -5,8 +5,8 @@ extern crate alloc; use casper_contract::contract_api::{runtime, storage}; use casper_types::{ - addressable_entity::Parameters, CLType, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Key, + addressable_entity::Parameters, CLType, EntryPoint, EntryPointAccess, EntryPointPayment, + EntryPointType, EntryPoints, Key, }; const ENTRY_FUNCTION_NAME: &str = "calculate"; @@ -35,6 +35,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); entry_points diff --git a/smart_contracts/contracts/test/get-call-stack-recursive-subcall/src/main.rs b/smart_contracts/contracts/test/get-call-stack-recursive-subcall/src/main.rs index a7ec5dd402..5e7dba6a31 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 @@ -7,7 +7,8 @@ use alloc::{boxed::Box, string::ToString, vec}; use casper_contract::contract_api::{runtime, storage}; use casper_types::{ - CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, + CLType, EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints, Key, + Parameter, }; use get_call_stack_recursive_subcall::{ @@ -38,6 +39,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let forwarder_session_entry_point = EntryPoint::new( METHOD_FORWARDER_SESSION_NAME.to_string(), @@ -48,6 +50,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Caller, + EntryPointPayment::Caller, ); entry_points.add_entry_point(forwarder_contract_entry_point); entry_points.add_entry_point(forwarder_session_entry_point); diff --git a/smart_contracts/contracts/test/get-caller-subcall/src/main.rs b/smart_contracts/contracts/test/get-caller-subcall/src/main.rs index e559585af0..c38d644cd8 100644 --- a/smart_contracts/contracts/test/get-caller-subcall/src/main.rs +++ b/smart_contracts/contracts/test/get-caller-subcall/src/main.rs @@ -10,8 +10,8 @@ use casper_contract::{ unwrap_or_revert::UnwrapOrRevert, }; use casper_types::{ - account::AccountHash, CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, RuntimeArgs, + account::AccountHash, CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointPayment, + EntryPointType, EntryPoints, RuntimeArgs, }; const ENTRY_POINT_NAME: &str = "get_caller_ext"; @@ -43,6 +43,7 @@ pub extern "C" fn call() { CLType::ByteArray(32), EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); entry_points diff --git a/smart_contracts/contracts/test/gh-1470-regression/src/bin/main.rs b/smart_contracts/contracts/test/gh-1470-regression/src/bin/main.rs index 80a8ce2570..c666129108 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 @@ -8,8 +8,8 @@ use alloc::collections::BTreeMap; use casper_contract::contract_api::{runtime, storage}; use casper_types::{ - addressable_entity::NamedKeys, CLType, CLTyped, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Group, Key, Parameter, + addressable_entity::NamedKeys, CLType, CLTyped, EntryPoint, EntryPointAccess, + EntryPointPayment, EntryPointType, EntryPoints, Group, Key, Parameter, }; use gh_1470_regression::{ Arg1Type, Arg2Type, Arg3Type, Arg4Type, Arg5Type, ARG1, ARG2, ARG3, ARG4, ARG5, @@ -62,6 +62,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Groups(vec![Group::new(GROUP_LABEL)]), EntryPointType::Called, + EntryPointPayment::Caller, )); entry_points.add_entry_point(EntryPoint::new( @@ -74,6 +75,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Groups(vec![Group::new(GROUP_LABEL)]), EntryPointType::Called, + EntryPointPayment::Caller, )); let named_keys = NamedKeys::new(); diff --git a/smart_contracts/contracts/test/gh-1688-regression/src/main.rs b/smart_contracts/contracts/test/gh-1688-regression/src/main.rs index f9b7ca0faa..ade4759cb0 100644 --- a/smart_contracts/contracts/test/gh-1688-regression/src/main.rs +++ b/smart_contracts/contracts/test/gh-1688-regression/src/main.rs @@ -6,8 +6,8 @@ extern crate alloc; use alloc::string::ToString; use casper_contract::contract_api::{runtime, storage}; use casper_types::{ - addressable_entity::Parameters, CLType, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Key, + addressable_entity::Parameters, CLType, EntryPoint, EntryPointAccess, EntryPointPayment, + EntryPointType, EntryPoints, Key, }; const METHOD_PUT_KEY: &str = "put_key"; @@ -31,6 +31,7 @@ fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); let (contract_hash, _version) = storage::new_contract( diff --git a/smart_contracts/contracts/test/gh-2280-regression/src/main.rs b/smart_contracts/contracts/test/gh-2280-regression/src/main.rs index ca01cafd3a..740b5f30e8 100644 --- a/smart_contracts/contracts/test/gh-2280-regression/src/main.rs +++ b/smart_contracts/contracts/test/gh-2280-regression/src/main.rs @@ -15,7 +15,7 @@ use casper_types::{ addressable_entity::{ EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys, Parameter, }, - CLType, CLTyped, Key, U512, + CLType, CLTyped, EntryPointPayment, Key, U512, }; const FAUCET_NAME: &str = "faucet"; @@ -49,6 +49,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(faucet_entrypoint); diff --git a/smart_contracts/contracts/test/gh-3097-regression/src/main.rs b/smart_contracts/contracts/test/gh-3097-regression/src/main.rs index a8cf62cdc5..df3f70c704 100644 --- a/smart_contracts/contracts/test/gh-3097-regression/src/main.rs +++ b/smart_contracts/contracts/test/gh-3097-regression/src/main.rs @@ -11,7 +11,7 @@ use casper_contract::{ }; use casper_types::{ addressable_entity::{NamedKeys, Parameters}, - CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, + CLType, EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints, Key, }; const CONTRACT_PACKAGE_HASH_KEY: &str = "contract_package_hash"; @@ -34,6 +34,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(do_something); diff --git a/smart_contracts/contracts/test/groups/src/main.rs b/smart_contracts/contracts/test/groups/src/main.rs index d4eb57c69b..724bad2ba4 100644 --- a/smart_contracts/contracts/test/groups/src/main.rs +++ b/smart_contracts/contracts/test/groups/src/main.rs @@ -18,7 +18,8 @@ use casper_types::{ addressable_entity::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys}, runtime_args, system::{handle_payment, standard_payment}, - CLType, CLTyped, Key, PackageHash, Parameter, RuntimeArgs, URef, ENTITY_INITIAL_VERSION, U512, + CLType, CLTyped, EntryPointPayment, Key, PackageHash, Parameter, RuntimeArgs, URef, + ENTITY_INITIAL_VERSION, U512, }; const PACKAGE_HASH_KEY: &str = "package_hash_key"; @@ -132,6 +133,7 @@ fn create_entry_points_1() -> EntryPoints { CLType::I32, EntryPointAccess::groups(&["Group 1"]), EntryPointType::Caller, + EntryPointPayment::Caller, ); entry_points.add_entry_point(restricted_session); @@ -141,6 +143,7 @@ fn create_entry_points_1() -> EntryPoints { CLType::I32, EntryPointAccess::groups(&["Group 1"]), EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(restricted_contract); @@ -150,6 +153,7 @@ fn create_entry_points_1() -> EntryPoints { CLType::I32, EntryPointAccess::Public, EntryPointType::Caller, + EntryPointPayment::Caller, ); entry_points.add_entry_point(restricted_session_caller); @@ -159,6 +163,7 @@ fn create_entry_points_1() -> EntryPoints { CLType::I32, EntryPointAccess::groups(&["Group 1"]), EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(restricted_contract); @@ -172,6 +177,7 @@ fn create_entry_points_1() -> EntryPoints { // NOTE: Public contract authorizes any contract call, because this contract has groups // uref in its named keys EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(unrestricted_contract_caller); @@ -185,6 +191,7 @@ fn create_entry_points_1() -> EntryPoints { // NOTE: Public contract authorizes any contract call, because this contract has groups // uref in its named keys EntryPointType::Caller, + EntryPointPayment::Caller, ); entry_points.add_entry_point(unrestricted_contract_caller_as_session); @@ -198,6 +205,7 @@ fn create_entry_points_1() -> EntryPoints { // NOTE: Public contract authorizes any contract call, because this contract has groups // uref in its named keys EntryPointType::Caller, + EntryPointPayment::Caller, ); entry_points.add_entry_point(uncallable_session); @@ -211,6 +219,7 @@ fn create_entry_points_1() -> EntryPoints { // NOTE: Public contract authorizes any contract call, because this contract has groups // uref in its named keys EntryPointType::Caller, + EntryPointPayment::Caller, ); entry_points.add_entry_point(uncallable_contract); @@ -226,6 +235,7 @@ fn create_entry_points_1() -> EntryPoints { // NOTE: Public contract authorizes any contract call, because this contract has groups // uref in its named keys EntryPointType::Caller, + EntryPointPayment::Caller, ); entry_points.add_entry_point(call_restricted_entry_points); @@ -238,6 +248,7 @@ fn create_entry_points_1() -> EntryPoints { CLType::Unit, EntryPointAccess::groups(&["Group 1"]), EntryPointType::Caller, + EntryPointPayment::Caller, ); entry_points.add_entry_point(restricted_standard_payment); diff --git a/smart_contracts/contracts/test/host-function-costs/src/main.rs b/smart_contracts/contracts/test/host-function-costs/src/main.rs index e1930a2c7c..3f1c397c63 100644 --- a/smart_contracts/contracts/test/host-function-costs/src/main.rs +++ b/smart_contracts/contracts/test/host-function-costs/src/main.rs @@ -17,7 +17,7 @@ use casper_types::{ addressable_entity::{ActionType, NamedKeys, Weight}, bytesrepr::Bytes, runtime_args, ApiError, BlockTime, CLType, CLTyped, CLValue, EntryPoint, EntryPointAccess, - EntryPointType, EntryPoints, Key, Parameter, Phase, RuntimeArgs, U512, + EntryPointPayment, EntryPointType, EntryPoints, Key, Parameter, Phase, RuntimeArgs, U512, }; const DO_NOTHING_NAME: &str = "do_nothing"; @@ -282,6 +282,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -291,6 +292,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -300,6 +302,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); let entry_point = EntryPoint::new( @@ -308,6 +311,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -317,6 +321,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); let entry_point = EntryPoint::new( @@ -325,6 +330,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -334,6 +340,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); let entry_point = EntryPoint::new( @@ -342,6 +349,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -351,6 +359,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -360,6 +369,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -369,6 +379,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -378,6 +389,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -387,6 +399,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/manage-groups/src/main.rs b/smart_contracts/contracts/test/manage-groups/src/main.rs index 50f93921a8..4cdb776cff 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, Group, Key, Package, PackageHash, Parameter, URef, + ApiError, CLType, EntryPointPayment, Group, Key, Package, PackageHash, Parameter, URef, }; const PACKAGE_HASH_KEY: &str = "package_hash_key"; @@ -179,6 +179,7 @@ fn create_entry_points_1() -> EntryPoints { CLType::Unit, EntryPointAccess::Public, EntryPointType::Caller, + EntryPointPayment::Caller, ); entry_points.add_entry_point(restricted_session); @@ -188,6 +189,7 @@ fn create_entry_points_1() -> EntryPoints { CLType::Unit, EntryPointAccess::Public, EntryPointType::Caller, + EntryPointPayment::Caller, ); entry_points.add_entry_point(remove_group); @@ -201,6 +203,7 @@ fn create_entry_points_1() -> EntryPoints { CLType::Unit, EntryPointAccess::Public, EntryPointType::Caller, + EntryPointPayment::Caller, ); entry_points.add_entry_point(extend_group_urefs); @@ -214,6 +217,7 @@ fn create_entry_points_1() -> EntryPoints { CLType::Unit, EntryPointAccess::Public, EntryPointType::Caller, + EntryPointPayment::Caller, ); entry_points.add_entry_point(remove_group_urefs); entry_points diff --git a/smart_contracts/contracts/test/measure-gas-subcall/src/main.rs b/smart_contracts/contracts/test/measure-gas-subcall/src/main.rs index e44dbb2617..0b009e43a6 100644 --- a/smart_contracts/contracts/test/measure-gas-subcall/src/main.rs +++ b/smart_contracts/contracts/test/measure-gas-subcall/src/main.rs @@ -11,7 +11,8 @@ use casper_contract::{ }; use casper_types::{ addressable_entity::Parameters, AddressableEntityHash, ApiError, CLType, CLValue, - EntityVersion, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Phase, RuntimeArgs, + EntityVersion, EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints, + Phase, RuntimeArgs, }; const ARG_TARGET: &str = "target_contract"; @@ -45,6 +46,7 @@ fn store() -> (AddressableEntityHash, EntityVersion) { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point_1); @@ -55,6 +57,7 @@ fn store() -> (AddressableEntityHash, EntityVersion) { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); 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 a085778d50..ec066418dd 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, Key, + EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints, Key, }; const ROLE_A_KEYS: [AccountHash; 3] = [ @@ -78,6 +78,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let entrypoint_b = EntryPoint::new( @@ -86,6 +87,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entrypoint_a); diff --git a/smart_contracts/contracts/test/named-keys-stored/src/main.rs b/smart_contracts/contracts/test/named-keys-stored/src/main.rs index d54e7d8313..073eebd458 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,8 @@ use casper_contract::{ }; use casper_types::{ addressable_entity::{NamedKeys, Parameters}, - ApiError, CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, PackageHash, - RuntimeArgs, + ApiError, CLType, EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints, + Key, PackageHash, RuntimeArgs, }; const ENTRY_POINT_CONTRACT: &str = "named_keys_contract"; @@ -143,6 +143,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(contract_entrypoint); let session_entrypoint = EntryPoint::new( @@ -151,6 +152,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(session_entrypoint); let contract_to_contract_entrypoint = EntryPoint::new( @@ -159,6 +161,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(contract_to_contract_entrypoint); let contract_to_contract_entrypoint = EntryPoint::new( @@ -167,6 +170,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(contract_to_contract_entrypoint); entry_points diff --git a/smart_contracts/contracts/test/ordered-transforms/src/main.rs b/smart_contracts/contracts/test/ordered-transforms/src/main.rs index 7b565b10c4..85f0ad4698 100644 --- a/smart_contracts/contracts/test/ordered-transforms/src/main.rs +++ b/smart_contracts/contracts/test/ordered-transforms/src/main.rs @@ -3,6 +3,7 @@ #[macro_use] extern crate alloc; + use alloc::{string::ToString, vec::Vec}; use casper_contract::{ @@ -10,8 +11,8 @@ use casper_contract::{ unwrap_or_revert::UnwrapOrRevert, }; use casper_types::{ - addressable_entity::NamedKeys, CLType, CLTyped, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Key, Parameter, URef, + addressable_entity::NamedKeys, CLType, CLTyped, EntryPoint, EntryPointAccess, + EntryPointPayment, EntryPointType, EntryPoints, Key, Parameter, URef, }; #[no_mangle] @@ -26,6 +27,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); let n: u32 = runtime::get_named_arg("n"); diff --git a/smart_contracts/contracts/test/purse-holder-stored-upgrader/src/main.rs b/smart_contracts/contracts/test/purse-holder-stored-upgrader/src/main.rs index 7febdcae82..c93d69d4e3 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, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Key, PackageHash, Parameter, URef, + addressable_entity::NamedKeys, CLType, CLValue, EntryPoint, EntryPointAccess, + EntryPointPayment, EntryPointType, EntryPoints, Key, PackageHash, Parameter, URef, }; pub const METHOD_ADD: &str = "add"; @@ -64,6 +64,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(add); let version = EntryPoint::new( @@ -72,6 +73,7 @@ pub extern "C" fn call() { CLType::String, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(version); @@ -81,6 +83,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(remove); entry_points diff --git a/smart_contracts/contracts/test/purse-holder-stored/src/main.rs b/smart_contracts/contracts/test/purse-holder-stored/src/main.rs index 6a2cf6f6e0..2d8e6a6615 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, Key, Parameter, + CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints, + Key, Parameter, }; pub const METHOD_ADD: &str = "add"; @@ -53,6 +54,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(add); let version = EntryPoint::new( @@ -61,6 +63,7 @@ pub extern "C" fn call() { CLType::String, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(version); entry_points diff --git a/smart_contracts/contracts/test/regression-20210707/src/main.rs b/smart_contracts/contracts/test/regression-20210707/src/main.rs index 820ebe1082..810a48c5d0 100644 --- a/smart_contracts/contracts/test/regression-20210707/src/main.rs +++ b/smart_contracts/contracts/test/regression-20210707/src/main.rs @@ -15,8 +15,8 @@ use casper_types::{ addressable_entity::NamedKeys, runtime_args, system::{handle_payment, mint}, - AccessRights, CLType, CLTyped, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, - Parameter, RuntimeArgs, URef, U512, + AccessRights, CLType, CLTyped, EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, + EntryPoints, Key, Parameter, RuntimeArgs, URef, U512, }; const HARDCODED_UREF: URef = URef::new([42; 32], AccessRights::READ_ADD_WRITE); @@ -150,6 +150,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let send_to_purse = EntryPoint::new( METHOD_SEND_TO_PURSE, @@ -161,6 +162,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let hardcoded_src = EntryPoint::new( METHOD_HARDCODED_PURSE_SRC, @@ -171,6 +173,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let stored_payment = EntryPoint::new( METHOD_STORED_PAYMENT, @@ -181,6 +184,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let hardcoded_payment = EntryPoint::new( METHOD_HARDCODED_PAYMENT, @@ -188,6 +192,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(send_to_account); diff --git a/smart_contracts/contracts/test/regression-20210831/src/main.rs b/smart_contracts/contracts/test/regression-20210831/src/main.rs index 80b6a4b945..f5f783e5d6 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, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, - PackageHash, Parameter, PublicKey, RuntimeArgs, U512, + CLType, CLTyped, CLValue, EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, + EntryPoints, Key, PackageHash, Parameter, PublicKey, RuntimeArgs, U512, }; const METHOD_ADD_BID_PROXY_CALL_1: &str = "add_bid_proxy_call_1"; @@ -183,6 +183,7 @@ pub extern "C" fn call() { U512::cl_type(), EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(add_bid_proxy_call_1); @@ -196,6 +197,7 @@ pub extern "C" fn call() { U512::cl_type(), EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(add_bid_proxy_call); @@ -208,6 +210,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let withdraw_proxy_call = EntryPoint::new( @@ -219,6 +222,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let delegate_proxy_call = EntryPoint::new( @@ -231,6 +235,7 @@ pub extern "C" fn call() { U512::cl_type(), EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let delegate_proxy_call_1 = EntryPoint::new( @@ -243,6 +248,7 @@ pub extern "C" fn call() { U512::cl_type(), EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let undelegate_proxy_call = EntryPoint::new( @@ -255,6 +261,7 @@ pub extern "C" fn call() { U512::cl_type(), EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let undelegate_proxy_call_1 = EntryPoint::new( @@ -267,6 +274,7 @@ pub extern "C" fn call() { U512::cl_type(), EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let activate_bid_proxy_call = EntryPoint::new( @@ -275,6 +283,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); let activate_bid_proxy_call_1 = EntryPoint::new( METHOD_ACTIVATE_BID_CALL_1, @@ -282,6 +291,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(withdraw_proxy_call); diff --git a/smart_contracts/contracts/test/regression-20220204/src/main.rs b/smart_contracts/contracts/test/regression-20220204/src/main.rs index e3e3fb547d..797bed8145 100644 --- a/smart_contracts/contracts/test/regression-20220204/src/main.rs +++ b/smart_contracts/contracts/test/regression-20220204/src/main.rs @@ -11,7 +11,7 @@ use casper_contract::{ }; use casper_types::{ account::AccountHash, addressable_entity::NamedKeys, CLType, CLTyped, EntryPoint, - EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, URef, U512, + EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints, Key, Parameter, URef, U512, }; const TRANSFER_AS_CONTRACT: &str = "transfer_as_contract"; @@ -20,6 +20,7 @@ const ARG_PURSE: &str = "purse"; const PURSE_KEY: &str = "purse"; const CONTRACT_HASH_NAME: &str = "regression-contract-hash"; const PACKAGE_HASH_NAME: &str = "package-contract-hash"; + type NonTrivialArg = BTreeMap<String, Key>; #[no_mangle] @@ -35,6 +36,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); type NonTrivialArg = BTreeMap<String, Key>; @@ -45,6 +47,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); let named_keys = { diff --git a/smart_contracts/contracts/test/regression-20220211/src/main.rs b/smart_contracts/contracts/test/regression-20220211/src/main.rs index 4aacb2c37f..0ad86744e7 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, Key, URef, + EntryPointPayment, EntryPointType, EntryPoints, Key, URef, }; const RET_AS_CONTRACT: &str = "ret_as_contract"; @@ -31,14 +31,15 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); - entry_points.add_entry_point(EntryPoint::new( RET_AS_SESSION, Parameters::new(), CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); entry_points.add_entry_point(EntryPoint::new( PUT_KEY_AS_SESSION, @@ -46,6 +47,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); entry_points.add_entry_point(EntryPoint::new( PUT_KEY_AS_CONTRACT, @@ -53,6 +55,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); entry_points.add_entry_point(EntryPoint::new( READ_AS_SESSION, @@ -60,6 +63,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); entry_points.add_entry_point(EntryPoint::new( READ_AS_CONTRACT, @@ -67,6 +71,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); entry_points.add_entry_point(EntryPoint::new( WRITE_AS_SESSION, @@ -74,6 +79,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); entry_points.add_entry_point(EntryPoint::new( WRITE_AS_CONTRACT, @@ -81,6 +87,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); entry_points.add_entry_point(EntryPoint::new( ADD_AS_SESSION, @@ -88,6 +95,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); entry_points.add_entry_point(EntryPoint::new( ADD_AS_CONTRACT, @@ -95,6 +103,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); let (contract_hash, _contract_version) = storage::new_locked_contract(entry_points, None, None, None, None); diff --git a/smart_contracts/contracts/test/regression_20211110/src/main.rs b/smart_contracts/contracts/test/regression_20211110/src/main.rs index 5f1d793f4a..6d6d8e59d1 100644 --- a/smart_contracts/contracts/test/regression_20211110/src/main.rs +++ b/smart_contracts/contracts/test/regression_20211110/src/main.rs @@ -7,7 +7,7 @@ extern crate alloc; use casper_contract::contract_api::{runtime, storage}; use casper_types::{ runtime_args, AddressableEntityHash, CLType, CLTyped, EntryPoint, EntryPointAccess, - EntryPointType, EntryPoints, Key, Parameter, + EntryPointPayment, EntryPointType, EntryPoints, Key, Parameter, }; const RECURSE_ENTRYPOINT: &str = "recurse"; @@ -23,6 +23,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); let (contract_hash, _contract_version) = diff --git a/smart_contracts/contracts/test/ret-uref/src/main.rs b/smart_contracts/contracts/test/ret-uref/src/main.rs index 09b9e8d8e3..914c380eb2 100644 --- a/smart_contracts/contracts/test/ret-uref/src/main.rs +++ b/smart_contracts/contracts/test/ret-uref/src/main.rs @@ -12,8 +12,8 @@ use casper_contract::{ unwrap_or_revert::UnwrapOrRevert, }; use casper_types::{ - runtime_args, CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, - Parameter, URef, + runtime_args, CLType, CLValue, EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, + EntryPoints, Key, Parameter, URef, }; const ACCESS_UREF: &str = "access_uref"; @@ -55,6 +55,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(put_uref_entrypoint); let get_uref_entrypoint = EntryPoint::new( @@ -63,6 +64,7 @@ pub extern "C" fn call() { CLType::URef, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(get_uref_entrypoint); let insert_uref_entrypoint = EntryPoint::new( @@ -71,6 +73,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Caller, + EntryPointPayment::Caller, ); entry_points.add_entry_point(insert_uref_entrypoint); entry_points diff --git a/smart_contracts/contracts/test/storage-costs/src/main.rs b/smart_contracts/contracts/test/storage-costs/src/main.rs index e665c6f874..7622190180 100644 --- a/smart_contracts/contracts/test/storage-costs/src/main.rs +++ b/smart_contracts/contracts/test/storage-costs/src/main.rs @@ -10,8 +10,8 @@ use casper_contract::{ unwrap_or_revert::UnwrapOrRevert, }; use casper_types::{ - addressable_entity::NamedKeys, CLType, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Key, U512, + addressable_entity::NamedKeys, CLType, EntryPoint, EntryPointAccess, EntryPointPayment, + EntryPointType, EntryPoints, Key, U512, }; const WRITE_FUNCTION_SMALL_NAME: &str = "write_function_small"; @@ -144,6 +144,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); let entry_point = EntryPoint::new( @@ -152,6 +153,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); let entry_point = EntryPoint::new( @@ -160,6 +162,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); let entry_point = EntryPoint::new( @@ -168,6 +171,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -177,6 +181,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -186,6 +191,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -195,6 +201,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -204,6 +211,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -213,6 +221,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -222,6 +231,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -231,6 +241,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -240,6 +251,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); diff --git a/smart_contracts/contracts/test/test-payment-stored/src/main.rs b/smart_contracts/contracts/test/test-payment-stored/src/main.rs index 24eddf3bd7..663b04ee89 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, Key, RuntimeArgs, URef, U512, + CLType, EntryPointPayment, Key, RuntimeArgs, URef, U512, }; const ENTRY_FUNCTION_NAME: &str = "pay"; @@ -54,6 +54,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); entry_points diff --git a/smart_contracts/contracts/test/transfer-purse-to-account-stored/src/main.rs b/smart_contracts/contracts/test/transfer-purse-to-account-stored/src/main.rs index b46127963b..acdc0ce1f3 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,7 @@ use casper_contract::contract_api::{runtime, storage}; use casper_types::{ addressable_entity::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Parameter}, - CLType, Key, + CLType, EntryPointPayment, Key, }; const ENTRY_FUNCTION_NAME: &str = "transfer"; @@ -39,6 +39,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Caller, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); entry_points diff --git a/smart_contracts/contracts/test/transfer-purse-to-accounts-stored/src/main.rs b/smart_contracts/contracts/test/transfer-purse-to-accounts-stored/src/main.rs index dcbbc0c3d1..7129925ba6 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,7 @@ use casper_types::{ addressable_entity::{ EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys, Parameter, }, - CLType, CLTyped, Key, U512, + CLType, CLTyped, EntryPointPayment, Key, U512, }; const ENTRY_FUNCTION_NAME: &str = "transfer"; @@ -57,6 +57,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); tmp.add_entry_point(entry_point); tmp diff --git a/smart_contracts/contracts/test/upgrade-threshold-upgrader/src/main.rs b/smart_contracts/contracts/test/upgrade-threshold-upgrader/src/main.rs index 35e165dfdc..5f76df13ea 100644 --- a/smart_contracts/contracts/test/upgrade-threshold-upgrader/src/main.rs +++ b/smart_contracts/contracts/test/upgrade-threshold-upgrader/src/main.rs @@ -11,7 +11,8 @@ use casper_contract::{ use casper_types::{ account::AccountHash, addressable_entity::{ActionType, NamedKeys, Weight}, - CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, PackageHash, Parameter, + CLType, EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints, Key, + PackageHash, Parameter, }; const ARG_ENTITY_ACCOUNT_HASH: &str = "entity_account_hash"; @@ -58,6 +59,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entrypoints.add_entry_point(add_associated_key_entry_point); let manage_action_threshold_entrypoint = EntryPoint::new( @@ -66,6 +68,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entrypoints.add_entry_point(manage_action_threshold_entrypoint); let remove_associated_key_entry_point = EntryPoint::new( @@ -77,6 +80,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entrypoints.add_entry_point(remove_associated_key_entry_point); entrypoints diff --git a/smart_contracts/contracts/test/upgrade-threshold/src/main.rs b/smart_contracts/contracts/test/upgrade-threshold/src/main.rs index 8270ac0de3..f645b9d4ee 100644 --- a/smart_contracts/contracts/test/upgrade-threshold/src/main.rs +++ b/smart_contracts/contracts/test/upgrade-threshold/src/main.rs @@ -11,7 +11,8 @@ use casper_contract::{ use casper_types::{ account::AccountHash, addressable_entity::{ActionType, Weight}, - CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Key, Parameter, + CLType, EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints, Key, + Parameter, }; const ARG_ENTITY_ACCOUNT_HASH: &str = "entity_account_hash"; @@ -52,6 +53,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entrypoints.add_entry_point(add_associated_key_entry_point); let manage_action_threshold_entrypoint = EntryPoint::new( @@ -60,6 +62,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entrypoints.add_entry_point(manage_action_threshold_entrypoint); entrypoints diff --git a/smart_contracts/contracts/tutorial/counter-installer/src/main.rs b/smart_contracts/contracts/tutorial/counter-installer/src/main.rs index 8c4dc9b364..71f26a7ea6 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, Key, URef, + CLType, CLValue, EntryPointPayment, Key, URef, }; const COUNT_KEY: &str = "count"; @@ -66,6 +66,7 @@ pub extern "C" fn call() { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); counter_entry_points.add_entry_point(EntryPoint::new( COUNTER_GET, @@ -73,6 +74,7 @@ pub extern "C" fn call() { CLType::I32, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, )); let (stored_contract_hash, contract_version) = storage::new_contract( diff --git a/storage/src/data_access_layer.rs b/storage/src/data_access_layer.rs index e9feea1da8..9397da4791 100644 --- a/storage/src/data_access_layer.rs +++ b/storage/src/data_access_layer.rs @@ -13,6 +13,7 @@ mod balance_hold; pub mod bids; mod block_global; pub mod block_rewards; +mod entry_points; pub mod era_validators; mod execution_results_checksum; mod fee; @@ -44,6 +45,7 @@ pub use balance_hold::{ pub use bids::{BidsRequest, BidsResult}; pub use block_global::{BlockGlobalKind, BlockGlobalRequest, BlockGlobalResult}; pub use block_rewards::{BlockRewardsError, BlockRewardsRequest, BlockRewardsResult}; +pub use entry_points::{EntryPointsRequest, EntryPointsResult}; pub use era_validators::{EraValidatorsRequest, EraValidatorsResult}; pub use execution_results_checksum::{ ExecutionResultsChecksumRequest, ExecutionResultsChecksumResult, diff --git a/storage/src/data_access_layer/entry_points.rs b/storage/src/data_access_layer/entry_points.rs new file mode 100644 index 0000000000..a0b28188cb --- /dev/null +++ b/storage/src/data_access_layer/entry_points.rs @@ -0,0 +1,55 @@ +use crate::tracking_copy::TrackingCopyError; +use casper_types::{Digest, EntryPoint, EntryPointValue, Key}; + +/// Represents a request to obtain entry points. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct EntryPointsRequest { + state_hash: Digest, + key: Key, +} + +impl EntryPointsRequest { + /// Creates new request. + pub fn new(state_hash: Digest, key: Key) -> Self { + EntryPointsRequest { state_hash, key } + } + + /// Returns state root hash. + pub fn state_hash(&self) -> Digest { + self.state_hash + } + + /// Returns key. + pub fn key(&self) -> Key { + self.key + } +} + +/// Represents a result of a `entry_points` request. +#[derive(Debug)] +pub enum EntryPointsResult { + /// Invalid state root hash. + RootNotFound, + /// Value not found. + ValueNotFound(String), + /// Contains an addressable entity from global state. + Success { + /// An addressable entity. + entry_point: EntryPointValue, + }, + Failure(TrackingCopyError), +} + +impl EntryPointsResult { + /// Returns the result based on a particular variant of entrypoint + pub fn into_v1_entry_point(self) -> Option<EntryPoint> { + if let Self::Success { entry_point } = self { + match entry_point { + EntryPointValue::V1CasperVm(entry_point) => Some(entry_point), + EntryPointValue::V2CasperVm(_) => None, + } + } else { + None + } + } +} diff --git a/storage/src/global_state/state/mod.rs b/storage/src/global_state/state/mod.rs index 7f44420fae..22aa4560a5 100644 --- a/storage/src/global_state/state/mod.rs +++ b/storage/src/global_state/state/mod.rs @@ -50,16 +50,16 @@ use crate::{ BalanceHoldKind, BalanceHoldMode, BalanceHoldRequest, BalanceHoldResult, BalanceIdentifier, BalanceRequest, BalanceResult, BidsRequest, BidsResult, BlockGlobalKind, BlockGlobalRequest, BlockGlobalResult, BlockRewardsError, BlockRewardsRequest, - BlockRewardsResult, EraValidatorsRequest, ExecutionResultsChecksumRequest, - ExecutionResultsChecksumResult, FeeError, FeeRequest, FeeResult, FlushRequest, FlushResult, - GenesisRequest, GenesisResult, HandleRefundMode, HandleRefundRequest, HandleRefundResult, - InsufficientBalanceHandling, ProofHandling, ProofsResult, ProtocolUpgradeRequest, - ProtocolUpgradeResult, PruneRequest, PruneResult, PutTrieRequest, PutTrieResult, - QueryRequest, QueryResult, RoundSeigniorageRateRequest, RoundSeigniorageRateResult, - StepError, StepRequest, StepResult, SystemEntityRegistryPayload, - SystemEntityRegistryRequest, SystemEntityRegistryResult, SystemEntityRegistrySelector, - TotalSupplyRequest, TotalSupplyResult, TrieRequest, TrieResult, - EXECUTION_RESULTS_CHECKSUM_NAME, + BlockRewardsResult, EntryPointsRequest, EntryPointsResult, EraValidatorsRequest, + ExecutionResultsChecksumRequest, ExecutionResultsChecksumResult, FeeError, FeeRequest, + FeeResult, FlushRequest, FlushResult, GenesisRequest, GenesisResult, HandleRefundMode, + HandleRefundRequest, HandleRefundResult, InsufficientBalanceHandling, ProofHandling, + ProofsResult, ProtocolUpgradeRequest, ProtocolUpgradeResult, PruneRequest, PruneResult, + PutTrieRequest, PutTrieResult, QueryRequest, QueryResult, RoundSeigniorageRateRequest, + RoundSeigniorageRateResult, StepError, StepRequest, StepResult, + SystemEntityRegistryPayload, SystemEntityRegistryRequest, SystemEntityRegistryResult, + SystemEntityRegistrySelector, TotalSupplyRequest, TotalSupplyResult, TrieRequest, + TrieResult, EXECUTION_RESULTS_CHECKSUM_NAME, }, global_state::{ error::Error as GlobalStateError, @@ -147,7 +147,7 @@ pub trait CommitProvider: StateProvider { Err(err) => { return GenesisResult::Failure(GenesisError::TrackingCopy( TrackingCopyError::Storage(err), - )) + )); } }; let chainspec_hash = request.chainspec_hash(); @@ -183,7 +183,7 @@ pub trait CommitProvider: StateProvider { Err(err) => { return ProtocolUpgradeResult::Failure(ProtocolUpgradeError::TrackingCopy( TrackingCopyError::Storage(err), - )) + )); } }; @@ -250,7 +250,7 @@ pub trait CommitProvider: StateProvider { Err(err) => { return StepResult::Failure(StepError::TrackingCopy(TrackingCopyError::Storage( err, - ))) + ))); } }; let protocol_version = request.protocol_version(); @@ -262,7 +262,7 @@ pub trait CommitProvider: StateProvider { Err(bre) => { return StepResult::Failure(StepError::TrackingCopy( TrackingCopyError::BytesRepr(bre), - )) + )); } }; match &mut protocol_version.into_bytes() { @@ -270,7 +270,7 @@ pub trait CommitProvider: StateProvider { Err(bre) => { return StepResult::Failure(StepError::TrackingCopy( TrackingCopyError::BytesRepr(*bre), - )) + )); } }; match &mut request.next_era_id().into_bytes() { @@ -278,7 +278,7 @@ pub trait CommitProvider: StateProvider { Err(bre) => { return StepResult::Failure(StepError::TrackingCopy( TrackingCopyError::BytesRepr(*bre), - )) + )); } }; @@ -355,7 +355,7 @@ pub trait CommitProvider: StateProvider { Err(err) => { return BlockRewardsResult::Failure(BlockRewardsError::TrackingCopy( TrackingCopyError::Storage(err), - )) + )); } }; @@ -367,7 +367,7 @@ pub trait CommitProvider: StateProvider { Err(bre) => { return BlockRewardsResult::Failure(BlockRewardsError::TrackingCopy( TrackingCopyError::BytesRepr(bre), - )) + )); } }; match &mut protocol_version.into_bytes() { @@ -375,7 +375,7 @@ pub trait CommitProvider: StateProvider { Err(bre) => { return BlockRewardsResult::Failure(BlockRewardsError::TrackingCopy( TrackingCopyError::BytesRepr(*bre), - )) + )); } }; @@ -433,7 +433,7 @@ pub trait CommitProvider: StateProvider { Ok(Some(tracking_copy)) => Rc::new(RefCell::new(tracking_copy)), Ok(None) => return FeeResult::RootNotFound, Err(gse) => { - return FeeResult::Failure(FeeError::TrackingCopy(TrackingCopyError::Storage(gse))) + return FeeResult::Failure(FeeError::TrackingCopy(TrackingCopyError::Storage(gse))); } }; @@ -445,7 +445,7 @@ pub trait CommitProvider: StateProvider { Err(bre) => { return FeeResult::Failure(FeeError::TrackingCopy( TrackingCopyError::BytesRepr(bre), - )) + )); } }; match &mut protocol_version.into_bytes() { @@ -453,7 +453,7 @@ pub trait CommitProvider: StateProvider { Err(bre) => { return FeeResult::Failure(FeeError::TrackingCopy( TrackingCopyError::BytesRepr(*bre), - )) + )); } }; @@ -491,7 +491,7 @@ pub trait CommitProvider: StateProvider { Err(gse) => { return FeeResult::Failure(FeeError::TrackingCopy( TrackingCopyError::Storage(gse), - )) + )); } }; FeeResult::Success { @@ -665,7 +665,7 @@ pub trait StateProvider { total_balance, available_balance: total_balance, proofs_result, - } + }; } Err(tce) => return tce.into(), }; @@ -679,7 +679,7 @@ pub trait StateProvider { total_balance, available_balance: total_balance, proofs_result, - } + }; } Err(tce) => return tce.into(), }; @@ -710,7 +710,7 @@ pub trait StateProvider { Err(err) => { return BalanceHoldResult::Failure(BalanceHoldError::TrackingCopy( TrackingCopyError::Storage(err), - )) + )); } }; let hold_mode = request.balance_hold_mode(); @@ -729,7 +729,7 @@ pub trait StateProvider { BalanceHoldKind::All => { return BalanceHoldResult::Failure( BalanceHoldError::UnexpectedWildcardVariant, - ) + ); } BalanceHoldKind::Tag(tag) => tag, }; @@ -780,7 +780,7 @@ pub trait StateProvider { Err(cve) => { return BalanceHoldResult::Failure(BalanceHoldError::TrackingCopy( TrackingCopyError::CLValue(cve), - )) + )); } }; @@ -814,7 +814,7 @@ pub trait StateProvider { let purse_addr = match identifier.purse_uref(&mut tc, request.protocol_version()) { Ok(source_purse) => source_purse.addr(), Err(tce) => { - return BalanceHoldResult::Failure(BalanceHoldError::TrackingCopy(tce)) + return BalanceHoldResult::Failure(BalanceHoldError::TrackingCopy(tce)); } }; @@ -832,7 +832,7 @@ pub trait StateProvider { Err(tce) => { return BalanceHoldResult::Failure(BalanceHoldError::TrackingCopy( tce, - )) + )); } }; filter.push((tag, HoldsEpoch::from_millis(block_time.value(), interval))); @@ -847,7 +847,7 @@ pub trait StateProvider { Err(tce) => { return BalanceHoldResult::Failure(BalanceHoldError::TrackingCopy( tce, - )) + )); } }; filter.push((tag, HoldsEpoch::from_millis(block_time.value(), interval))); @@ -978,7 +978,9 @@ pub trait StateProvider { bids.push(bid_kind); } Some(_) => { - return BidsResult::Failure(TrackingCopyError::UnexpectedStoredValueVariant) + return BidsResult::Failure( + TrackingCopyError::UnexpectedStoredValueVariant, + ); } None => return BidsResult::Failure(TrackingCopyError::MissingBid(*key)), }, @@ -1448,7 +1450,7 @@ pub trait StateProvider { Ok(Some(tc)) => tc, Ok(None) => return ExecutionResultsChecksumResult::RootNotFound, Err(err) => { - return ExecutionResultsChecksumResult::Failure(TrackingCopyError::Storage(err)) + return ExecutionResultsChecksumResult::Failure(TrackingCopyError::Storage(err)); } }; match tc.get_checksum_registry() { @@ -1472,7 +1474,7 @@ pub trait StateProvider { match self.query(query_request) { QueryResult::RootNotFound => return AddressableEntityResult::RootNotFound, QueryResult::ValueNotFound(msg) => { - return AddressableEntityResult::ValueNotFound(msg) + return AddressableEntityResult::ValueNotFound(msg); } QueryResult::Failure(err) => return AddressableEntityResult::Failure(err), QueryResult::Success { value, .. } => { @@ -1521,7 +1523,7 @@ pub trait StateProvider { match self.query(query_request) { QueryResult::RootNotFound => return AddressableEntityResult::RootNotFound, QueryResult::ValueNotFound(msg) => { - return AddressableEntityResult::ValueNotFound(msg) + return AddressableEntityResult::ValueNotFound(msg); } QueryResult::Failure(err) => return AddressableEntityResult::Failure(err), QueryResult::Success { value, .. } => { @@ -1538,7 +1540,7 @@ pub trait StateProvider { _ => { return AddressableEntityResult::Failure(TrackingCopyError::UnexpectedKeyVariant( key, - )) + )); } }; @@ -1552,7 +1554,7 @@ pub trait StateProvider { None => { return AddressableEntityResult::Failure( TrackingCopyError::UnexpectedStoredValueVariant, - ) + ); } }; AddressableEntityResult::Success { entity } @@ -1571,7 +1573,7 @@ pub trait StateProvider { Ok(Some(tc)) => tc, Ok(None) => return SystemEntityRegistryResult::RootNotFound, Err(err) => { - return SystemEntityRegistryResult::Failure(TrackingCopyError::Storage(err)) + return SystemEntityRegistryResult::Failure(TrackingCopyError::Storage(err)); } }; @@ -1608,6 +1610,28 @@ pub trait StateProvider { } } + /// Gets an entry point value. + fn entry_point(&self, request: EntryPointsRequest) -> EntryPointsResult { + let state_hash = request.state_hash(); + let query_request = QueryRequest::new(state_hash, request.key(), vec![]); + + match self.query(query_request) { + QueryResult::RootNotFound => EntryPointsResult::RootNotFound, + QueryResult::ValueNotFound(msg) => EntryPointsResult::ValueNotFound(msg), + QueryResult::Failure(tce) => EntryPointsResult::Failure(tce), + QueryResult::Success { value, .. } => { + if let StoredValue::EntryPoint(entry_point_value) = *value { + EntryPointsResult::Success { + entry_point: entry_point_value, + } + } else { + error!("Expected to get entry point value received other variant"); + EntryPointsResult::Failure(TrackingCopyError::UnexpectedStoredValueVariant) + } + } + } + } + /// Gets total supply. fn total_supply(&self, request: TotalSupplyRequest) -> TotalSupplyResult { let state_hash = request.state_hash(); @@ -1668,7 +1692,7 @@ pub trait StateProvider { Ok(Some(tc)) => tc, Ok(None) => return RoundSeigniorageRateResult::RootNotFound, Err(err) => { - return RoundSeigniorageRateResult::Failure(TrackingCopyError::Storage(err)) + return RoundSeigniorageRateResult::Failure(TrackingCopyError::Storage(err)); } }; diff --git a/storage/src/system/genesis.rs b/storage/src/system/genesis.rs index ba6d39f792..ab068bd31b 100644 --- a/storage/src/system/genesis.rs +++ b/storage/src/system/genesis.rs @@ -41,10 +41,11 @@ use casper_types::{ }, AccessRights, AddressableEntity, AddressableEntityHash, AdministratorAccount, BlockGlobalAddr, BlockTime, ByteCode, ByteCodeAddr, ByteCodeHash, ByteCodeKind, CLValue, Chainspec, - ChainspecRegistry, Digest, EntityAddr, EntityVersions, EntryPoints, EraId, FeeHandling, - GenesisAccount, GenesisConfig, GenesisConfigBuilder, Groups, Key, Motes, Package, PackageHash, - PackageStatus, Phase, ProtocolVersion, PublicKey, RefundHandling, StoredValue, SystemConfig, - SystemEntityRegistry, Tagged, TimeDiff, URef, WasmConfig, U512, + ChainspecRegistry, Digest, EntityAddr, EntityVersions, EntryPointAddr, EntryPointValue, + EntryPoints, EraId, FeeHandling, GenesisAccount, GenesisConfig, GenesisConfigBuilder, Groups, + Key, Motes, Package, PackageHash, PackageStatus, Phase, ProtocolVersion, PublicKey, + RefundHandling, StoredValue, SystemConfig, SystemEntityRegistry, Tagged, TimeDiff, URef, + WasmConfig, U512, }; use crate::{ @@ -741,23 +742,15 @@ where let associated_keys = entity_kind.associated_keys(); let maybe_account_hash = entity_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, - None => { - if maybe_account_hash.is_some() { - EntryPoints::new() - } else { - EntryPoints::new_with_default_entry_point() - } - } - }; self.store_system_contract_named_keys(entity_hash, named_keys)?; + if let Some(entry_point) = maybe_entry_points { + self.store_system_entry_points(entity_hash, entry_point)?; + } let entity = AddressableEntity::new( package_hash, byte_code_hash, - entry_points, protocol_version, main_purse, associated_keys, @@ -837,6 +830,26 @@ where Ok(()) } + fn store_system_entry_points( + &self, + contract_hash: AddressableEntityHash, + entry_points: EntryPoints, + ) -> Result<(), Box<GenesisError>> { + let entity_addr = EntityAddr::new_system(contract_hash.value()); + + for entry_point in entry_points.take_entry_points() { + let entry_point_addr = + EntryPointAddr::new_v1_entry_point_addr(entity_addr, entry_point.name()) + .map_err(GenesisError::Bytesrepr)?; + self.tracking_copy.borrow_mut().write( + Key::EntryPoint(entry_point_addr), + StoredValue::EntryPoint(EntryPointValue::V1CasperVm(entry_point)), + ) + } + + Ok(()) + } + fn store_system_entity_registry( &self, contract_name: &str, diff --git a/storage/src/system/protocol_upgrade.rs b/storage/src/system/protocol_upgrade.rs index 3c2dab42c0..9b3a616974 100644 --- a/storage/src/system/protocol_upgrade.rs +++ b/storage/src/system/protocol_upgrade.rs @@ -23,8 +23,8 @@ use casper_types::{ SystemEntityType, AUCTION, HANDLE_PAYMENT, MINT, }, AccessRights, AddressableEntity, AddressableEntityHash, ByteCode, ByteCodeAddr, ByteCodeHash, - ByteCodeKind, CLValue, CLValueError, Digest, EntityAddr, EntityVersions, EntryPoints, - FeeHandling, Groups, Key, KeyTag, Package, PackageHash, PackageStatus, Phase, + ByteCodeKind, CLValue, CLValueError, Digest, EntityAddr, EntityVersions, EntryPointAddr, + EntryPointValue, FeeHandling, Groups, Key, KeyTag, Package, PackageHash, PackageStatus, Phase, ProtocolUpgradeConfig, ProtocolVersion, PublicKey, StoredValue, SystemEntityRegistry, URef, U512, }; @@ -317,7 +317,6 @@ where ) -> Result<(), ProtocolUpgradeError> { debug!(%system_entity_type, "refresh system contract entry points"); let entity_name = system_entity_type.entity_name(); - let entry_points = system_entity_type.entry_points(); let (mut entity, maybe_named_keys, must_prune) = match self.retrieve_system_entity(entity_hash, system_entity_type) { @@ -340,7 +339,6 @@ where let new_entity = AddressableEntity::new( entity.package_hash(), ByteCodeHash::default(), - entry_points, self.config.new_protocol_version(), URef::default(), AssociatedKeys::default(), @@ -362,9 +360,9 @@ where .borrow_mut() .write(entity_key, StoredValue::AddressableEntity(new_entity)); - if let Some(named_keys) = maybe_named_keys { - let entity_addr = EntityAddr::new_system(entity_hash.value()); + let entity_addr = EntityAddr::new_system(entity_hash.value()); + if let Some(named_keys) = maybe_named_keys { for (string, key) in named_keys.into_inner().into_iter() { let entry_addr = NamedKeyAddr::new_from_string(entity_addr, string.clone()) .map_err(|err| ProtocolUpgradeError::Bytesrepr(err.to_string()))?; @@ -380,6 +378,20 @@ where } } + println!("writing entry points"); + + let entry_points = system_entity_type.entry_points(); + + for entry_point in entry_points.take_entry_points() { + let entry_point_addr = + EntryPointAddr::new_v1_entry_point_addr(entity_addr, entry_point.name()) + .map_err(|error| ProtocolUpgradeError::Bytesrepr(error.to_string()))?; + self.tracking_copy.borrow_mut().write( + Key::EntryPoint(entry_point_addr), + StoredValue::EntryPoint(EntryPointValue::V1CasperVm(entry_point)), + ); + } + package.insert_entity_version( self.config.new_protocol_version().value().major, entity_hash, @@ -523,7 +535,6 @@ where let system_account_entity = AddressableEntity::new( package_hash, byte_code_hash, - EntryPoints::new(), self.config.new_protocol_version(), main_purse, associated_keys, diff --git a/storage/src/tracking_copy/byte_size.rs b/storage/src/tracking_copy/byte_size.rs index 7b9a4eeeb1..d78b7c8227 100644 --- a/storage/src/tracking_copy/byte_size.rs +++ b/storage/src/tracking_copy/byte_size.rs @@ -48,6 +48,7 @@ impl ByteSize for StoredValue { StoredValue::Message(message_summary) => message_summary.serialized_length(), StoredValue::NamedKey(named_key) => named_key.serialized_length(), StoredValue::Reservation(reservation_kind) => reservation_kind.serialized_length(), + StoredValue::EntryPoint(entry_point) => entry_point.serialized_length(), } } } diff --git a/storage/src/tracking_copy/ext.rs b/storage/src/tracking_copy/ext.rs index 060e0f10c1..e7ee530432 100644 --- a/storage/src/tracking_copy/ext.rs +++ b/storage/src/tracking_copy/ext.rs @@ -23,8 +23,9 @@ use casper_types::{ MINT, }, BlockGlobalAddr, BlockTime, ByteCode, ByteCodeAddr, ByteCodeHash, CLValue, ChecksumRegistry, - EntityAddr, HoldBalanceHandling, HoldsEpoch, Key, KeyTag, Motes, Package, PackageHash, - StoredValue, StoredValueTypeMismatch, SystemEntityRegistry, URef, URefAddr, U512, + EntityAddr, EntryPointAddr, EntryPointValue, EntryPoints, HoldBalanceHandling, HoldsEpoch, Key, + KeyTag, Motes, Package, PackageHash, StoredValue, StoredValueTypeMismatch, + SystemEntityRegistry, URef, URefAddr, U512, }; /// Higher-level operations on the state via a `TrackingCopy`. @@ -93,6 +94,9 @@ pub trait TrackingCopyExt<R> { /// Returns the collection of named keys for a given AddressableEntity. fn get_named_keys(&self, entity_addr: EntityAddr) -> Result<NamedKeys, Self::Error>; + /// Returns the collection of entry points for a given AddresableEntity. + fn get_v1_entry_points(&mut self, entity_addr: EntityAddr) -> Result<EntryPoints, Self::Error>; + /// Gets a package by hash. fn get_package(&mut self, package_hash: PackageHash) -> Result<Package, Self::Error>; @@ -147,7 +151,7 @@ where }; let (handling_key, interval_key) = match hold_kind { BalanceHoldAddrTag::Processing => { - return Ok(Some((block_time, HoldBalanceHandling::Accrued, 0))) + return Ok(Some((block_time, HoldBalanceHandling::Accrued, 0))); } BalanceHoldAddrTag::Gas => (MINT_GAS_HOLD_HANDLING_KEY, MINT_GAS_HOLD_INTERVAL_KEY), }; @@ -580,7 +584,7 @@ where Some(other) => { return Err(TrackingCopyError::TypeMismatch( StoredValueTypeMismatch::new("CLValue".to_string(), other.type_name()), - )) + )); } None => match self.cache.reads_cached.get(entry_key) { Some(StoredValue::NamedKey(named_key_value)) => { @@ -602,6 +606,78 @@ where Ok(named_keys) } + fn get_v1_entry_points(&mut self, entity_addr: EntityAddr) -> Result<EntryPoints, Self::Error> { + let entry_points_prefix = entity_addr + .entry_points_v1_prefix() + .map_err(Self::Error::BytesRepr)?; + + let mut ret: BTreeSet<Key> = BTreeSet::new(); + let keys = self.reader.keys_with_prefix(&entry_points_prefix)?; + let pruned = &self.cache.prunes_cached; + // don't include keys marked for pruning + for key in keys { + if pruned.contains(&key) { + continue; + } + ret.insert(key); + } + + let cache = self.cache.get_key_tag_muts_cached(&KeyTag::EntryPoint); + + // there may be newly inserted keys which have not been committed yet + if let Some(keys) = cache { + for key in keys { + if ret.contains(&key) { + continue; + } + if let Key::EntryPoint(entry_point_addr) = key { + match entry_point_addr { + EntryPointAddr::VmCasperV1 { .. } => { + ret.insert(key); + } + EntryPointAddr::VmCasperV2 { .. } => continue, + } + } + } + }; + + let mut entry_points_v1 = EntryPoints::new(); + + for entry_point_key in ret.iter() { + match self.read(entry_point_key)? { + Some(StoredValue::EntryPoint(EntryPointValue::V1CasperVm(entry_point))) => { + entry_points_v1.add_entry_point(entry_point) + } + Some(other) => { + return Err(TrackingCopyError::TypeMismatch( + StoredValueTypeMismatch::new( + "EntryPointsV1".to_string(), + other.type_name(), + ), + )); + } + None => match self.cache.reads_cached.get(entry_point_key) { + Some(StoredValue::EntryPoint(EntryPointValue::V1CasperVm(entry_point))) => { + entry_points_v1.add_entry_point(entry_point.to_owned()) + } + Some(other) => { + return Err(TrackingCopyError::TypeMismatch( + StoredValueTypeMismatch::new( + "EntryPointsV1".to_string(), + other.type_name(), + ), + )); + } + None => { + return Err(TrackingCopyError::KeyNotFound(*entry_point_key)); + } + }, + } + } + + Ok(entry_points_v1) + } + fn get_package(&mut self, package_hash: PackageHash) -> Result<Package, Self::Error> { let key = package_hash.into(); match self.read(&key)? { diff --git a/storage/src/tracking_copy/ext_entity.rs b/storage/src/tracking_copy/ext_entity.rs index 4b129210f9..ba4cd2532d 100644 --- a/storage/src/tracking_copy/ext_entity.rs +++ b/storage/src/tracking_copy/ext_entity.rs @@ -11,8 +11,9 @@ use casper_types::{ system::{handle_payment::ACCUMULATION_PURSE_KEY, AUCTION, HANDLE_PAYMENT, MINT}, AccessRights, Account, AddressableEntity, AddressableEntityHash, ByteCode, ByteCodeAddr, ByteCodeHash, CLValue, ContextAccessRights, EntityAddr, EntityKind, EntityVersions, - EntryPoints, Groups, Key, Package, PackageHash, PackageStatus, Phase, ProtocolVersion, - PublicKey, StoredValue, StoredValueTypeMismatch, URef, U512, + EntryPointAddr, EntryPointValue, EntryPoints, Groups, Key, Package, PackageHash, PackageStatus, + Phase, ProtocolVersion, PublicKey, StoredValue, StoredValueTypeMismatch, TransactionRuntime, + URef, U512, }; use crate::{ @@ -75,6 +76,11 @@ pub trait TrackingCopyEntityExt<R> { entity_addr: EntityAddr, named_keys: NamedKeys, ) -> Result<(), Self::Error>; + fn migrate_entry_points( + &mut self, + entity_addr: EntityAddr, + entry_points: EntryPoints, + ) -> Result<(), Self::Error>; /// Upsert uref value to global state and imputed entity's named keys. fn upsert_uref_to_named_keys( @@ -226,8 +232,6 @@ where let entity_hash = AddressableEntityHash::new(generator.new_hash_address()); let package_hash = PackageHash::new(generator.new_hash_address()); - let entry_points = EntryPoints::new(); - self.migrate_named_keys( EntityAddr::Account(entity_hash.value()), account.named_keys().clone(), @@ -236,7 +240,6 @@ where let entity = AddressableEntity::new( package_hash, byte_code_hash, - entry_points, protocol_version, account.main_purse(), account.associated_keys().clone().into(), @@ -350,6 +353,25 @@ where Ok(()) } + fn migrate_entry_points( + &mut self, + entity_addr: EntityAddr, + entry_points: EntryPoints, + ) -> Result<(), Self::Error> { + if entry_points.is_empty() { + return Ok(()); + } + for entry_point in entry_points.take_entry_points().into_iter() { + let entry_point_addr = + EntryPointAddr::new_v1_entry_point_addr(entity_addr, entry_point.name())?; + let entry_point_value = + StoredValue::EntryPoint(EntryPointValue::V1CasperVm(entry_point)); + self.write(Key::EntryPoint(entry_point_addr), entry_point_value) + } + + Ok(()) + } + fn upsert_uref_to_named_keys( &mut self, entity_addr: EntityAddr, @@ -423,8 +445,6 @@ where 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::new(account_hash, Weight::new(1)); let action_thresholds: ActionThresholds = Default::default(); @@ -432,7 +452,6 @@ where let entity = AddressableEntity::new( package_hash, byte_code_hash, - entry_points, protocol_version, main_purse, associated_keys, @@ -508,7 +527,6 @@ where // however, we intend to revisit this and potentially allow it in a future release // as a replacement for stored session. let byte_code_hash = ByteCodeHash::default(); - let entry_points = EntryPoints::new(); let action_thresholds = { let account_threshold = account.action_thresholds().clone(); @@ -525,7 +543,6 @@ where let entity = AddressableEntity::new( package_hash, byte_code_hash, - entry_points, protocol_version, account.main_purse(), associated_keys, @@ -600,18 +617,19 @@ where let updated_entity = AddressableEntity::new( PackageHash::new(legacy_contract.contract_package_hash().value()), ByteCodeHash::new(contract_wasm_hash.value()), - legacy_contract.entry_points().clone(), protocol_version, purse, AssociatedKeys::default(), ActionThresholds::default(), MessageTopics::default(), - EntityKind::SmartContract, + EntityKind::SmartContract(TransactionRuntime::VmCasperV1), ); + let entry_points = legacy_contract.entry_points().clone(); let named_keys = legacy_contract.take_named_keys(); self.migrate_named_keys(contract_addr, named_keys)?; + self.migrate_entry_points(contract_addr, entry_points.into())?; let maybe_previous_wasm = self .read(&Key::Hash(contract_wasm_hash.value()))? diff --git a/storage/src/tracking_copy/mod.rs b/storage/src/tracking_copy/mod.rs index 9d7c57a678..5321265792 100644 --- a/storage/src/tracking_copy/mod.rs +++ b/storage/src/tracking_copy/mod.rs @@ -568,7 +568,7 @@ where return Ok(query.into_not_found_result(&format!( "Failed to retrieve dictionary value: {}", error - ))) + ))); } }; @@ -619,11 +619,11 @@ where } Err(_) => { return Ok(query - .into_not_found_result("Failed to parse CLValue as String")) + .into_not_found_result("Failed to parse CLValue as String")); } }, None if path.is_empty() => { - return Ok(TrackingCopyQueryResult::Success { value, proofs }) + return Ok(TrackingCopyQueryResult::Success { value, proofs }); } None => return Ok(query.into_not_found_result("No visited names")), } @@ -701,6 +701,9 @@ where StoredValue::Message(_) => { return Ok(query.into_not_found_result("Message value found.")); } + StoredValue::EntryPoint(_) => { + return Ok(query.into_not_found_result("EntryPoint value found.")); + } // TODO: We may be interested in this value, check the logic StoredValue::Reservation(_) => { return Ok(query.into_not_found_result("Reservation value found.")) diff --git a/storage/src/tracking_copy/tests.rs b/storage/src/tracking_copy/tests.rs index baa713e581..5fdf6847d9 100644 --- a/storage/src/tracking_copy/tests.rs +++ b/storage/src/tracking_copy/tests.rs @@ -8,12 +8,13 @@ use casper_types::{ ActionThresholds, AddressableEntityHash, AssociatedKeys, MessageTopics, NamedKeyAddr, NamedKeyValue, NamedKeys, Weight, }, + contracts::EntryPoints as ContractEntryPoints, execution::{Effects, TransformKindV2, TransformV2}, gens::*, global_state::TrieMerkleProof, handle_stored_dictionary_value, AccessRights, AddressableEntity, ByteCodeHash, CLValue, - CLValueDictionary, CLValueError, EntityAddr, EntityKind, EntryPoints, HashAddr, Key, KeyTag, - PackageHash, ProtocolVersion, StoredValue, URef, U256, U512, UREF_ADDR_LENGTH, + CLValueDictionary, CLValueError, EntityAddr, EntityKind, HashAddr, Key, KeyTag, PackageHash, + ProtocolVersion, StoredValue, TransactionRuntime, URef, U256, U512, UREF_ADDR_LENGTH, }; use super::{ @@ -147,7 +148,7 @@ fn tracking_copy_write() { tc.effects, effects(vec![ (k, TransformKindV2::Write(one)), - (k, TransformKindV2::Write(two)) + (k, TransformKindV2::Write(two)), ]) ); } @@ -192,7 +193,7 @@ fn tracking_copy_rw() { tc.effects, effects(vec![ (k, TransformKindV2::Identity), - (k, TransformKindV2::Write(value)) + (k, TransformKindV2::Write(value)), ]) ); } @@ -212,7 +213,7 @@ fn tracking_copy_ra() { tc.effects, effects(vec![ (k, TransformKindV2::Identity), - (k, TransformKindV2::AddInt32(3)) + (k, TransformKindV2::AddInt32(3)), ]) ); } @@ -233,7 +234,7 @@ fn tracking_copy_aw() { tc.effects, effects(vec![ (k, TransformKindV2::AddInt32(3)), - (k, TransformKindV2::Write(write_value)) + (k, TransformKindV2::Write(write_value)), ]) ); } @@ -321,7 +322,7 @@ fn should_traverse_contract_pathing() { [2; 32].into(), [3; 32].into(), contract_named_keys, - EntryPoints::new(), + ContractEntryPoints::new(), ProtocolVersion::V1_0_0, ); let contract_hash = ContractHash::default(); @@ -348,7 +349,7 @@ fn should_traverse_account_pathing() { [2; 32].into(), [3; 32].into(), NamedKeys::default(), - EntryPoints::new(), + ContractEntryPoints::new(), ProtocolVersion::V1_0_0, ); let contract_hash = ContractHash::default(); @@ -412,7 +413,7 @@ fn should_traverse_all_paths() { [2; 32].into(), [3; 32].into(), contract_named_keys, - EntryPoints::new(), + ContractEntryPoints::new(), ProtocolVersion::V1_0_0, ); StoredValue::Contract(contract) @@ -517,6 +518,7 @@ fn should_traverse_all_paths() { "unexpected stored value" ); } + fn handle_stored_value_into( key: Key, stored_value: StoredValue, @@ -547,13 +549,12 @@ proptest! { StoredValue::AddressableEntity(AddressableEntity::new( [2; 32].into(), [3; 32].into(), - EntryPoints::new(), ProtocolVersion::V1_0_0, URef::default(), AssociatedKeys::default(), ActionThresholds::default(), MessageTopics::default(), - EntityKind::SmartContract + EntityKind::SmartContract(TransactionRuntime::VmCasperV1) )); let contract_key = Key::AddressableEntity(EntityAddr::SmartContract(hash)); @@ -594,7 +595,6 @@ proptest! { let entity = AddressableEntity::new( PackageHash::new([1u8;32]), ByteCodeHash::default(), - EntryPoints::new_with_default_entry_point(), ProtocolVersion::V1_0_0, purse, associated_keys, @@ -642,13 +642,12 @@ proptest! { StoredValue::AddressableEntity(AddressableEntity::new( [2; 32].into(), [3; 32].into(), - EntryPoints::new(), ProtocolVersion::V1_0_0, URef::default(), AssociatedKeys::default(), ActionThresholds::default(), MessageTopics::default(), - EntityKind::SmartContract + EntityKind::SmartContract(TransactionRuntime::VmCasperV1) )); let contract_key = Key::AddressableEntity(EntityAddr::SmartContract(hash)); let contract_named_key = NamedKeyAddr::new_from_string(EntityAddr::SmartContract(hash), state_name.clone()) @@ -740,13 +739,12 @@ fn query_for_circular_references_should_fail() { let contract = StoredValue::AddressableEntity(AddressableEntity::new( [2; 32].into(), [3; 32].into(), - EntryPoints::new(), ProtocolVersion::V1_0_0, URef::default(), AssociatedKeys::default(), ActionThresholds::default(), MessageTopics::default(), - EntityKind::SmartContract, + EntityKind::SmartContract(TransactionRuntime::VmCasperV1), )); let name_key_cl_value = Key::NamedKey( @@ -804,7 +802,6 @@ fn validate_query_proof_should_work() { let a_e = StoredValue::AddressableEntity(AddressableEntity::new( PackageHash::new([20; 32]), ByteCodeHash::default(), - EntryPoints::new_with_default_entry_point(), ProtocolVersion::V1_0_0, URef::default(), AssociatedKeys::new(AccountHash::new([3; 32]), Weight::new(1)), @@ -817,13 +814,12 @@ fn validate_query_proof_should_work() { let c_e = StoredValue::AddressableEntity(AddressableEntity::new( [2; 32].into(), [3; 32].into(), - EntryPoints::new(), ProtocolVersion::V1_0_0, URef::default(), AssociatedKeys::default(), ActionThresholds::default(), MessageTopics::default(), - EntityKind::SmartContract, + EntityKind::SmartContract(TransactionRuntime::VmCasperV1), )); let c_nk = "abc".to_string(); @@ -1073,13 +1069,12 @@ fn query_with_large_depth_with_fixed_path_should_fail() { let contract = StoredValue::AddressableEntity(AddressableEntity::new( val_to_hashaddr(PACKAGE_OFFSET + value).into(), val_to_hashaddr(WASM_OFFSET + value).into(), - EntryPoints::new(), ProtocolVersion::V1_0_0, URef::default(), AssociatedKeys::default(), ActionThresholds::default(), MessageTopics::default(), - EntityKind::SmartContract, + EntityKind::SmartContract(TransactionRuntime::VmCasperV1), )); pairs.push((contract_key, contract)); contract_keys.push(contract_key); @@ -1141,13 +1136,12 @@ fn query_with_large_depth_with_urefs_should_fail() { let contract = StoredValue::AddressableEntity(AddressableEntity::new( val_to_hashaddr(PACKAGE_OFFSET).into(), val_to_hashaddr(WASM_OFFSET).into(), - EntryPoints::new(), ProtocolVersion::V1_0_0, URef::default(), AssociatedKeys::default(), ActionThresholds::default(), MessageTopics::default(), - EntityKind::SmartContract, + EntityKind::SmartContract(casper_types::TransactionRuntime::VmCasperV1), )); let contract_key = Key::AddressableEntity(contract_addr); pairs.push((contract_key, contract)); diff --git a/types/benches/bytesrepr_bench.rs b/types/benches/bytesrepr_bench.rs index d7e154fb02..131bbe07ae 100644 --- a/types/benches/bytesrepr_bench.rs +++ b/types/benches/bytesrepr_bench.rs @@ -1,10 +1,10 @@ -use criterion::{black_box, criterion_group, criterion_main, Bencher, Criterion}; - use std::{ collections::{BTreeMap, BTreeSet}, iter, }; +use criterion::{black_box, criterion_group, criterion_main, Bencher, Criterion}; + use casper_types::{ account::AccountHash, addressable_entity::{ @@ -12,12 +12,11 @@ use casper_types::{ }, bytesrepr::{self, Bytes, FromBytes, ToBytes}, system::auction::{Bid, Delegator, EraInfo, SeigniorageAllocation}, - AccessRights, AddressableEntityHash, ByteCodeHash, CLType, CLTyped, CLValue, DeployHash, - DeployInfo, EntityVersionKey, EntityVersions, EntryPoint, EntryPointAccess, EntryPointType, - EntryPoints, Gas, Group, Groups, InitiatorAddr, Key, Package, PackageHash, PackageStatus, - Parameter, ProtocolVersion, PublicKey, SecretKey, TransactionHash, TransactionV1Hash, - TransferAddr, TransferV2, URef, KEY_HASH_LENGTH, TRANSFER_ADDR_LENGTH, U128, U256, U512, - UREF_ADDR_LENGTH, + AccessRights, AddressableEntityHash, ByteCodeHash, CLTyped, CLValue, DeployHash, DeployInfo, + EntityVersionKey, EntityVersions, Gas, Group, Groups, InitiatorAddr, Key, Package, PackageHash, + PackageStatus, ProtocolVersion, PublicKey, SecretKey, TransactionHash, TransactionRuntime, + TransactionV1Hash, TransferAddr, TransferV2, URef, KEY_HASH_LENGTH, TRANSFER_ADDR_LENGTH, U128, + U256, U512, UREF_ADDR_LENGTH, }; static KB: usize = 1024; @@ -450,46 +449,26 @@ fn deserialize_u512(b: &mut Bencher) { } fn serialize_contract(b: &mut Bencher) { - let contract = sample_contract(10); + let contract = sample_contract(); b.iter(|| ToBytes::to_bytes(black_box(&contract))); } fn deserialize_contract(b: &mut Bencher) { - let contract = sample_contract(10); + let contract = sample_contract(); let contract_bytes = AddressableEntity::to_bytes(&contract).unwrap(); b.iter(|| AddressableEntity::from_bytes(black_box(&contract_bytes)).unwrap()); } -fn sample_contract(entry_points_len: u8) -> AddressableEntity { - let entry_points = { - let mut tmp = EntryPoints::new_with_default_entry_point(); - (1..entry_points_len).for_each(|i| { - let args = vec![ - Parameter::new("first", CLType::U32), - Parameter::new("Foo", CLType::U32), - ]; - let entry_point = EntryPoint::new( - format!("test-{}", i), - args, - casper_types::CLType::U512, - EntryPointAccess::groups(&["Group 2"]), - EntryPointType::Called, - ); - tmp.add_entry_point(entry_point); - }); - tmp - }; - +fn sample_contract() -> AddressableEntity { AddressableEntity::new( PackageHash::default(), ByteCodeHash::default(), - entry_points, ProtocolVersion::default(), URef::default(), AssociatedKeys::default(), ActionThresholds::default(), MessageTopics::default(), - EntityKind::SmartContract, + EntityKind::SmartContract(TransactionRuntime::VmCasperV1), ) } diff --git a/types/src/addressable_entity.rs b/types/src/addressable_entity.rs index cfc9470c2d..d827d7cef1 100644 --- a/types/src/addressable_entity.rs +++ b/types/src/addressable_entity.rs @@ -5,6 +5,7 @@ pub mod action_thresholds; mod action_type; pub mod associated_keys; +mod entry_points; mod error; mod named_keys; mod weight; @@ -25,8 +26,6 @@ use core::{ fmt::{self, Debug, Display, Formatter}, iter, }; -use num_derive::FromPrimitive; -use num_traits::FromPrimitive; #[cfg(feature = "json-schema")] use crate::SecretKey; @@ -50,6 +49,10 @@ pub use self::{ action_thresholds::ActionThresholds, action_type::ActionType, associated_keys::AssociatedKeys, + entry_points::{ + EntryPoint, EntryPointAccess, EntryPointAddr, EntryPointPayment, EntryPointType, + EntryPointValue, EntryPoints, Parameter, Parameters, DEFAULT_ENTRY_POINT_NAME, + }, error::{ FromAccountHashStrError, SetThresholdFailure, TryFromIntError, TryFromSliceForAccountHashError, @@ -66,9 +69,9 @@ use crate::{ contracts::{Contract, ContractHash}, system::SystemEntityType, uref::{self, URef}, - AccessRights, ApiError, CLType, CLTyped, CLValue, CLValueError, ContextAccessRights, Group, - HashAddr, Key, KeyTag, PackageHash, ProtocolVersion, PublicKey, Tagged, BLAKE2B_DIGEST_LENGTH, - KEY_HASH_LENGTH, + AccessRights, ApiError, CLType, CLTyped, CLValue, CLValueError, ContextAccessRights, HashAddr, + Key, KeyTag, PackageHash, ProtocolVersion, PublicKey, Tagged, TransactionRuntime, + BLAKE2B_DIGEST_LENGTH, KEY_HASH_LENGTH, }; /// Maximum number of distinct user groups. @@ -556,125 +559,6 @@ impl TryFrom<i32> for UpdateKeyFailure { } } -/// Collection of named entry points. -#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] -#[cfg_attr(feature = "datasize", derive(DataSize))] -#[cfg_attr(feature = "json-schema", derive(JsonSchema))] -#[serde(transparent, deny_unknown_fields)] -pub struct EntryPoints( - #[serde(with = "BTreeMapToArray::<String, EntryPoint, EntryPointLabels>")] - BTreeMap<String, EntryPoint>, -); - -impl ToBytes for EntryPoints { - fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> { - self.0.to_bytes() - } - - fn serialized_length(&self) -> usize { - self.0.serialized_length() - } - - fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> { - self.0.write_bytes(writer) - } -} - -impl FromBytes for EntryPoints { - fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (entry_points_map, remainder) = BTreeMap::<String, EntryPoint>::from_bytes(bytes)?; - Ok((EntryPoints(entry_points_map), remainder)) - } -} - -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 { - EntryPoints(BTreeMap::<String, EntryPoint>::new()) - } - - /// Constructs a new `EntryPoints` with a single entry for the default `EntryPoint`. - pub fn new_with_default_entry_point() -> Self { - let mut entry_points = EntryPoints::new(); - let entry_point = EntryPoint::default(); - entry_points.add_entry_point(entry_point); - entry_points - } - - /// Adds new [`EntryPoint`]. - pub fn add_entry_point(&mut self, entry_point: EntryPoint) { - self.0.insert(entry_point.name().to_string(), entry_point); - } - - /// Checks if given [`EntryPoint`] exists. - pub fn has_entry_point(&self, entry_point_name: &str) -> bool { - self.0.contains_key(entry_point_name) - } - - /// Gets an existing [`EntryPoint`] by its name. - pub fn get(&self, entry_point_name: &str) -> Option<&EntryPoint> { - self.0.get(entry_point_name) - } - - /// Returns iterator for existing entry point names. - pub fn keys(&self) -> impl Iterator<Item = &String> { - self.0.keys() - } - - /// Takes all entry points. - pub fn take_entry_points(self) -> Vec<EntryPoint> { - self.0.into_values().collect() - } - - /// Returns the length of the entry points - pub fn len(&self) -> usize { - self.0.len() - } - - /// Checks if the `EntryPoints` is empty. - 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::Caller) - } -} - -impl From<Vec<EntryPoint>> for EntryPoints { - fn from(entry_points: Vec<EntryPoint>) -> EntryPoints { - let entries = entry_points - .into_iter() - .map(|entry_point| (String::from(entry_point.name()), entry_point)) - .collect(); - EntryPoints(entries) - } -} - -struct EntryPointLabels; - -impl KeyValueLabels for EntryPointLabels { - const KEY: &'static str = "name"; - const VALUE: &'static str = "entry_point"; -} - -#[cfg(feature = "json-schema")] -impl KeyValueJsonSchema for EntryPointLabels { - const JSON_SCHEMA_KV_NAME: Option<&'static str> = Some("NamedEntryPoint"); -} - /// Tag for the variants of [`EntityKind`]. #[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize)] #[cfg_attr(feature = "datasize", derive(DataSize))] @@ -750,9 +634,7 @@ impl Distribution<EntityKindTag> for Standard { } } -#[derive( - Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Serialize, Deserialize, -)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] /// The type of Package. @@ -762,8 +644,7 @@ pub enum EntityKind { /// Package associated with an Account hash. Account(AccountHash), /// Packages associated with Wasm stored on chain. - #[default] - SmartContract, + SmartContract(TransactionRuntime), } impl EntityKind { @@ -771,7 +652,7 @@ impl EntityKind { pub fn maybe_account_hash(&self) -> Option<AccountHash> { match self { Self::Account(account_hash) => Some(*account_hash), - Self::SmartContract | Self::System(_) => None, + Self::SmartContract(_) | Self::System(_) => None, } } @@ -779,7 +660,7 @@ impl EntityKind { pub fn associated_keys(&self) -> AssociatedKeys { match self { Self::Account(account_hash) => AssociatedKeys::new(*account_hash, Weight::new(1)), - Self::SmartContract | Self::System(_) => AssociatedKeys::default(), + Self::SmartContract(_) | Self::System(_) => AssociatedKeys::default(), } } @@ -817,7 +698,7 @@ impl Tagged<EntityKindTag> for EntityKind { match self { EntityKind::System(_) => EntityKindTag::System, EntityKind::Account(_) => EntityKindTag::Account, - EntityKind::SmartContract => EntityKindTag::SmartContract, + EntityKind::SmartContract(_) => EntityKindTag::SmartContract, } } } @@ -839,7 +720,9 @@ impl ToBytes for EntityKind { fn serialized_length(&self) -> usize { U8_SERIALIZED_LENGTH + match self { - EntityKind::SmartContract => 0, + EntityKind::SmartContract(transaction_runtime) => { + transaction_runtime.serialized_length() + } EntityKind::System(system_entity_type) => system_entity_type.serialized_length(), EntityKind::Account(account_hash) => account_hash.serialized_length(), } @@ -847,9 +730,9 @@ impl ToBytes for EntityKind { fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> { match self { - EntityKind::SmartContract => { + EntityKind::SmartContract(transaction_runtime) => { writer.push(self.tag()); - Ok(()) + transaction_runtime.write_bytes(writer) } EntityKind::System(system_entity_type) => { writer.push(self.tag()); @@ -875,7 +758,10 @@ impl FromBytes for EntityKind { let (account_hash, remainder) = AccountHash::from_bytes(remainder)?; Ok((EntityKind::Account(account_hash), remainder)) } - EntityKindTag::SmartContract => Ok((EntityKind::SmartContract, remainder)), + EntityKindTag::SmartContract => { + let (transaction_runtime, remainder) = TransactionRuntime::from_bytes(remainder)?; + Ok((EntityKind::SmartContract(transaction_runtime), remainder)) + } } } } @@ -889,8 +775,8 @@ impl Display for EntityKind { EntityKind::Account(account_hash) => { write!(f, "account-entity-kind({})", account_hash) } - EntityKind::SmartContract => { - write!(f, "smart-contract-entity-kind") + EntityKind::SmartContract(transaction_runtime) => { + write!(f, "smart-contract-entity-kind({})", transaction_runtime) } } } @@ -902,7 +788,7 @@ impl Distribution<EntityKind> for Standard { match rng.gen_range(0..=2) { 0 => EntityKind::System(rng.gen()), 1 => EntityKind::Account(rng.gen()), - 2 => EntityKind::SmartContract, + 2 => EntityKind::SmartContract(rng.gen()), _ => unreachable!(), } } @@ -945,7 +831,7 @@ impl EntityAddr { match entity_kind { EntityKind::System(_) => Self::new_system(hash_addr), EntityKind::Account(_) => Self::new_account(hash_addr), - EntityKind::SmartContract => Self::new_smart_contract(hash_addr), + EntityKind::SmartContract(_) => Self::new_smart_contract(hash_addr), } } @@ -981,6 +867,26 @@ impl EntityAddr { Ok(ret) } + /// Returns the common prefix for all v1 EntryPoints. + pub fn entry_points_v1_prefix(&self) -> Result<Vec<u8>, bytesrepr::Error> { + let mut ret = Vec::with_capacity(self.serialized_length() + 2); + ret.push(KeyTag::EntryPoint as u8); + // Current a naked u8, redo to enum + ret.push(0u8); + self.write_bytes(&mut ret)?; + Ok(ret) + } + + /// Returns the common prefix for all v2 EntryPoints. + pub fn entry_points_v2_prefix(&self) -> Result<Vec<u8>, bytesrepr::Error> { + let mut ret = Vec::with_capacity(self.serialized_length() + 2); + ret.push(KeyTag::EntryPoint as u8); + // Current a naked u8, redo to enum + ret.push(1u8); + self.write_bytes(&mut ret)?; + Ok(ret) + } + /// Returns the formatted String representation of the [`EntityAddr`]. pub fn to_formatted_string(&self) -> String { match self { @@ -1156,7 +1062,6 @@ impl Distribution<EntityAddr> for Standard { } /// A NamedKey address. - #[derive(PartialOrd, Ord, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize)] #[cfg_attr(feature = "datasize", derive(DataSize))] #[cfg_attr(feature = "json-schema", derive(JsonSchema))] @@ -1189,7 +1094,12 @@ impl NamedKeyAddr { entry: String, ) -> Result<Self, bytesrepr::Error> { let bytes = entry.to_bytes()?; - let mut hasher = VarBlake2b::new(BLAKE2B_DIGEST_LENGTH).expect("should create hasher"); + let mut hasher = { + match VarBlake2b::new(BLAKE2B_DIGEST_LENGTH) { + Ok(hasher) => hasher, + Err(_) => return Err(bytesrepr::Error::Formatting), + } + }; hasher.update(bytes); // NOTE: Assumed safe as size of `HashAddr` equals to the output provided by hasher. let mut string_bytes = HashAddr::default(); @@ -1478,7 +1388,6 @@ static ADDRESSABLE_ENTITY: Lazy<AddressableEntity> = Lazy::new(|| { let weight = Weight::new(1); let associated_keys = AssociatedKeys::new(account_hash, weight); let action_thresholds = ActionThresholds::new(weight, weight, weight).unwrap(); - let entry_points = EntryPoints::new_with_default_entry_point(); let protocol_version = ProtocolVersion::from_parts(2, 0, 0); let mut message_topics = MessageTopics::default(); message_topics @@ -1489,7 +1398,6 @@ static ADDRESSABLE_ENTITY: Lazy<AddressableEntity> = Lazy::new(|| { entity_kind: EntityKind::Account(account_hash), package_hash, byte_code_hash, - entry_points, main_purse, associated_keys, action_thresholds, @@ -1508,7 +1416,6 @@ pub struct AddressableEntity { byte_code_hash: ByteCodeHash, main_purse: URef, - entry_points: EntryPoints, associated_keys: AssociatedKeys, action_thresholds: ActionThresholds, message_topics: MessageTopics, @@ -1518,7 +1425,6 @@ impl From<AddressableEntity> for ( PackageHash, ByteCodeHash, - EntryPoints, ProtocolVersion, URef, AssociatedKeys, @@ -1529,7 +1435,6 @@ impl From<AddressableEntity> ( entity.package_hash, entity.byte_code_hash, - entity.entry_points, entity.protocol_version, entity.main_purse, entity.associated_keys, @@ -1544,7 +1449,6 @@ impl AddressableEntity { pub fn new( package_hash: PackageHash, byte_code_hash: ByteCodeHash, - entry_points: EntryPoints, protocol_version: ProtocolVersion, main_purse: URef, associated_keys: AssociatedKeys, @@ -1555,7 +1459,6 @@ impl AddressableEntity { AddressableEntity { package_hash, byte_code_hash, - entry_points, protocol_version, main_purse, action_thresholds, @@ -1571,7 +1474,7 @@ impl AddressableEntity { match self.entity_kind { EntityKind::System(_) => EntityAddr::new_system(hash_addr), EntityKind::Account(_) => EntityAddr::new_account(hash_addr), - EntityKind::SmartContract => EntityAddr::new_smart_contract(hash_addr), + EntityKind::SmartContract(_) => EntityAddr::new_smart_contract(hash_addr), } } @@ -1585,16 +1488,6 @@ impl AddressableEntity { self.byte_code_hash } - /// Checks whether there is a method with the given name - pub fn has_entry_point(&self, name: &str) -> bool { - self.entry_points.has_entry_point(name) - } - - /// Returns the type signature for the given `method`. - pub fn entry_point(&self, method: &str) -> Option<&EntryPoint> { - self.entry_points.get(method) - } - /// Get the protocol version this header is targeting. pub fn protocol_version(&self) -> ProtocolVersion { self.protocol_version @@ -1772,21 +1665,11 @@ impl AddressableEntity { total_weight >= *self.action_thresholds().upgrade_management() } - /// Adds new entry point - pub fn add_entry_point<T: Into<String>>(&mut self, entry_point: EntryPoint) { - self.entry_points.add_entry_point(entry_point); - } - /// Addr for accessing wasm bytes pub fn byte_code_addr(&self) -> HashAddr { self.byte_code_hash.value() } - /// Returns immutable reference to methods - pub fn entry_points(&self) -> &EntryPoints { - &self.entry_points - } - /// Returns a reference to the message topics pub fn message_topics(&self) -> &MessageTopics { &self.message_topics @@ -1839,7 +1722,7 @@ impl AddressableEntity { EntityKind::Account(_) => { Key::addressable_entity_key(EntityKindTag::Account, entity_hash) } - EntityKind::SmartContract => { + EntityKind::SmartContract(_) => { Key::addressable_entity_key(EntityKindTag::SmartContract, entity_hash) } } @@ -1858,25 +1741,6 @@ impl AddressableEntity { 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, - entry_points, - protocol_version: self.protocol_version, - main_purse: self.main_purse, - associated_keys: self.associated_keys, - action_thresholds: self.action_thresholds, - message_topics: self.message_topics, - entity_kind: self.entity_kind, - } - } - // This method is not intended to be used by third party crates. #[doc(hidden)] #[cfg(feature = "json-schema")] @@ -1890,7 +1754,6 @@ impl ToBytes for AddressableEntity { let mut result = bytesrepr::allocate_buffer(self)?; self.package_hash().write_bytes(&mut result)?; self.byte_code_hash().write_bytes(&mut result)?; - self.entry_points().write_bytes(&mut result)?; self.protocol_version().write_bytes(&mut result)?; self.main_purse().write_bytes(&mut result)?; self.associated_keys().write_bytes(&mut result)?; @@ -1901,8 +1764,7 @@ impl ToBytes for AddressableEntity { } fn serialized_length(&self) -> usize { - ToBytes::serialized_length(&self.entry_points) - + ToBytes::serialized_length(&self.package_hash) + ToBytes::serialized_length(&self.package_hash) + ToBytes::serialized_length(&self.byte_code_hash) + ToBytes::serialized_length(&self.protocol_version) + ToBytes::serialized_length(&self.main_purse) @@ -1915,7 +1777,6 @@ impl ToBytes for AddressableEntity { fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> { self.package_hash().write_bytes(writer)?; self.byte_code_hash().write_bytes(writer)?; - self.entry_points().write_bytes(writer)?; self.protocol_version().write_bytes(writer)?; self.main_purse().write_bytes(writer)?; self.associated_keys().write_bytes(writer)?; @@ -1930,7 +1791,6 @@ impl FromBytes for AddressableEntity { fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { let (package_hash, bytes) = PackageHash::from_bytes(bytes)?; let (byte_code_hash, bytes) = ByteCodeHash::from_bytes(bytes)?; - let (entry_points, bytes) = EntryPoints::from_bytes(bytes)?; let (protocol_version, bytes) = ProtocolVersion::from_bytes(bytes)?; let (main_purse, bytes) = URef::from_bytes(bytes)?; let (associated_keys, bytes) = AssociatedKeys::from_bytes(bytes)?; @@ -1941,7 +1801,6 @@ impl FromBytes for AddressableEntity { AddressableEntity { package_hash, byte_code_hash, - entry_points, protocol_version, main_purse, associated_keys, @@ -1957,7 +1816,6 @@ impl FromBytes for AddressableEntity { impl Default for AddressableEntity { fn default() -> Self { AddressableEntity { - entry_points: EntryPoints::new_with_default_entry_point(), byte_code_hash: [0; KEY_HASH_LENGTH].into(), package_hash: [0; KEY_HASH_LENGTH].into(), protocol_version: ProtocolVersion::V1_0_0, @@ -1965,7 +1823,7 @@ impl Default for AddressableEntity { action_thresholds: ActionThresholds::default(), associated_keys: AssociatedKeys::default(), message_topics: MessageTopics::default(), - entity_kind: EntityKind::SmartContract, + entity_kind: EntityKind::SmartContract(TransactionRuntime::VmCasperV1), } } } @@ -1975,13 +1833,12 @@ impl From<Contract> for AddressableEntity { AddressableEntity::new( PackageHash::new(value.contract_package_hash().value()), ByteCodeHash::new(value.contract_wasm_hash().value()), - value.entry_points().clone(), value.protocol_version(), URef::default(), AssociatedKeys::default(), ActionThresholds::default(), MessageTopics::default(), - EntityKind::SmartContract, + EntityKind::SmartContract(TransactionRuntime::VmCasperV1), ) } } @@ -1991,7 +1848,6 @@ impl From<Account> for AddressableEntity { AddressableEntity::new( PackageHash::default(), ByteCodeHash::new([0u8; 32]), - EntryPoints::new(), ProtocolVersion::default(), value.main_purse(), value.associated_keys().clone().into(), @@ -2002,383 +1858,6 @@ impl From<Account> for AddressableEntity { } } -/// Context of method execution -/// -/// Most significant bit represents version i.e. -/// - 0b0 -> 0.x/1.x (session & contracts) -/// - 0b1 -> 2.x and later (introduced installer, utility entry points) -#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, FromPrimitive)] -#[cfg_attr(feature = "datasize", derive(DataSize))] -#[cfg_attr(feature = "json-schema", derive(JsonSchema))] -pub enum EntryPointType { - /// Runs using the calling entity's context. - /// In v1.x this was used for both "session" code run using the originating - /// Account's context, and also for "StoredSession" code that ran in the - /// caller's context. While this made systemic sense due to the way the runtime - /// context nesting works, this dual usage was very confusing to most human beings. - /// - /// In v2.x the renamed Caller variant is exclusively used for wasm run using the initiating - /// account entity's context. Previously installed 1.x stored session code should - /// continue to work as the binary value matches but we no longer allow such logic - /// to be upgraded, nor do we allow new stored session to be installed. - Caller = 0b00000000, - /// Runs using the called entity's context. - Called = 0b00000001, - /// Extract a subset of bytecode and installs it as a new smart contract. - /// Runs using the called entity's context. - Factory = 0b10000000, -} - -impl EntryPointType { - /// Checks if entry point type is introduced before 2.0. - /// - /// This method checks if there is a bit pattern for entry point types introduced in 2.0. - /// - /// If this bit is missing, that means given entry point type was defined in pre-2.0 world. - pub fn is_legacy_pattern(&self) -> bool { - (*self as u8) & 0b10000000 == 0 - } - - /// Get the bit pattern. - 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::Caller => true, - EntryPointType::Called | EntryPointType::Factory => false, - } - } -} - -impl ToBytes for EntryPointType { - fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> { - self.bits().to_bytes() - } - - fn serialized_length(&self) -> usize { - 1 - } - - fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> { - writer.push(self.bits()); - Ok(()) - } -} - -impl FromBytes for EntryPointType { - fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (value, bytes) = u8::from_bytes(bytes)?; - let entry_point_type = - EntryPointType::from_u8(value).ok_or(bytesrepr::Error::Formatting)?; - Ok((entry_point_type, bytes)) - } -} - -/// Default name for an entry point. -pub const DEFAULT_ENTRY_POINT_NAME: &str = "call"; - -/// Name for an installer entry point. -pub const INSTALL_ENTRY_POINT_NAME: &str = "install"; - -/// Name for an upgrade entry point. -pub const UPGRADE_ENTRY_POINT_NAME: &str = "upgrade"; - -/// Collection of entry point parameters. -pub type Parameters = Vec<Parameter>; - -/// Type signature of a method. Order of arguments matter since can be -/// referenced by index as well as name. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[cfg_attr(feature = "datasize", derive(DataSize))] -#[cfg_attr(feature = "json-schema", derive(JsonSchema))] -pub struct EntryPoint { - name: String, - args: Parameters, - ret: CLType, - access: EntryPointAccess, - entry_point_type: EntryPointType, -} - -impl From<EntryPoint> for (String, Parameters, CLType, EntryPointAccess, EntryPointType) { - fn from(entry_point: EntryPoint) -> Self { - ( - entry_point.name, - entry_point.args, - entry_point.ret, - entry_point.access, - entry_point.entry_point_type, - ) - } -} - -impl EntryPoint { - /// `EntryPoint` constructor. - pub fn new<T: Into<String>>( - name: T, - args: Parameters, - ret: CLType, - access: EntryPointAccess, - entry_point_type: EntryPointType, - ) -> Self { - EntryPoint { - name: name.into(), - args, - ret, - access, - entry_point_type, - } - } - - /// Create a default [`EntryPoint`] with specified name. - pub fn default_with_name<T: Into<String>>(name: T) -> Self { - EntryPoint { - name: name.into(), - ..Default::default() - } - } - - /// Get name. - pub fn name(&self) -> &str { - &self.name - } - - /// Get access enum. - pub fn access(&self) -> &EntryPointAccess { - &self.access - } - - /// Get the arguments for this method. - pub fn args(&self) -> &[Parameter] { - self.args.as_slice() - } - - /// Get the return type. - pub fn ret(&self) -> &CLType { - &self.ret - } - - /// Obtains entry point - pub fn entry_point_type(&self) -> EntryPointType { - self.entry_point_type - } -} - -impl Default for EntryPoint { - /// constructor for a public session `EntryPoint` that takes no args and returns `Unit` - fn default() -> Self { - EntryPoint { - name: DEFAULT_ENTRY_POINT_NAME.to_string(), - args: Vec::new(), - ret: CLType::Unit, - access: EntryPointAccess::Public, - entry_point_type: EntryPointType::Caller, - } - } -} - -impl ToBytes for EntryPoint { - fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> { - let mut buffer = bytesrepr::allocate_buffer(self)?; - self.write_bytes(&mut buffer)?; - Ok(buffer) - } - - fn serialized_length(&self) -> usize { - self.name.serialized_length() - + self.args.serialized_length() - + self.ret.serialized_length() - + self.access.serialized_length() - + self.entry_point_type.serialized_length() - } - - fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> { - self.name.write_bytes(writer)?; - self.args.write_bytes(writer)?; - self.ret.append_bytes(writer)?; - self.access.write_bytes(writer)?; - self.entry_point_type.write_bytes(writer)?; - Ok(()) - } -} - -impl FromBytes for EntryPoint { - fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (name, bytes) = String::from_bytes(bytes)?; - let (args, bytes) = Vec::<Parameter>::from_bytes(bytes)?; - let (ret, bytes) = CLType::from_bytes(bytes)?; - let (access, bytes) = EntryPointAccess::from_bytes(bytes)?; - let (entry_point_type, bytes) = EntryPointType::from_bytes(bytes)?; - - Ok(( - EntryPoint { - name, - args, - ret, - access, - entry_point_type, - }, - bytes, - )) - } -} - -/// Enum describing the possible access control options for a contract entry -/// point (method). -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[cfg_attr(feature = "datasize", derive(DataSize))] -#[cfg_attr(feature = "json-schema", derive(JsonSchema))] -pub enum EntryPointAccess { - /// Anyone can call this method (no access controls). - Public, - /// Only users from the listed groups may call this method. Note: if the - /// list is empty then this method is not callable from outside the - /// contract. - Groups(Vec<Group>), - /// Can't be accessed directly but are kept in the derived wasm bytes. - Template, -} - -const ENTRYPOINTACCESS_PUBLIC_TAG: u8 = 1; -const ENTRYPOINTACCESS_GROUPS_TAG: u8 = 2; -const ENTRYPOINTACCESS_ABSTRACT_TAG: u8 = 3; - -impl EntryPointAccess { - /// Constructor for access granted to only listed groups. - pub fn groups(labels: &[&str]) -> Self { - let list: Vec<Group> = labels - .iter() - .map(|s| Group::new(String::from(*s))) - .collect(); - EntryPointAccess::Groups(list) - } -} - -impl ToBytes for EntryPointAccess { - fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> { - let mut result = bytesrepr::allocate_buffer(self)?; - - match self { - EntryPointAccess::Public => { - result.push(ENTRYPOINTACCESS_PUBLIC_TAG); - } - EntryPointAccess::Groups(groups) => { - result.push(ENTRYPOINTACCESS_GROUPS_TAG); - result.append(&mut groups.to_bytes()?); - } - EntryPointAccess::Template => { - result.push(ENTRYPOINTACCESS_ABSTRACT_TAG); - } - } - Ok(result) - } - - fn serialized_length(&self) -> usize { - match self { - EntryPointAccess::Public => 1, - EntryPointAccess::Groups(groups) => 1 + groups.serialized_length(), - EntryPointAccess::Template => 1, - } - } - - fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> { - match self { - EntryPointAccess::Public => { - writer.push(ENTRYPOINTACCESS_PUBLIC_TAG); - } - EntryPointAccess::Groups(groups) => { - writer.push(ENTRYPOINTACCESS_GROUPS_TAG); - groups.write_bytes(writer)?; - } - EntryPointAccess::Template => { - writer.push(ENTRYPOINTACCESS_ABSTRACT_TAG); - } - } - Ok(()) - } -} - -impl FromBytes for EntryPointAccess { - fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (tag, bytes) = u8::from_bytes(bytes)?; - - match tag { - ENTRYPOINTACCESS_PUBLIC_TAG => Ok((EntryPointAccess::Public, bytes)), - ENTRYPOINTACCESS_GROUPS_TAG => { - let (groups, bytes) = Vec::<Group>::from_bytes(bytes)?; - let result = EntryPointAccess::Groups(groups); - Ok((result, bytes)) - } - ENTRYPOINTACCESS_ABSTRACT_TAG => Ok((EntryPointAccess::Template, bytes)), - _ => Err(bytesrepr::Error::Formatting), - } - } -} - -/// Parameter to a method -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[cfg_attr(feature = "datasize", derive(DataSize))] -#[cfg_attr(feature = "json-schema", derive(JsonSchema))] -pub struct Parameter { - name: String, - cl_type: CLType, -} - -impl Parameter { - /// `Parameter` constructor. - pub fn new<T: Into<String>>(name: T, cl_type: CLType) -> Self { - Parameter { - name: name.into(), - cl_type, - } - } - - /// Get the type of this argument. - pub fn cl_type(&self) -> &CLType { - &self.cl_type - } - - /// Get a reference to the parameter's name. - pub fn name(&self) -> &str { - &self.name - } -} - -impl From<Parameter> for (String, CLType) { - fn from(parameter: Parameter) -> Self { - (parameter.name, parameter.cl_type) - } -} - -impl ToBytes for Parameter { - fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> { - let mut result = ToBytes::to_bytes(&self.name)?; - self.cl_type.append_bytes(&mut result)?; - - Ok(result) - } - - fn serialized_length(&self) -> usize { - ToBytes::serialized_length(&self.name) + self.cl_type.serialized_length() - } - - fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> { - self.name.write_bytes(writer)?; - self.cl_type.append_bytes(writer) - } -} - -impl FromBytes for Parameter { - fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { - let (name, bytes) = String::from_bytes(bytes)?; - let (cl_type, bytes) = CLType::from_bytes(bytes)?; - - Ok((Parameter { name, cl_type }, bytes)) - } -} - #[cfg(test)] mod tests { use super::*; @@ -2526,14 +2005,13 @@ mod tests { let contract = AddressableEntity::new( PackageHash::new([254; 32]), ByteCodeHash::new([253; 32]), - EntryPoints::new_with_default_entry_point(), ProtocolVersion::V1_0_0, MAIN_PURSE, associated_keys, ActionThresholds::new(Weight::new(1), Weight::new(1), Weight::new(1)) .expect("should create thresholds"), MessageTopics::default(), - EntityKind::SmartContract, + EntityKind::SmartContract(TransactionRuntime::VmCasperV1), ); let access_rights = contract.extract_access_rights(entity_hash, &named_keys); let expected_uref = URef::new([42; UREF_ADDR_LENGTH], AccessRights::READ_ADD_WRITE); diff --git a/types/src/addressable_entity/entry_points.rs b/types/src/addressable_entity/entry_points.rs new file mode 100644 index 0000000000..ffa07a8911 --- /dev/null +++ b/types/src/addressable_entity/entry_points.rs @@ -0,0 +1,955 @@ +use core::fmt::{Debug, Display, Formatter}; + +use alloc::{ + collections::BTreeMap, + format, + string::{String, ToString}, + vec::Vec, +}; + +use blake2::{ + digest::{Update, VariableOutput}, + VarBlake2b, +}; + +#[cfg(feature = "datasize")] +use datasize::DataSize; +use num_derive::FromPrimitive; +use num_traits::FromPrimitive; +#[cfg(any(feature = "testing", test))] +use rand::{ + distributions::{Distribution, Standard}, + Rng, +}; +#[cfg(feature = "json-schema")] +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use serde_json::from_str; +#[cfg(feature = "json-schema")] +use serde_map_to_array::KeyValueJsonSchema; +use serde_map_to_array::{BTreeMapToArray, KeyValueLabels}; + +use crate::{ + addressable_entity::FromStrError, + bytesrepr, + bytesrepr::{Error, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}, + checksummed_hex, CLType, EntityAddr, Group, HashAddr, BLAKE2B_DIGEST_LENGTH, KEY_HASH_LENGTH, +}; + +const V1_ENTRY_POINT_TAG: u8 = 0; +const V2_ENTRY_POINT_TAG: u8 = 1; + +const V1_ENTRY_POINT_PREFIX: &str = "entry-point-v1-"; +const V2_ENTRY_POINT_PREFIX: &str = "entry-point-v2-"; + +/// Context of method execution +/// +/// Most significant bit represents version i.e. +/// - 0b0 -> 0.x/1.x (session & contracts) +/// - 0b1 -> 2.x and later (introduced installer, utility entry points) +#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, FromPrimitive)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +pub enum EntryPointType { + /// Runs using the calling entity's context. + /// In v1.x this was used for both "session" code run using the originating + /// Account's context, and also for "StoredSession" code that ran in the + /// caller's context. While this made systemic sense due to the way the runtime + /// context nesting works, this dual usage was very confusing to most human beings. + /// + /// In v2.x the renamed Caller variant is exclusively used for wasm run using the initiating + /// account entity's context. Previously installed 1.x stored session code should + /// continue to work as the binary value matches but we no longer allow such logic + /// to be upgraded, nor do we allow new stored session to be installed. + Caller = 0b00000000, + /// Runs using the called entity's context. + Called = 0b00000001, + /// Extract a subset of bytecode and installs it as a new smart contract. + /// Runs using the called entity's context. + Factory = 0b10000000, +} + +impl EntryPointType { + /// Checks if entry point type is introduced before 2.0. + /// + /// This method checks if there is a bit pattern for entry point types introduced in 2.0. + /// + /// If this bit is missing, that means given entry point type was defined in pre-2.0 world. + pub fn is_legacy_pattern(&self) -> bool { + (*self as u8) & 0b10000000 == 0 + } + + /// Get the bit pattern. + 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::Caller => true, + EntryPointType::Called | EntryPointType::Factory => false, + } + } +} + +impl ToBytes for EntryPointType { + fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> { + self.bits().to_bytes() + } + + fn serialized_length(&self) -> usize { + 1 + } + + fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> { + writer.push(self.bits()); + Ok(()) + } +} + +impl FromBytes for EntryPointType { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (value, bytes) = u8::from_bytes(bytes)?; + let entry_point_type = + EntryPointType::from_u8(value).ok_or(bytesrepr::Error::Formatting)?; + Ok((entry_point_type, bytes)) + } +} + +/// Default name for an entry point. +pub const DEFAULT_ENTRY_POINT_NAME: &str = "call"; + +/// Collection of entry point parameters. +pub type Parameters = Vec<Parameter>; + +/// An enum specifying who pays for the invocation and execution of the entrypoint. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +#[repr(u8)] +pub enum EntryPointPayment { + /// The caller must cover cost + Caller = 0, + /// Will cover cost to execute self but not cost of any subsequent invoked contracts + SelfOnly = 1, + /// will cover cost to execute self and the cost of any subsequent invoked contracts + SelfOnward = 2, +} + +impl ToBytes for EntryPointPayment { + fn to_bytes(&self) -> Result<Vec<u8>, Error> { + let mut result = bytesrepr::unchecked_allocate_buffer(self); + self.write_bytes(&mut result)?; + Ok(result) + } + + fn serialized_length(&self) -> usize { + U8_SERIALIZED_LENGTH + } + + fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), Error> { + writer.push(*self as u8); + Ok(()) + } +} + +impl FromBytes for EntryPointPayment { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> { + let (id, rem) = u8::from_bytes(bytes)?; + let tag = match id { + tag if tag == EntryPointPayment::Caller as u8 => EntryPointPayment::Caller, + tag if tag == EntryPointPayment::SelfOnly as u8 => EntryPointPayment::SelfOnly, + tag if tag == EntryPointPayment::SelfOnward as u8 => EntryPointPayment::SelfOnward, + _ => return Err(Error::Formatting), + }; + Ok((tag, rem)) + } +} + +/// Type signature of a method. Order of arguments matter since can be +/// referenced by index as well as name. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +pub struct EntryPoint { + name: String, + args: Parameters, + ret: CLType, + access: EntryPointAccess, + entry_point_type: EntryPointType, + entry_point_payment: EntryPointPayment, +} + +impl From<EntryPoint> + for ( + String, + Parameters, + CLType, + EntryPointAccess, + EntryPointType, + EntryPointPayment, + ) +{ + fn from(entry_point: EntryPoint) -> Self { + ( + entry_point.name, + entry_point.args, + entry_point.ret, + entry_point.access, + entry_point.entry_point_type, + entry_point.entry_point_payment, + ) + } +} + +impl EntryPoint { + /// `EntryPoint` constructor. + pub fn new<T: Into<String>>( + name: T, + args: Parameters, + ret: CLType, + access: EntryPointAccess, + entry_point_type: EntryPointType, + entry_point_payment: EntryPointPayment, + ) -> Self { + EntryPoint { + name: name.into(), + args, + ret, + access, + entry_point_type, + entry_point_payment, + } + } + + /// Create a default [`EntryPoint`] with specified name. + pub fn default_with_name<T: Into<String>>(name: T) -> Self { + EntryPoint { + name: name.into(), + ..Default::default() + } + } + + /// Get name. + pub fn name(&self) -> &str { + &self.name + } + + /// Get access enum. + pub fn access(&self) -> &EntryPointAccess { + &self.access + } + + /// Get the arguments for this method. + pub fn args(&self) -> &[Parameter] { + self.args.as_slice() + } + + /// Get the return type. + pub fn ret(&self) -> &CLType { + &self.ret + } + + /// Obtains entry point + pub fn entry_point_type(&self) -> EntryPointType { + self.entry_point_type + } +} + +impl Default for EntryPoint { + /// constructor for a public session `EntryPoint` that takes no args and returns `Unit` + fn default() -> Self { + EntryPoint { + name: DEFAULT_ENTRY_POINT_NAME.to_string(), + args: Vec::new(), + ret: CLType::Unit, + access: EntryPointAccess::Public, + entry_point_type: EntryPointType::Caller, + entry_point_payment: EntryPointPayment::Caller, + } + } +} + +impl ToBytes for EntryPoint { + fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> { + let mut buffer = bytesrepr::allocate_buffer(self)?; + self.write_bytes(&mut buffer)?; + Ok(buffer) + } + + fn serialized_length(&self) -> usize { + self.name.serialized_length() + + self.args.serialized_length() + + self.ret.serialized_length() + + self.access.serialized_length() + + self.entry_point_type.serialized_length() + + self.entry_point_payment.serialized_length() + } + + fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> { + self.name.write_bytes(writer)?; + self.args.write_bytes(writer)?; + self.ret.append_bytes(writer)?; + self.access.write_bytes(writer)?; + self.entry_point_type.write_bytes(writer)?; + self.entry_point_payment.write_bytes(writer)?; + Ok(()) + } +} + +impl FromBytes for EntryPoint { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (name, bytes) = String::from_bytes(bytes)?; + let (args, bytes) = Vec::<Parameter>::from_bytes(bytes)?; + let (ret, bytes) = CLType::from_bytes(bytes)?; + let (access, bytes) = EntryPointAccess::from_bytes(bytes)?; + let (entry_point_type, bytes) = EntryPointType::from_bytes(bytes)?; + let (entry_point_payment, bytes) = EntryPointPayment::from_bytes(bytes)?; + + Ok(( + EntryPoint { + name, + args, + ret, + access, + entry_point_type, + entry_point_payment, + }, + bytes, + )) + } +} + +/// Enum describing the possible access control options for a contract entry +/// point (method). +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +pub enum EntryPointAccess { + /// Anyone can call this method (no access controls). + Public, + /// Only users from the listed groups may call this method. Note: if the + /// list is empty then this method is not callable from outside the + /// contract. + Groups(Vec<Group>), + /// Can't be accessed directly but are kept in the derived wasm bytes. + Template, +} + +const ENTRYPOINTACCESS_PUBLIC_TAG: u8 = 1; +const ENTRYPOINTACCESS_GROUPS_TAG: u8 = 2; +const ENTRYPOINTACCESS_ABSTRACT_TAG: u8 = 3; + +impl EntryPointAccess { + /// Constructor for access granted to only listed groups. + pub fn groups(labels: &[&str]) -> Self { + let list: Vec<Group> = labels + .iter() + .map(|s| Group::new(String::from(*s))) + .collect(); + EntryPointAccess::Groups(list) + } +} + +impl ToBytes for EntryPointAccess { + fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> { + let mut result = bytesrepr::allocate_buffer(self)?; + + match self { + EntryPointAccess::Public => { + result.push(ENTRYPOINTACCESS_PUBLIC_TAG); + } + EntryPointAccess::Groups(groups) => { + result.push(ENTRYPOINTACCESS_GROUPS_TAG); + result.append(&mut groups.to_bytes()?); + } + EntryPointAccess::Template => { + result.push(ENTRYPOINTACCESS_ABSTRACT_TAG); + } + } + Ok(result) + } + + fn serialized_length(&self) -> usize { + match self { + EntryPointAccess::Public => 1, + EntryPointAccess::Groups(groups) => 1 + groups.serialized_length(), + EntryPointAccess::Template => 1, + } + } + + fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> { + match self { + EntryPointAccess::Public => { + writer.push(ENTRYPOINTACCESS_PUBLIC_TAG); + } + EntryPointAccess::Groups(groups) => { + writer.push(ENTRYPOINTACCESS_GROUPS_TAG); + groups.write_bytes(writer)?; + } + EntryPointAccess::Template => { + writer.push(ENTRYPOINTACCESS_ABSTRACT_TAG); + } + } + Ok(()) + } +} + +impl FromBytes for EntryPointAccess { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (tag, bytes) = u8::from_bytes(bytes)?; + + match tag { + ENTRYPOINTACCESS_PUBLIC_TAG => Ok((EntryPointAccess::Public, bytes)), + ENTRYPOINTACCESS_GROUPS_TAG => { + let (groups, bytes) = Vec::<Group>::from_bytes(bytes)?; + let result = EntryPointAccess::Groups(groups); + Ok((result, bytes)) + } + ENTRYPOINTACCESS_ABSTRACT_TAG => Ok((EntryPointAccess::Template, bytes)), + _ => Err(bytesrepr::Error::Formatting), + } + } +} + +/// Parameter to a method +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +pub struct Parameter { + name: String, + cl_type: CLType, +} + +impl Parameter { + /// `Parameter` constructor. + pub fn new<T: Into<String>>(name: T, cl_type: CLType) -> Self { + Parameter { + name: name.into(), + cl_type, + } + } + + /// Get the type of this argument. + pub fn cl_type(&self) -> &CLType { + &self.cl_type + } + + /// Get a reference to the parameter's name. + pub fn name(&self) -> &str { + &self.name + } +} + +impl From<Parameter> for (String, CLType) { + fn from(parameter: Parameter) -> Self { + (parameter.name, parameter.cl_type) + } +} + +impl ToBytes for Parameter { + fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> { + let mut result = ToBytes::to_bytes(&self.name)?; + self.cl_type.append_bytes(&mut result)?; + + Ok(result) + } + + fn serialized_length(&self) -> usize { + ToBytes::serialized_length(&self.name) + self.cl_type.serialized_length() + } + + fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> { + self.name.write_bytes(writer)?; + self.cl_type.append_bytes(writer) + } +} + +impl FromBytes for Parameter { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (name, bytes) = String::from_bytes(bytes)?; + let (cl_type, bytes) = CLType::from_bytes(bytes)?; + + Ok((Parameter { name, cl_type }, bytes)) + } +} + +/// Collection of named entry points. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +#[serde(transparent, deny_unknown_fields)] +pub struct EntryPoints( + #[serde(with = "BTreeMapToArray::<String, EntryPoint, EntryPointLabels>")] + BTreeMap<String, EntryPoint>, +); + +impl ToBytes for EntryPoints { + fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> { + self.0.to_bytes() + } + + fn serialized_length(&self) -> usize { + self.0.serialized_length() + } + + fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> { + self.0.write_bytes(writer) + } +} + +impl FromBytes for EntryPoints { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (entry_points_map, remainder) = BTreeMap::<String, EntryPoint>::from_bytes(bytes)?; + Ok((EntryPoints(entry_points_map), remainder)) + } +} + +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 { + EntryPoints(BTreeMap::<String, EntryPoint>::new()) + } + + /// Constructs a new `EntryPoints` with a single entry for the default `EntryPoint`. + pub fn new_with_default_entry_point() -> Self { + let mut entry_points = EntryPoints::new(); + let entry_point = EntryPoint::default(); + entry_points.add_entry_point(entry_point); + entry_points + } + + /// Adds new [`EntryPoint`]. + pub fn add_entry_point(&mut self, entry_point: EntryPoint) { + self.0.insert(entry_point.name().to_string(), entry_point); + } + + /// Checks if given [`EntryPoint`] exists. + pub fn has_entry_point(&self, entry_point_name: &str) -> bool { + self.0.contains_key(entry_point_name) + } + + /// Gets an existing [`EntryPoint`] by its name. + pub fn get(&self, entry_point_name: &str) -> Option<&EntryPoint> { + self.0.get(entry_point_name) + } + + /// Returns iterator for existing entry point names. + pub fn keys(&self) -> impl Iterator<Item = &String> { + self.0.keys() + } + + /// Takes all entry points. + pub fn take_entry_points(self) -> Vec<EntryPoint> { + self.0.into_values().collect() + } + + /// Returns the length of the entry points + pub fn len(&self) -> usize { + self.0.len() + } + + /// Checks if the `EntryPoints` is empty. + 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::Caller) + } +} + +impl From<Vec<EntryPoint>> for EntryPoints { + fn from(entry_points: Vec<EntryPoint>) -> EntryPoints { + let entries = entry_points + .into_iter() + .map(|entry_point| (String::from(entry_point.name()), entry_point)) + .collect(); + EntryPoints(entries) + } +} + +struct EntryPointLabels; + +impl KeyValueLabels for EntryPointLabels { + const KEY: &'static str = "name"; + const VALUE: &'static str = "entry_point"; +} + +#[cfg(feature = "json-schema")] +impl KeyValueJsonSchema for EntryPointLabels { + const JSON_SCHEMA_KV_NAME: Option<&'static str> = Some("NamedEntryPoint"); +} + +/// The entry point for the V2 Casper VM. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +pub struct EntryPointV2 { + /// The selector. + pub function_index: u32, + /// The flags. + pub flags: u32, +} + +impl ToBytes for EntryPointV2 { + fn to_bytes(&self) -> Result<Vec<u8>, Error> { + let mut buffer = bytesrepr::allocate_buffer(self)?; + self.write_bytes(&mut buffer)?; + Ok(buffer) + } + + fn serialized_length(&self) -> usize { + self.function_index.serialized_length() + self.flags.serialized_length() + } + + fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), Error> { + writer.append(&mut self.function_index.to_bytes()?); + writer.append(&mut self.flags.to_bytes()?); + Ok(()) + } +} + +impl FromBytes for EntryPointV2 { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> { + let (function_index, remainder) = u32::from_bytes(bytes)?; + let (flags, remainder) = u32::from_bytes(remainder)?; + Ok(( + EntryPointV2 { + function_index, + flags, + }, + remainder, + )) + } +} + +/// The entry point address. +#[derive(PartialOrd, Ord, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +pub enum EntryPointAddr { + /// The address for a V1 Entrypoint. + VmCasperV1 { + /// The addr of the entity. + entity_addr: EntityAddr, + /// The 32 byte hash of the name of the entry point + name_bytes: [u8; KEY_HASH_LENGTH], + }, + /// The address for a V2 entrypoint + VmCasperV2 { + /// The addr of the entity. + entity_addr: EntityAddr, + /// The selector. + selector: u32, + }, +} + +impl EntryPointAddr { + /// Returns a `VmCasperV1` variant of the entry point address. + pub fn new_v1_entry_point_addr( + entity_addr: EntityAddr, + name: &str, + ) -> Result<Self, bytesrepr::Error> { + let bytes = name.to_bytes()?; + let mut hasher = { + match VarBlake2b::new(BLAKE2B_DIGEST_LENGTH) { + Ok(hasher) => hasher, + Err(_) => return Err(bytesrepr::Error::Formatting), + } + }; + hasher.update(bytes); + // NOTE: Assumed safe as size of `HashAddr` equals to the output provided by hasher. + let mut name_bytes = HashAddr::default(); + hasher.finalize_variable(|hash| name_bytes.clone_from_slice(hash)); + Ok(Self::VmCasperV1 { + entity_addr, + name_bytes, + }) + } + + /// Returns a `VmCasperV2` variant of the entry point address. + pub const fn new_v2_entry_point_addr(entity_addr: EntityAddr, selector: u32) -> Self { + Self::VmCasperV2 { + entity_addr, + selector, + } + } + + /// Returns the encapsulated [`EntityAddr`]. + pub fn entity_addr(&self) -> EntityAddr { + match self { + EntryPointAddr::VmCasperV1 { entity_addr, .. } => *entity_addr, + EntryPointAddr::VmCasperV2 { entity_addr, .. } => *entity_addr, + } + } + + /// Returns the formatted String representation of the [`EntryPointAddr`]. + pub fn to_formatted_string(&self) -> String { + format!("{}", self) + } + + /// Returns the address from the formatted string. + pub fn from_formatted_str(input: &str) -> Result<Self, FromStrError> { + if let Some(entry_point_v1) = input.strip_prefix(V1_ENTRY_POINT_PREFIX) { + if let Some((entity_addr_str, string_bytes_str)) = entry_point_v1.rsplit_once('-') { + let entity_addr = EntityAddr::from_formatted_str(entity_addr_str)?; + let string_bytes = + checksummed_hex::decode(string_bytes_str).map_err(FromStrError::Hex)?; + let (name_bytes, _) = + FromBytes::from_vec(string_bytes).map_err(FromStrError::BytesRepr)?; + return Ok(Self::VmCasperV1 { + entity_addr, + name_bytes, + }); + } + } + + if let Some(entry_point_v2) = input.strip_prefix(V2_ENTRY_POINT_PREFIX) { + if let Some((entity_addr_str, selector_str)) = entry_point_v2.rsplit_once('-') { + let entity_addr = EntityAddr::from_formatted_str(entity_addr_str)?; + let selector: u32 = from_str(selector_str) + .map_err(|_| FromStrError::BytesRepr(Error::Formatting))?; + return Ok(Self::VmCasperV2 { + entity_addr, + selector, + }); + } + } + + Err(FromStrError::InvalidPrefix) + } +} + +impl ToBytes for EntryPointAddr { + fn to_bytes(&self) -> Result<Vec<u8>, Error> { + let mut buffer = bytesrepr::allocate_buffer(self)?; + match self { + EntryPointAddr::VmCasperV1 { + entity_addr, + name_bytes: named_bytes, + } => { + buffer.insert(0, V1_ENTRY_POINT_TAG); + buffer.append(&mut entity_addr.to_bytes()?); + buffer.append(&mut named_bytes.to_bytes()?); + } + EntryPointAddr::VmCasperV2 { + entity_addr, + selector, + } => { + buffer.insert(0, V2_ENTRY_POINT_TAG); + buffer.append(&mut entity_addr.to_bytes()?); + buffer.append(&mut selector.to_bytes()?); + } + } + Ok(buffer) + } + + fn serialized_length(&self) -> usize { + U8_SERIALIZED_LENGTH + + match self { + EntryPointAddr::VmCasperV1 { + entity_addr, + name_bytes: named_bytes, + } => entity_addr.serialized_length() + named_bytes.serialized_length(), + EntryPointAddr::VmCasperV2 { + entity_addr, + selector, + } => entity_addr.serialized_length() + selector.serialized_length(), + } + } +} + +impl FromBytes for EntryPointAddr { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> { + let (tag, bytes) = u8::from_bytes(bytes)?; + match tag { + V1_ENTRY_POINT_TAG => { + let (entity_addr, bytes) = EntityAddr::from_bytes(bytes)?; + let (name_bytes, bytes) = FromBytes::from_bytes(bytes)?; + Ok(( + Self::VmCasperV1 { + entity_addr, + name_bytes, + }, + bytes, + )) + } + V2_ENTRY_POINT_TAG => { + let (entity_addr, bytes) = EntityAddr::from_bytes(bytes)?; + let (selector, bytes) = u32::from_bytes(bytes)?; + Ok(( + Self::VmCasperV2 { + entity_addr, + selector, + }, + bytes, + )) + } + _ => Err(Error::Formatting), + } + } +} + +impl Display for EntryPointAddr { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + match self { + EntryPointAddr::VmCasperV1 { + entity_addr, + name_bytes, + } => { + write!( + f, + "{}{}-{}", + V1_ENTRY_POINT_PREFIX, + entity_addr, + base16::encode_lower(name_bytes) + ) + } + EntryPointAddr::VmCasperV2 { + entity_addr, + selector, + } => { + write!(f, "{}{}-{}", V2_ENTRY_POINT_PREFIX, entity_addr, selector) + } + } + } +} + +impl Debug for EntryPointAddr { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + match self { + EntryPointAddr::VmCasperV1 { + entity_addr, + name_bytes, + } => { + write!(f, "EntryPointAddr({:?}-{:?})", entity_addr, name_bytes) + } + EntryPointAddr::VmCasperV2 { + entity_addr, + selector, + } => { + write!(f, "EntryPointAddr({:?}-{:?})", entity_addr, selector) + } + } + } +} + +#[cfg(any(feature = "testing", test))] +impl Distribution<EntryPointAddr> for Standard { + fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> EntryPointAddr { + if rng.gen() { + EntryPointAddr::VmCasperV1 { + entity_addr: rng.gen(), + name_bytes: rng.gen(), + } + } else { + EntryPointAddr::VmCasperV2 { + entity_addr: rng.gen(), + selector: rng.gen(), + } + } + } +} + +/// The encaspulated representation of entrypoints. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +pub enum EntryPointValue { + /// Entrypoints to be executed against the V1 Casper VM. + V1CasperVm(EntryPoint), + /// Entrypoints to be executed against the V2 Casper VM. + V2CasperVm(EntryPointV2), +} + +impl EntryPointValue { + /// Returns [`EntryPointValue::V1CasperVm`] variant. + pub fn new_v1_entry_point_value(entry_point: EntryPoint) -> Self { + Self::V1CasperVm(entry_point) + } + + /// Returns [`EntryPointValue::V2CasperVm`] variant. + pub fn new_v2_entry_point_value(entry_point: EntryPointV2) -> Self { + Self::V2CasperVm(entry_point) + } +} + +impl ToBytes for EntryPointValue { + fn to_bytes(&self) -> Result<Vec<u8>, Error> { + let mut buffer = bytesrepr::allocate_buffer(self)?; + self.write_bytes(&mut buffer)?; + Ok(buffer) + } + + fn serialized_length(&self) -> usize { + U8_SERIALIZED_LENGTH + + match self { + EntryPointValue::V1CasperVm(entry_point) => entry_point.serialized_length(), + EntryPointValue::V2CasperVm(entry_point) => entry_point.serialized_length(), + } + } + + fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), Error> { + match self { + EntryPointValue::V1CasperVm(entry_point) => { + writer.push(V1_ENTRY_POINT_TAG); + entry_point.write_bytes(writer)?; + } + EntryPointValue::V2CasperVm(entry_point) => { + writer.push(V2_ENTRY_POINT_TAG); + entry_point.write_bytes(writer)?; + } + } + Ok(()) + } +} + +impl FromBytes for EntryPointValue { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> { + let (tag, remainder) = u8::from_bytes(bytes)?; + match tag { + V1_ENTRY_POINT_TAG => { + let (entry_point, remainder) = EntryPoint::from_bytes(remainder)?; + Ok((Self::V1CasperVm(entry_point), remainder)) + } + V2_ENTRY_POINT_TAG => { + let (entry_point, remainder) = EntryPointV2::from_bytes(remainder)?; + Ok((Self::V2CasperVm(entry_point), remainder)) + } + _ => Err(Error::Formatting), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn entry_point_type_serialization_roundtrip() { + let vm1 = EntryPointAddr::VmCasperV1 { + entity_addr: EntityAddr::new_smart_contract([42; 32]), + name_bytes: [99; 32], + }; + bytesrepr::test_serialization_roundtrip(&vm1); + let vm2 = EntryPointAddr::VmCasperV2 { + entity_addr: EntityAddr::new_smart_contract([42; 32]), + selector: u32::MAX, + }; + bytesrepr::test_serialization_roundtrip(&vm2); + } +} diff --git a/types/src/contracts.rs b/types/src/contracts.rs index d2c0ac4d22..753970af3b 100644 --- a/types/src/contracts.rs +++ b/types/src/contracts.rs @@ -5,7 +5,7 @@ use alloc::{ collections::{BTreeMap, BTreeSet}, format, - string::String, + string::{String, ToString}, vec::Vec, }; use core::{ @@ -23,6 +23,9 @@ use serde::{ de::{self, Error as SerdeError}, ser, Deserialize, Deserializer, Serialize, Serializer, }; +#[cfg(feature = "json-schema")] +use serde_map_to_array::KeyValueJsonSchema; +use serde_map_to_array::{BTreeMapToArray, KeyValueLabels}; use crate::{ account, @@ -33,8 +36,9 @@ use crate::{ package::PackageStatus, serde_helpers::contract_package::HumanReadableContractPackage, uref::{self, URef}, - AddressableEntityHash, CLType, CLTyped, EntityVersionKey, EntryPoint, EntryPoints, Groups, - HashAddr, Key, Package, ProtocolVersion, KEY_HASH_LENGTH, + AddressableEntityHash, CLType, CLTyped, EntityVersionKey, EntryPoint as EntityEntryPoint, + EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints as EntityEntryPoints, Groups, + HashAddr, Key, Package, Parameter, Parameters, ProtocolVersion, KEY_HASH_LENGTH, }; const CONTRACT_STRING_PREFIX: &str = "contract-"; @@ -898,6 +902,284 @@ impl From<ContractPackage> for Package { } } +/// Type signature of a method. Order of arguments matter since can be +/// referenced by index as well as name. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +pub struct EntryPoint { + name: String, + args: Parameters, + ret: CLType, + access: EntryPointAccess, + entry_point_type: EntryPointType, +} + +impl From<EntryPoint> for (String, Parameters, CLType, EntryPointAccess, EntryPointType) { + fn from(entry_point: EntryPoint) -> Self { + ( + entry_point.name, + entry_point.args, + entry_point.ret, + entry_point.access, + entry_point.entry_point_type, + ) + } +} + +impl EntryPoint { + /// `EntryPoint` constructor. + pub fn new<T: Into<String>>( + name: T, + args: Parameters, + ret: CLType, + access: EntryPointAccess, + entry_point_type: EntryPointType, + ) -> Self { + EntryPoint { + name: name.into(), + args, + ret, + access, + entry_point_type, + } + } + + /// Create a default [`EntryPoint`] with specified name. + pub fn default_with_name<T: Into<String>>(name: T) -> Self { + EntryPoint { + name: name.into(), + ..Default::default() + } + } + + /// Get name. + pub fn name(&self) -> &str { + &self.name + } + + /// Get access enum. + pub fn access(&self) -> &EntryPointAccess { + &self.access + } + + /// Get the arguments for this method. + pub fn args(&self) -> &[Parameter] { + self.args.as_slice() + } + + /// Get the return type. + pub fn ret(&self) -> &CLType { + &self.ret + } + + /// Obtains entry point + pub fn entry_point_type(&self) -> EntryPointType { + self.entry_point_type + } +} + +impl Default for EntryPoint { + /// constructor for a public session `EntryPoint` that takes no args and returns `Unit` + fn default() -> Self { + EntryPoint { + name: DEFAULT_ENTRY_POINT_NAME.to_string(), + args: Vec::new(), + ret: CLType::Unit, + access: EntryPointAccess::Public, + entry_point_type: EntryPointType::Caller, + } + } +} + +impl ToBytes for EntryPoint { + fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> { + let mut buffer = bytesrepr::allocate_buffer(self)?; + self.write_bytes(&mut buffer)?; + Ok(buffer) + } + + fn serialized_length(&self) -> usize { + self.name.serialized_length() + + self.args.serialized_length() + + self.ret.serialized_length() + + self.access.serialized_length() + + self.entry_point_type.serialized_length() + } + + fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> { + self.name.write_bytes(writer)?; + self.args.write_bytes(writer)?; + self.ret.append_bytes(writer)?; + self.access.write_bytes(writer)?; + self.entry_point_type.write_bytes(writer)?; + Ok(()) + } +} + +impl FromBytes for EntryPoint { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (name, bytes) = String::from_bytes(bytes)?; + let (args, bytes) = Vec::<Parameter>::from_bytes(bytes)?; + let (ret, bytes) = CLType::from_bytes(bytes)?; + let (access, bytes) = EntryPointAccess::from_bytes(bytes)?; + let (entry_point_type, bytes) = EntryPointType::from_bytes(bytes)?; + + Ok(( + EntryPoint { + name, + args, + ret, + access, + entry_point_type, + }, + bytes, + )) + } +} + +/// Collection of named entry points. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +#[cfg_attr(feature = "datasize", derive(DataSize))] +#[cfg_attr(feature = "json-schema", derive(JsonSchema))] +#[serde(transparent, deny_unknown_fields)] +pub struct EntryPoints( + #[serde(with = "BTreeMapToArray::<String, EntryPoint, EntryPointLabels>")] + BTreeMap<String, EntryPoint>, +); + +impl ToBytes for EntryPoints { + fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> { + self.0.to_bytes() + } + + fn serialized_length(&self) -> usize { + self.0.serialized_length() + } + + fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> { + self.0.write_bytes(writer) + } +} + +impl FromBytes for EntryPoints { + fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> { + let (entry_points_map, remainder) = BTreeMap::<String, EntryPoint>::from_bytes(bytes)?; + Ok((EntryPoints(entry_points_map), remainder)) + } +} + +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 From<EntryPoint> for EntityEntryPoint { + fn from(value: EntryPoint) -> Self { + EntityEntryPoint::new( + value.name, + value.args, + value.ret, + value.access, + value.entry_point_type, + EntryPointPayment::Caller, + ) + } +} + +impl EntryPoints { + /// Constructs a new, empty `EntryPoints`. + pub const fn new() -> EntryPoints { + EntryPoints(BTreeMap::<String, EntryPoint>::new()) + } + + /// Constructs a new `EntryPoints` with a single entry for the default `EntryPoint`. + pub fn new_with_default_entry_point() -> Self { + let mut entry_points = EntryPoints::new(); + let entry_point = EntryPoint::default(); + entry_points.add_entry_point(entry_point); + entry_points + } + + /// Adds new [`EntryPoint`]. + pub fn add_entry_point(&mut self, entry_point: EntryPoint) { + self.0.insert(entry_point.name().to_string(), entry_point); + } + + /// Checks if given [`EntryPoint`] exists. + pub fn has_entry_point(&self, entry_point_name: &str) -> bool { + self.0.contains_key(entry_point_name) + } + + /// Gets an existing [`EntryPoint`] by its name. + pub fn get(&self, entry_point_name: &str) -> Option<&EntryPoint> { + self.0.get(entry_point_name) + } + + /// Returns iterator for existing entry point names. + pub fn keys(&self) -> impl Iterator<Item = &String> { + self.0.keys() + } + + /// Takes all entry points. + pub fn take_entry_points(self) -> Vec<EntryPoint> { + self.0.into_values().collect() + } + + /// Returns the length of the entry points + pub fn len(&self) -> usize { + self.0.len() + } + + /// Checks if the `EntryPoints` is empty. + 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::Caller) + } +} + +impl From<Vec<EntryPoint>> for EntryPoints { + fn from(entry_points: Vec<EntryPoint>) -> EntryPoints { + let entries = entry_points + .into_iter() + .map(|entry_point| (String::from(entry_point.name()), entry_point)) + .collect(); + EntryPoints(entries) + } +} + +impl From<EntryPoints> for EntityEntryPoints { + fn from(value: EntryPoints) -> Self { + let mut entry_points = EntityEntryPoints::new(); + for contract_entry_point in value.take_entry_points() { + entry_points.add_entry_point(EntityEntryPoint::from(contract_entry_point)); + } + entry_points + } +} + +struct EntryPointLabels; + +impl KeyValueLabels for EntryPointLabels { + const KEY: &'static str = "name"; + const VALUE: &'static str = "entry_point"; +} + +#[cfg(feature = "json-schema")] +impl KeyValueJsonSchema for EntryPointLabels { + const JSON_SCHEMA_KV_NAME: Option<&'static str> = Some("NamedEntryPoint"); +} + /// Methods and type signatures supported by a contract. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "datasize", derive(DataSize))] diff --git a/types/src/execution/transform_kind.rs b/types/src/execution/transform_kind.rs index 5b94e04d64..7caa013954 100644 --- a/types/src/execution/transform_kind.rs +++ b/types/src/execution/transform_kind.rs @@ -188,6 +188,11 @@ impl TransformKindV2 { let found = "Reservation".to_string(); Err(StoredValueTypeMismatch::new(expected, found).into()) } + StoredValue::EntryPoint(_) => { + let expected = "Contract or Account".to_string(); + let found = "EntryPoint".to_string(); + Err(StoredValueTypeMismatch::new(expected, found).into()) + } }, TransformKindV2::Failure(error) => Err(error), } diff --git a/types/src/gens.rs b/types/src/gens.rs index 08520239fd..482eaa299b 100644 --- a/types/src/gens.rs +++ b/types/src/gens.rs @@ -31,7 +31,7 @@ use crate::{ contract_messages::{MessageChecksum, MessageTopicSummary, TopicNameHash}, contracts::{ Contract, ContractHash, ContractPackage, ContractPackageStatus, ContractVersionKey, - ContractVersions, + ContractVersions, EntryPoint as ContractEntryPoint, EntryPoints as ContractEntryPoints, }, crypto::{self, gens::public_key_arb_no_system}, deploy_info::gens::deploy_info_arb, @@ -43,6 +43,7 @@ use crate::{ ValidatorBid, WithdrawPurse, DELEGATION_RATE_DENOMINATOR, }, mint::BalanceHoldAddr, + SystemEntityType, }, transaction::gens::deploy_hash_arb, transfer::{ @@ -50,9 +51,9 @@ use crate::{ TransferAddr, }, AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, ByteCode, CLType, CLValue, - Digest, EntityKind, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, EraId, Group, - Key, NamedArg, Package, Parameter, Phase, ProtocolVersion, SemVer, StoredValue, URef, U128, - U256, U512, + Digest, EntityKind, EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, + EntryPoints, EraId, Group, Key, NamedArg, Package, Parameter, Phase, ProtocolVersion, SemVer, + StoredValue, TransactionRuntime, URef, U128, U256, U512, }; pub fn u8_slice_32() -> impl Strategy<Value = [u8; 32]> { @@ -342,6 +343,14 @@ pub fn entry_point_type_arb() -> impl Strategy<Value = EntryPointType> { ] } +pub fn entry_point_payment_arb() -> impl Strategy<Value = EntryPointPayment> { + prop_oneof![ + Just(EntryPointPayment::Caller), + Just(EntryPointPayment::SelfOnly), + Just(EntryPointPayment::SelfOnward), + ] +} + pub fn parameter_arb() -> impl Strategy<Value = Parameter> { (".*", cl_type_arb()).prop_map(|(name, cl_type)| Parameter::new(name, cl_type)) } @@ -351,6 +360,29 @@ pub fn parameters_arb() -> impl Strategy<Value = Parameters> { } pub fn entry_point_arb() -> impl Strategy<Value = EntryPoint> { + ( + ".*", + parameters_arb(), + entry_point_type_arb(), + entry_point_access_arb(), + entry_point_payment_arb(), + cl_type_arb(), + ) + .prop_map( + |(name, parameters, entry_point_type, entry_point_access, entry_point_payment, ret)| { + EntryPoint::new( + name, + parameters, + ret, + entry_point_access, + entry_point_type, + entry_point_payment, + ) + }, + ) +} + +pub fn contract_entry_point_arb() -> impl Strategy<Value = ContractEntryPoint> { ( ".*", parameters_arb(), @@ -360,7 +392,7 @@ pub fn entry_point_arb() -> impl Strategy<Value = EntryPoint> { ) .prop_map( |(name, parameters, entry_point_type, entry_point_access, ret)| { - EntryPoint::new(name, parameters, ret, entry_point_access, entry_point_type) + ContractEntryPoint::new(name, parameters, ret, entry_point_access, entry_point_type) }, ) } @@ -369,6 +401,10 @@ pub fn entry_points_arb() -> impl Strategy<Value = EntryPoints> { collection::vec(entry_point_arb(), 1..10).prop_map(EntryPoints::from) } +pub fn contract_entry_points_arb() -> impl Strategy<Value = ContractEntryPoints> { + collection::vec(contract_entry_point_arb(), 1..10).prop_map(ContractEntryPoints::from) +} + pub fn message_topics_arb() -> impl Strategy<Value = MessageTopics> { collection::vec(any::<String>(), 1..100).prop_map(|topic_names| { MessageTopics::from( @@ -425,7 +461,7 @@ pub fn contract_package_arb() -> impl Strategy<Value = ContractPackage> { pub fn contract_arb() -> impl Strategy<Value = Contract> { ( protocol_version_arb(), - entry_points_arb(), + contract_entry_points_arb(), u8_slice_32(), u8_slice_32(), named_keys_arb(20), @@ -449,38 +485,61 @@ pub fn contract_arb() -> impl Strategy<Value = Contract> { ) } +pub fn system_entity_type_arb() -> impl Strategy<Value = SystemEntityType> { + prop_oneof![ + Just(SystemEntityType::Mint), + Just(SystemEntityType::HandlePayment), + Just(SystemEntityType::StandardPayment), + Just(SystemEntityType::Auction), + ] +} + +pub fn transaction_runtime_arb() -> impl Strategy<Value = TransactionRuntime> { + prop_oneof![ + Just(TransactionRuntime::VmCasperV1), + Just(TransactionRuntime::VmCasperV2), + ] +} + +pub fn entity_kind_arb() -> impl Strategy<Value = EntityKind> { + prop_oneof![ + system_entity_type_arb().prop_map(EntityKind::System), + account_hash_arb().prop_map(EntityKind::Account), + transaction_runtime_arb().prop_map(EntityKind::SmartContract), + ] +} + pub fn addressable_entity_arb() -> impl Strategy<Value = AddressableEntity> { ( protocol_version_arb(), - entry_points_arb(), u8_slice_32(), u8_slice_32(), uref_arb(), associated_keys_arb(), action_thresholds_arb(), message_topics_arb(), + entity_kind_arb(), ) .prop_map( |( protocol_version, - entry_points, contract_package_hash_arb, contract_wasm_hash, main_purse, associated_keys, action_thresholds, message_topics, + entity_kind, )| { AddressableEntity::new( contract_package_hash_arb.into(), contract_wasm_hash.into(), - entry_points, protocol_version, main_purse, associated_keys, action_thresholds, message_topics, - EntityKind::SmartContract, + entity_kind, ) }, ) @@ -758,6 +817,7 @@ pub fn stored_value_arb() -> impl Strategy<Value = StoredValue> { StoredValue::Message(_) => stored_value, StoredValue::NamedKey(_) => stored_value, StoredValue::Reservation(_) => stored_value, + StoredValue::EntryPoint(_) => stored_value, }) } diff --git a/types/src/key.rs b/types/src/key.rs index 3e411a37e2..c267469f58 100644 --- a/types/src/key.rs +++ b/types/src/key.rs @@ -36,7 +36,9 @@ use tracing::warn; use crate::{ account::{AccountHash, ACCOUNT_HASH_LENGTH}, addressable_entity, - addressable_entity::{AddressableEntityHash, EntityAddr, EntityKindTag, NamedKeyAddr}, + addressable_entity::{ + AddressableEntityHash, EntityAddr, EntityKindTag, EntryPointAddr, NamedKeyAddr, + }, block::BlockGlobalAddr, byte_code, bytesrepr::{ @@ -156,6 +158,7 @@ pub enum KeyTag { NamedKey = 20, BlockGlobal = 21, BalanceHold = 22, + EntryPoint = 23, } impl KeyTag { @@ -186,6 +189,7 @@ impl KeyTag { 20 => KeyTag::NamedKey, 21 => KeyTag::BlockGlobal, 22 => KeyTag::BalanceHold, + 23 => KeyTag::EntryPoint, _ => panic!(), } } @@ -217,6 +221,7 @@ impl Display for KeyTag { KeyTag::NamedKey => write!(f, "NamedKey"), KeyTag::BlockGlobal => write!(f, "BlockGlobal"), KeyTag::BalanceHold => write!(f, "BalanceHold"), + KeyTag::EntryPoint => write!(f, "EntryPoint"), } } } @@ -265,6 +270,7 @@ impl FromBytes for KeyTag { tag if tag == KeyTag::NamedKey as u8 => KeyTag::NamedKey, tag if tag == KeyTag::BlockGlobal as u8 => KeyTag::BlockGlobal, tag if tag == KeyTag::BalanceHold as u8 => KeyTag::BalanceHold, + tag if tag == KeyTag::EntryPoint as u8 => KeyTag::EntryPoint, _ => return Err(Error::Formatting), }; Ok((tag, rem)) @@ -325,6 +331,8 @@ pub enum Key { BlockGlobal(BlockGlobalAddr), /// A `Key` under which a hold on a purse balance is stored. BalanceHold(BalanceHoldAddr), + /// A `Key` under which a entrypoint record is written. + EntryPoint(EntryPointAddr), } #[cfg(feature = "json-schema")] @@ -395,6 +403,8 @@ pub enum FromStrError { BlockGlobal(String), /// Balance hold parse error. BalanceHold(String), + /// Entry point parse error. + EntryPoint(String), /// Unknown prefix. UnknownPrefix, } @@ -475,6 +485,9 @@ impl Display for FromStrError { FromStrError::BalanceHold(error) => { write!(f, "balance-hold from string error: {}", error) } + FromStrError::EntryPoint(error) => { + write!(f, "entry-point from string error: {}", error) + } FromStrError::UnknownPrefix => write!(f, "unknown prefix for key"), } } @@ -508,6 +521,7 @@ impl Key { Key::NamedKey(_) => String::from("Key::NamedKey"), Key::BlockGlobal(_) => String::from("Key::BlockGlobal"), Key::BalanceHold(_) => String::from("Key::BalanceHold"), + Key::EntryPoint(_) => String::from("Key::EntryPoint"), } } @@ -628,6 +642,9 @@ impl Key { let tail = BalanceHoldAddr::to_formatted_string(&balance_hold_addr); format!("{}{}", BALANCE_HOLD_PREFIX, tail) } + Key::EntryPoint(entry_point_addr) => { + format!("{}", entry_point_addr) + } } } @@ -853,6 +870,12 @@ impl Key { return Ok(BlockGlobalAddr::MessageCount.into()); } + match EntryPointAddr::from_formatted_str(input) { + Ok(entry_point_addr) => return Ok(Key::EntryPoint(entry_point_addr)), + Err(addressable_entity::FromStrError::InvalidPrefix) => {} + Err(error) => return Err(FromStrError::EntryPoint(error.to_string())), + } + Err(FromStrError::UnknownPrefix) } @@ -1048,6 +1071,11 @@ impl Key { Key::Message(MessageAddr::new_topic_addr(entity_addr, topic_name_hash)) } + /// Creates a new [`Key::EntryPoint`] variant from an entrypoint addr. + pub fn entry_point(entry_point_addr: EntryPointAddr) -> Self { + Key::EntryPoint(entry_point_addr) + } + /// Returns true if the key is of type [`Key::Dictionary`]. pub fn is_dictionary_key(&self) -> bool { if let Key::Dictionary(_) = self { @@ -1162,7 +1190,8 @@ impl Key { | Key::BalanceHold(_) | Key::Dictionary(_) | Key::Message(_) - | Key::BlockGlobal(_) => true, + | Key::BlockGlobal(_) + | Key::EntryPoint(_) => true, _ => false, }; if !ret { @@ -1301,6 +1330,9 @@ impl Display for Key { Key::BalanceHold(balance_hold_addr) => { write!(f, "Key::BalanceHold({})", balance_hold_addr) } + Key::EntryPoint(entry_point_addr) => { + write!(f, "Key::EntryPointAddr({})", entry_point_addr) + } } } } @@ -1337,6 +1369,7 @@ impl Tagged<KeyTag> for Key { Key::NamedKey(_) => KeyTag::NamedKey, Key::BlockGlobal(_) => KeyTag::BlockGlobal, Key::BalanceHold(_) => KeyTag::BalanceHold, + Key::EntryPoint(_) => KeyTag::EntryPoint, } } } @@ -1450,6 +1483,9 @@ impl ToBytes for Key { Key::BalanceHold(balance_hold_addr) => { U8_SERIALIZED_LENGTH + balance_hold_addr.serialized_length() } + Key::EntryPoint(entry_point_addr) => { + U8_SERIALIZED_LENGTH + entry_point_addr.serialized_length() + } } } @@ -1482,6 +1518,7 @@ impl ToBytes for Key { Key::Message(message_addr) => message_addr.write_bytes(writer), Key::NamedKey(named_key_addr) => named_key_addr.write_bytes(writer), Key::BalanceHold(balance_hold_addr) => balance_hold_addr.write_bytes(writer), + Key::EntryPoint(entry_point_addr) => entry_point_addr.write_bytes(writer), } } } @@ -1583,6 +1620,10 @@ impl FromBytes for Key { let (balance_hold_addr, rem) = BalanceHoldAddr::from_bytes(remainder)?; Ok((Key::BalanceHold(balance_hold_addr), rem)) } + KeyTag::EntryPoint => { + let (entry_point_addr, rem) = EntryPointAddr::from_bytes(remainder)?; + Ok((Key::EntryPoint(entry_point_addr), rem)) + } } } } @@ -1615,6 +1656,7 @@ fn please_add_to_distribution_impl(key: Key) { Key::NamedKey(_) => unimplemented!(), Key::BlockGlobal(_) => unimplemented!(), Key::BalanceHold(_) => unimplemented!(), + Key::EntryPoint(_) => unimplemented!(), } } @@ -1645,6 +1687,7 @@ impl Distribution<Key> for Standard { 20 => Key::NamedKey(NamedKeyAddr::new_named_key_entry(rng.gen(), rng.gen())), 21 => Key::BlockGlobal(rng.gen()), 22 => Key::BalanceHold(rng.gen()), + 23 => Key::EntryPoint(rng.gen()), _ => unreachable!(), } } @@ -1679,6 +1722,7 @@ mod serde_helpers { NamedKey(&'a NamedKeyAddr), BlockGlobal(&'a BlockGlobalAddr), BalanceHold(&'a BalanceHoldAddr), + EntryPoint(&'a EntryPointAddr), } #[derive(Deserialize)] @@ -1707,6 +1751,7 @@ mod serde_helpers { NamedKey(NamedKeyAddr), BlockGlobal(BlockGlobalAddr), BalanceHold(BalanceHoldAddr), + EntryPoint(EntryPointAddr), } impl<'a> From<&'a Key> for BinarySerHelper<'a> { @@ -1739,6 +1784,7 @@ mod serde_helpers { Key::BalanceHold(balance_hold_addr) => { BinarySerHelper::BalanceHold(balance_hold_addr) } + Key::EntryPoint(entry_point_addr) => BinarySerHelper::EntryPoint(entry_point_addr), } } } @@ -1773,6 +1819,9 @@ mod serde_helpers { BinaryDeserHelper::BalanceHold(balance_hold_addr) => { Key::BalanceHold(balance_hold_addr) } + BinaryDeserHelper::EntryPoint(entry_point_addr) => { + Key::EntryPoint(entry_point_addr) + } } } } @@ -1863,6 +1912,10 @@ mod tests { const BLOCK_MESSAGE_COUNT_KEY: Key = Key::BlockGlobal(BlockGlobalAddr::MessageCount); const BALANCE_HOLD: Key = Key::BalanceHold(BalanceHoldAddr::new_gas([42; 32], BlockTime::new(100))); + const ENTRY_POINT: Key = Key::EntryPoint(EntryPointAddr::new_v2_entry_point_addr( + EntityAddr::new_smart_contract([42; 32]), + 1u32, + )); const KEYS: &[Key] = &[ ACCOUNT_KEY, HASH_KEY, @@ -1894,6 +1947,7 @@ mod tests { BLOCK_TIME_KEY, BLOCK_MESSAGE_COUNT_KEY, BALANCE_HOLD, + ENTRY_POINT, ]; const HEX_STRING: &str = "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"; const TOPIC_NAME_HEX_STRING: &str = @@ -2489,5 +2543,6 @@ 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(&ENTRY_POINT); } } diff --git a/types/src/lib.rs b/types/src/lib.rs index aff9c04a0d..b288bf9c70 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -22,6 +22,7 @@ extern crate alloc; extern crate core; + mod access_rights; pub mod account; pub mod addressable_entity; @@ -87,7 +88,8 @@ pub use account::Account; #[doc(inline)] pub use addressable_entity::{ AddressableEntity, AddressableEntityHash, EntityAddr, EntityKind, EntryPoint, EntryPointAccess, - EntryPointType, EntryPoints, Parameter, + EntryPointAddr, EntryPointPayment, EntryPointType, EntryPointValue, EntryPoints, Parameter, + Parameters, DEFAULT_ENTRY_POINT_NAME, }; #[doc(inline)] pub use api_error::ApiError; diff --git a/types/src/package.rs b/types/src/package.rs index 644b2cf9dd..25abef3155 100644 --- a/types/src/package.rs +++ b/types/src/package.rs @@ -873,8 +873,8 @@ mod tests { use super::*; use crate::{ - AccessRights, EntityVersionKey, EntryPoint, EntryPointAccess, EntryPointType, Parameter, - ProtocolVersion, URef, + AccessRights, EntityVersionKey, EntryPoint, EntryPointAccess, EntryPointPayment, + EntryPointType, Parameter, ProtocolVersion, URef, }; use alloc::borrow::ToOwned; @@ -915,6 +915,7 @@ mod tests { CLType::U32, EntryPointAccess::groups(&["Group 2"]), EntryPointType::Caller, + EntryPointPayment::Caller, ); ret.insert(entrypoint.name().to_owned(), entrypoint); let entrypoint = EntryPoint::new( @@ -923,6 +924,7 @@ mod tests { CLType::U32, EntryPointAccess::groups(&["Group 1"]), EntryPointType::Caller, + EntryPointPayment::Caller, ); ret.insert(entrypoint.name().to_owned(), entrypoint); ret diff --git a/types/src/stored_value.rs b/types/src/stored_value.rs index 12e57baf98..22fa15e15b 100644 --- a/types/src/stored_value.rs +++ b/types/src/stored_value.rs @@ -27,7 +27,7 @@ use crate::{ auction::{Bid, BidKind, EraInfo, UnbondingPurse, WithdrawPurse}, reservations::ReservationKind, }, - AddressableEntity, ByteCode, CLValue, DeployInfo, TransferV1, + AddressableEntity, ByteCode, CLValue, DeployInfo, EntryPointValue, TransferV1, }; pub use global_state_identifier::GlobalStateIdentifier; pub use type_mismatch::TypeMismatch; @@ -54,6 +54,7 @@ enum Tag { Message = 16, NamedKey = 17, Reservation = 18, + EntryPoint = 19, } /// A value stored in Global State. @@ -104,6 +105,8 @@ pub enum StoredValue { NamedKey(NamedKeyValue), /// A reservation record. Reservation(ReservationKind), + /// An entrypoint record. + EntryPoint(EntryPointValue), } impl StoredValue { @@ -231,6 +234,14 @@ impl StoredValue { } } + /// Returns a reference to the wrapped `EntryPointValue` if this is a `EntryPointValue` variant. + pub fn as_entry_point_value(&self) -> Option<&EntryPointValue> { + match self { + StoredValue::EntryPoint(entry_point) => Some(entry_point), + _ => None, + } + } + /// Returns the `CLValue` if this is a `CLValue` variant. pub fn into_cl_value(self) -> Option<CLValue> { match self { @@ -343,6 +354,14 @@ impl StoredValue { } } + /// Returns the `EntryPointValue` if this is a `EntryPointValue` variant. + pub fn into_entry_point_value(self) -> Option<EntryPointValue> { + match self { + StoredValue::EntryPoint(value) => Some(value), + _ => None, + } + } + /// Returns the type name of the [`StoredValue`] enum variant. /// /// For [`CLValue`] variants it will return the name of the [`CLType`](crate::cl_type::CLType) @@ -367,6 +386,7 @@ impl StoredValue { StoredValue::Message(_) => "Message".to_string(), StoredValue::NamedKey(_) => "NamedKey".to_string(), StoredValue::Reservation(_) => "Reservation".to_string(), + StoredValue::EntryPoint(_) => "EntryPoint".to_string(), } } @@ -391,6 +411,7 @@ impl StoredValue { StoredValue::Message(_) => Tag::Message, StoredValue::NamedKey(_) => Tag::NamedKey, StoredValue::Reservation(_) => Tag::Reservation, + StoredValue::EntryPoint(_) => Tag::EntryPoint, } } } @@ -400,6 +421,7 @@ impl From<CLValue> for StoredValue { StoredValue::CLValue(value) } } + impl From<Account> for StoredValue { fn from(value: Account) -> StoredValue { StoredValue::Account(value) @@ -429,6 +451,7 @@ impl From<AddressableEntity> for StoredValue { StoredValue::AddressableEntity(value) } } + impl From<Package> for StoredValue { fn from(value: Package) -> StoredValue { StoredValue::Package(value) @@ -453,6 +476,12 @@ impl From<ByteCode> for StoredValue { } } +impl From<EntryPointValue> for StoredValue { + fn from(value: EntryPointValue) -> Self { + StoredValue::EntryPoint(value) + } +} + impl TryFrom<StoredValue> for CLValue { type Error = TypeMismatch; @@ -673,6 +702,7 @@ impl ToBytes for StoredValue { StoredValue::Message(message_digest) => message_digest.serialized_length(), StoredValue::NamedKey(named_key_value) => named_key_value.serialized_length(), StoredValue::Reservation(reservation_kind) => reservation_kind.serialized_length(), + StoredValue::EntryPoint(entry_point_value) => entry_point_value.serialized_length(), } } @@ -700,6 +730,7 @@ impl ToBytes for StoredValue { StoredValue::Message(message_digest) => message_digest.write_bytes(writer), StoredValue::NamedKey(named_key_value) => named_key_value.write_bytes(writer), StoredValue::Reservation(reservation_kind) => reservation_kind.write_bytes(writer), + StoredValue::EntryPoint(entry_point_value) => entry_point_value.write_bytes(writer), } } } @@ -764,6 +795,8 @@ impl FromBytes for StoredValue { (StoredValue::NamedKey(named_key_value), remainder) }) } + tag if tag == Tag::EntryPoint as u8 => EntryPointValue::from_bytes(remainder) + .map(|(entry_point, remainder)| (StoredValue::EntryPoint(entry_point), remainder)), _ => Err(Error::Formatting), } } @@ -807,6 +840,7 @@ mod serde_helpers { Message(&'a MessageChecksum), NamedKey(&'a NamedKeyValue), Reservation(&'a ReservationKind), + EntryPoint(&'a EntryPointValue), } #[derive(Deserialize)] @@ -829,6 +863,7 @@ mod serde_helpers { MessageTopic(MessageTopicSummary), Message(MessageChecksum), NamedKey(NamedKeyValue), + EntryPoint(EntryPointValue), } impl<'a> From<&'a StoredValue> for HumanReadableSerHelper<'a> { @@ -863,6 +898,7 @@ mod serde_helpers { } StoredValue::NamedKey(payload) => HumanReadableSerHelper::NamedKey(payload), StoredValue::Reservation(payload) => HumanReadableSerHelper::Reservation(payload), + StoredValue::EntryPoint(payload) => HumanReadableSerHelper::EntryPoint(payload), } } } @@ -900,6 +936,7 @@ mod serde_helpers { StoredValue::Message(message_digest) } HumanReadableDeserHelper::NamedKey(payload) => StoredValue::NamedKey(payload), + HumanReadableDeserHelper::EntryPoint(payload) => StoredValue::EntryPoint(payload), } } } @@ -936,6 +973,7 @@ mod tests { use crate::{bytesrepr, gens, StoredValue}; use proptest::proptest; use serde_json::Value; + const STORED_VALUE_CONTRACT_PACKAGE_RAW: &str = r#" { "ContractPackage": { diff --git a/types/src/system/auction/entry_points.rs b/types/src/system/auction/entry_points.rs index fbde8bd64d..eadd17538a 100644 --- a/types/src/system/auction/entry_points.rs +++ b/types/src/system/auction/entry_points.rs @@ -6,8 +6,8 @@ use crate::{ METHOD_GET_ERA_VALIDATORS, METHOD_READ_ERA_ID, METHOD_REDELEGATE, METHOD_RUN_AUCTION, METHOD_SLASH, METHOD_UNDELEGATE, METHOD_WITHDRAW_BID, }, - CLType, CLTyped, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Parameter, - PublicKey, U512, + CLType, CLTyped, EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints, + Parameter, PublicKey, U512, }; use super::{ARG_NEW_PUBLIC_KEY, ARG_REWARDS_MAP, METHOD_CHANGE_BID_PUBLIC_KEY}; @@ -22,6 +22,7 @@ pub fn auction_entry_points() -> EntryPoints { Option::<ValidatorWeights>::cl_type(), EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -35,6 +36,7 @@ pub fn auction_entry_points() -> EntryPoints { U512::cl_type(), EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -47,6 +49,7 @@ pub fn auction_entry_points() -> EntryPoints { U512::cl_type(), EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -60,6 +63,7 @@ pub fn auction_entry_points() -> EntryPoints { U512::cl_type(), EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -73,6 +77,7 @@ pub fn auction_entry_points() -> EntryPoints { U512::cl_type(), EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -87,6 +92,7 @@ pub fn auction_entry_points() -> EntryPoints { U512::cl_type(), EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -96,6 +102,7 @@ pub fn auction_entry_points() -> EntryPoints { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -105,6 +112,7 @@ pub fn auction_entry_points() -> EntryPoints { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -117,6 +125,7 @@ pub fn auction_entry_points() -> EntryPoints { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -126,6 +135,7 @@ pub fn auction_entry_points() -> EntryPoints { CLType::U64, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -135,6 +145,7 @@ pub fn auction_entry_points() -> EntryPoints { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -147,6 +158,7 @@ pub fn auction_entry_points() -> EntryPoints { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); diff --git a/types/src/system/handle_payment/entry_points.rs b/types/src/system/handle_payment/entry_points.rs index 3c7d77e4f1..52ed97fcf1 100644 --- a/types/src/system/handle_payment/entry_points.rs +++ b/types/src/system/handle_payment/entry_points.rs @@ -4,7 +4,8 @@ use crate::{ system::handle_payment::{ ARG_PURSE, METHOD_GET_PAYMENT_PURSE, METHOD_GET_REFUND_PURSE, METHOD_SET_REFUND_PURSE, }, - CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Parameter, + CLType, EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints, + Parameter, }; /// Creates handle payment contract entry points. @@ -17,6 +18,7 @@ pub fn handle_payment_entry_points() -> EntryPoints { CLType::URef, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(get_payment_purse); @@ -26,6 +28,7 @@ pub fn handle_payment_entry_points() -> EntryPoints { CLType::Unit, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(set_refund_purse); @@ -35,6 +38,7 @@ pub fn handle_payment_entry_points() -> EntryPoints { CLType::Option(Box::new(CLType::URef)), EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(get_refund_purse); diff --git a/types/src/system/mint/entry_points.rs b/types/src/system/mint/entry_points.rs index bc22fcec78..a8af8d3a7c 100644 --- a/types/src/system/mint/entry_points.rs +++ b/types/src/system/mint/entry_points.rs @@ -7,7 +7,8 @@ use crate::{ METHOD_CREATE, METHOD_MINT, METHOD_MINT_INTO_EXISTING_PURSE, METHOD_READ_BASE_ROUND_REWARD, METHOD_REDUCE_TOTAL_SUPPLY, METHOD_TRANSFER, }, - CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Parameter, + CLType, EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints, + Parameter, }; /// Returns entry points for a mint system contract. @@ -23,6 +24,7 @@ pub fn mint_entry_points() -> EntryPoints { }, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -35,6 +37,7 @@ pub fn mint_entry_points() -> EntryPoints { }, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -44,6 +47,7 @@ pub fn mint_entry_points() -> EntryPoints { CLType::URef, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -53,6 +57,7 @@ pub fn mint_entry_points() -> EntryPoints { CLType::Option(Box::new(CLType::U512)), EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -71,6 +76,7 @@ pub fn mint_entry_points() -> EntryPoints { }, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -80,6 +86,7 @@ pub fn mint_entry_points() -> EntryPoints { CLType::U512, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); @@ -95,6 +102,7 @@ pub fn mint_entry_points() -> EntryPoints { }, EntryPointAccess::Public, EntryPointType::Called, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); diff --git a/types/src/system/standard_payment/entry_points.rs b/types/src/system/standard_payment/entry_points.rs index fee12664a7..7dce6c15a2 100644 --- a/types/src/system/standard_payment/entry_points.rs +++ b/types/src/system/standard_payment/entry_points.rs @@ -2,7 +2,8 @@ use alloc::{boxed::Box, string::ToString}; use crate::{ system::standard_payment::{ARG_AMOUNT, METHOD_PAY}, - CLType, EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, Parameter, + CLType, EntryPoint, EntryPointAccess, EntryPointPayment, EntryPointType, EntryPoints, + Parameter, }; /// Creates standard payment contract entry points. @@ -18,6 +19,7 @@ pub fn standard_payment_entry_points() -> EntryPoints { }, EntryPointAccess::Public, EntryPointType::Caller, + EntryPointPayment::Caller, ); entry_points.add_entry_point(entry_point); diff --git a/types/src/transaction/transaction_runtime.rs b/types/src/transaction/transaction_runtime.rs index c1fac1ed8b..08465dde88 100644 --- a/types/src/transaction/transaction_runtime.rs +++ b/types/src/transaction/transaction_runtime.rs @@ -1,5 +1,10 @@ use alloc::vec::Vec; use core::fmt::{self, Display, Formatter}; +#[cfg(any(feature = "testing", test))] +use rand::{ + distributions::{Distribution, Standard}, + Rng, +}; #[cfg(feature = "datasize")] use datasize::DataSize; @@ -24,12 +29,15 @@ use crate::bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH}; pub enum TransactionRuntime { /// The Casper Version 1 Virtual Machine. VmCasperV1, + /// The Casper Version 2 Virtual Machine. + VmCasperV2, } impl Display for TransactionRuntime { fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { match self { TransactionRuntime::VmCasperV1 => write!(formatter, "vm-casper-v1"), + TransactionRuntime::VmCasperV2 => write!(formatter, "vm-casper-v2"), } } } @@ -57,17 +65,36 @@ impl FromBytes for TransactionRuntime { v if v == TransactionRuntime::VmCasperV1 as u8 => { Ok((TransactionRuntime::VmCasperV1, remainder)) } + v if v == TransactionRuntime::VmCasperV2 as u8 => { + Ok((TransactionRuntime::VmCasperV2, remainder)) + } _ => Err(bytesrepr::Error::Formatting), } } } +#[cfg(any(feature = "testing", test))] +impl Distribution<TransactionRuntime> for Standard { + fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> TransactionRuntime { + match rng.gen_range(0..=1) { + 0 => TransactionRuntime::VmCasperV1, + 1 => TransactionRuntime::VmCasperV2, + _ => unreachable!(), + } + } +} + #[cfg(test)] mod tests { use super::*; #[test] fn bytesrepr_roundtrip() { - bytesrepr::test_serialization_roundtrip(&TransactionRuntime::VmCasperV1); + for transaction_runtime in [ + TransactionRuntime::VmCasperV1, + TransactionRuntime::VmCasperV2, + ] { + bytesrepr::test_serialization_roundtrip(&transaction_runtime); + } } } 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 a9469bff8f..44f9066f90 100644 --- a/utils/global-state-update-gen/src/generic/state_tracker.rs +++ b/utils/global-state-update-gen/src/generic/state_tracker.rs @@ -11,8 +11,8 @@ use casper_types::{ addressable_entity::{ActionThresholds, AssociatedKeys, MessageTopics, Weight}, system::auction::{BidAddr, BidKind, BidsExt, SeigniorageRecipientsSnapshot, UnbondingPurse}, AccessRights, AddressableEntity, AddressableEntityHash, ByteCodeHash, CLValue, EntityKind, - EntityVersions, EntryPoints, Groups, Key, Package, PackageHash, PackageStatus, ProtocolVersion, - PublicKey, StoredValue, URef, U512, + EntityVersions, Groups, Key, Package, PackageHash, PackageStatus, ProtocolVersion, PublicKey, + StoredValue, URef, U512, }; use super::{config::Transfer, state_reader::StateReader}; @@ -169,7 +169,6 @@ impl<T: StateReader> StateTracker<T> { let addressable_entity = AddressableEntity::new( package_hash, contract_wasm_hash, - EntryPoints::new(), self.protocol_version, main_purse, associated_keys, diff --git a/utils/global-state-update-gen/src/generic/testing.rs b/utils/global-state-update-gen/src/generic/testing.rs index f365e2e76a..0284029305 100644 --- a/utils/global-state-update-gen/src/generic/testing.rs +++ b/utils/global-state-update-gen/src/generic/testing.rs @@ -1,6 +1,6 @@ -use itertools::Itertools; use std::collections::BTreeMap; +use itertools::Itertools; use rand::Rng; use casper_types::{ @@ -12,17 +12,18 @@ use casper_types::{ WithdrawPurse, WithdrawPurses, }, testing::TestRng, - AccessRights, AddressableEntity, ByteCodeHash, CLValue, EntityKind, EntryPoints, EraId, Key, - PackageHash, ProtocolVersion, PublicKey, StoredValue, URef, URefAddr, U512, + AccessRights, AddressableEntity, ByteCodeHash, CLValue, EntityKind, EraId, Key, PackageHash, + ProtocolVersion, PublicKey, StoredValue, URef, URefAddr, U512, }; +#[cfg(test)] +use crate::utils::ValidatorInfo; + use super::{ config::{AccountConfig, Config, DelegatorConfig, Transfer, ValidatorConfig}, get_update, state_reader::StateReader, }; -#[cfg(test)] -use crate::utils::ValidatorInfo; const TOTAL_SUPPLY_KEY: URef = URef::new([1; 32], AccessRights::READ_ADD_WRITE); const SEIGNIORAGE_RECIPIENTS_KEY: URef = URef::new([2; 32], AccessRights::READ_ADD_WRITE); @@ -62,7 +63,6 @@ impl MockStateReader { let entity = AddressableEntity::new( PackageHash::new(rng.gen()), ByteCodeHash::new(rng.gen()), - EntryPoints::new(), self.protocol_version, main_purse, AssociatedKeys::new(account_hash, Weight::new(1)), diff --git a/utils/validation/src/generators.rs b/utils/validation/src/generators.rs index eab2276a6f..73a1d0e7b8 100644 --- a/utils/validation/src/generators.rs +++ b/utils/validation/src/generators.rs @@ -20,9 +20,9 @@ use casper_types::{ }, AccessRights, AddressableEntityHash, BlockTime, ByteCode, ByteCodeHash, ByteCodeKind, CLType, CLTyped, CLValue, DeployHash, DeployInfo, EntityVersionKey, EntityVersions, EntryPoint, - EntryPointAccess, EntryPointType, EntryPoints, EraId, Group, Groups, Key, Package, PackageHash, - PackageStatus, Parameter, ProtocolVersion, PublicKey, SecretKey, StoredValue, TransferAddr, - TransferV1, URef, U512, + EntryPointAccess, EntryPointPayment, EntryPointType, EntryPointValue, EraId, Group, Groups, + Key, Package, PackageHash, PackageStatus, Parameter, ProtocolVersion, PublicKey, SecretKey, + StoredValue, TransactionRuntime, TransferAddr, TransferV1, URef, U512, }; use casper_validation::{ abi::{ABIFixture, ABITestCase}, @@ -352,34 +352,35 @@ pub fn make_abi_test_fixtures() -> Result<TestFixtures, Error> { ABITestCase::from_inputs(vec![StoredValue::ByteCode(byte_code).into()])?, ); - let entry_points = { - let mut entry_points = EntryPoints::new(); - let public_contract_entry_point = EntryPoint::new( - "public_entry_point_func", - vec![ - Parameter::new("param1", U512::cl_type()), - Parameter::new("param2", String::cl_type()), - ], - CLType::Unit, - EntryPointAccess::Public, - EntryPointType::Called, - ); - - entry_points.add_entry_point(public_contract_entry_point); + let public_contract_entry_point = EntryPoint::new( + "public_entry_point_func", + vec![ + Parameter::new("param1", U512::cl_type()), + Parameter::new("param2", String::cl_type()), + ], + CLType::Unit, + EntryPointAccess::Public, + EntryPointType::Called, + EntryPointPayment::Caller, + ); - entry_points - }; + stored_value.insert( + "EntryPoint".to_string(), + ABITestCase::from_inputs(vec![StoredValue::EntryPoint(EntryPointValue::V1CasperVm( + public_contract_entry_point, + )) + .into()])?, + ); let entity = AddressableEntity::new( PackageHash::new([100; 32]), ByteCodeHash::new([101; 32]), - entry_points, ProtocolVersion::V1_0_0, URef::default(), AssociatedKeys::default(), ActionThresholds::default(), MessageTopics::default(), - EntityKind::SmartContract, + EntityKind::SmartContract(TransactionRuntime::VmCasperV1), ); stored_value.insert( "AddressableEntity".to_string(), diff --git a/utils/validation/tests/fixtures/ABI/stored_value.json b/utils/validation/tests/fixtures/ABI/stored_value.json index 55a8470259..a7fde9ca7e 100644 --- a/utils/validation/tests/fixtures/ABI/stored_value.json +++ b/utils/validation/tests/fixtures/ABI/stored_value.json @@ -40,31 +40,12 @@ "value": { "AddressableEntity": { "protocol_version": "1.0.0", - "entity_kind": "SmartContract", + "entity_kind": { + "SmartContract": "VmCasperV1" + }, "package_hash": "package-6464646464646464646464646464646464646464646464646464646464646464", "byte_code_hash": "byte-code-6565656565656565656565656565656565656565656565656565656565656565", "main_purse": "uref-0000000000000000000000000000000000000000000000000000000000000000-000", - "entry_points": [ - { - "name": "public_entry_point_func", - "entry_point": { - "name": "public_entry_point_func", - "args": [ - { - "name": "param1", - "cl_type": "U512" - }, - { - "name": "param2", - "cl_type": "String" - } - ], - "ret": "Unit", - "access": "Public", - "entry_point_type": "Called" - } - } - ], "associated_keys": [], "action_thresholds": { "deployment": 1, @@ -76,7 +57,7 @@ } } ], - "output": "0d6464646464646464646464646464646464646464646464646464646464646464656565656565656565656565656565656565656565656565656565656565656501000000170000007075626c69635f656e7472795f706f696e745f66756e63170000007075626c69635f656e7472795f706f696e745f66756e630200000006000000706172616d310806000000706172616d320a090101010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101010000000002" + "output": "0d6464646464646464646464646464646464646464646464646464646464646464656565656565656565656565656565656565656565656565656565656565656501000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010101000000000200" }, "Bid": { "input": [ @@ -185,6 +166,35 @@ ], "output": "063737373737373737373737373737373737373737373737373737373737373737020000000101010101010101010101010101010101010101010101010101010101010101020202020202020202020202020202020202020202020202020202020202020264646464646464646464646464646464646464646464646464646464646464640a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a070400f90295" }, + "EntryPoint": { + "input": [ + { + "type": "StoredValue", + "value": { + "EntryPoint": { + "V1CasperVm": { + "name": "public_entry_point_func", + "args": [ + { + "name": "param1", + "cl_type": "U512" + }, + { + "name": "param2", + "cl_type": "String" + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Called", + "entry_point_payment": "Caller" + } + } + } + } + ], + "output": "1300170000007075626c69635f656e7472795f706f696e745f66756e630200000006000000706172616d310806000000706172616d320a09010100" + }, "EraInfo": { "input": [ {