From 04564ca1df09d8269b04957a99b3f597014a14c6 Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Thu, 7 Mar 2024 19:54:27 +0100 Subject: [PATCH] fixed map mapper get from address issue + tests --- .../storage_mapper_get_at_address.scen.json | 65 ++++++++++++++++++- .../src/storage_mapper_get_at_address.rs | 27 ++++++++ .../basic-features/wasm/src/lib.rs | 7 +- .../base/src/storage/mappers/map_mapper.rs | 8 ++- 4 files changed, 102 insertions(+), 5 deletions(-) diff --git a/contracts/feature-tests/basic-features/scenarios/storage_mapper_get_at_address.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_mapper_get_at_address.scen.json index e2beefa293..6c2feb1d84 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_mapper_get_at_address.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_get_at_address.scen.json @@ -240,6 +240,69 @@ "gas": "*", "refund": "*" } + }, + { + "step": "scCall", + "id": "fill map mapper", + "tx": { + "from": "address:an_account", + "to": "sc:to-be-called", + "function": "fill_map_mapper", + "arguments": [ + "5" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "keys at address", + "tx": { + "from": "address:an_account", + "to": "sc:caller", + "function": "keys_at_address", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0x0000271100002712000027130000271400002715" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "values at address", + "tx": { + "from": "address:an_account", + "to": "sc:caller", + "function": "values_at_address", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0x0000000100000002000000030000000400000005" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } } ] -} +} \ No newline at end of file diff --git a/contracts/feature-tests/basic-features/src/storage_mapper_get_at_address.rs b/contracts/feature-tests/basic-features/src/storage_mapper_get_at_address.rs index 7fc07d48eb..7970619957 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_get_at_address.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_get_at_address.rs @@ -70,15 +70,42 @@ pub trait StorageMapperGetAtAddress { mapper.back().unwrap() } + #[endpoint] + fn keys_at_address(&self) -> ManagedVec { + let address = self.contract_address().get(); + let mapper: MapMapper = + MapMapper::new_from_address(address, StorageKey::from("map_mapper")); + mapper.keys().collect() + } + + #[endpoint] + fn values_at_address(&self) -> ManagedVec { + let address = self.contract_address().get(); + let mapper: MapMapper = + MapMapper::new_from_address(address, StorageKey::from("map_mapper")); + mapper.values().collect() + } + /// Storage to be called. For testing, this contract is deployed twice, /// and this module acts both as caller and receiver #[storage_mapper("set_mapper")] fn set_mapper(&self) -> SetMapper; + #[storage_mapper("map_mapper")] + fn map_mapper(&self) -> MapMapper; + #[endpoint] fn fill_set_mapper(&self, value: u32) { for item in 1u32..=value { self.set_mapper().insert(item); } } + + #[endpoint] + fn fill_map_mapper(&self, value: u32) { + for item in 1u32..=value { + let key = 10_000u32 + item; + self.map_mapper().insert(key, item); + } + } } diff --git a/contracts/feature-tests/basic-features/wasm/src/lib.rs b/contracts/feature-tests/basic-features/wasm/src/lib.rs index e87654cc7e..dba8d815a6 100644 --- a/contracts/feature-tests/basic-features/wasm/src/lib.rs +++ b/contracts/feature-tests/basic-features/wasm/src/lib.rs @@ -5,9 +5,9 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 384 +// Endpoints: 387 // Async Callback: 1 -// Total number of exported functions: 386 +// Total number of exported functions: 389 #![no_std] #![allow(internal_features)] @@ -403,7 +403,10 @@ multiversx_sc_wasm_adapter::endpoints! { previous_at_address => previous_at_address front_at_address => front_at_address back_at_address => back_at_address + keys_at_address => keys_at_address + values_at_address => values_at_address fill_set_mapper => fill_set_mapper + fill_map_mapper => fill_map_mapper ) } diff --git a/framework/base/src/storage/mappers/map_mapper.rs b/framework/base/src/storage/mappers/map_mapper.rs index 8ed38a3c70..af4bbda6ff 100644 --- a/framework/base/src/storage/mappers/map_mapper.rs +++ b/framework/base/src/storage/mappers/map_mapper.rs @@ -11,7 +11,7 @@ use crate::{ multi_encode_iter_or_handle_err, multi_types::MultiValue2, CodecFrom, EncodeErrorHandler, NestedDecode, NestedEncode, TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput, }, - storage::{storage_clear, storage_get, storage_set, StorageKey}, + storage::{storage_clear, storage_set, StorageKey}, types::{ManagedAddress, ManagedType, MultiValueEncoded}, }; @@ -26,6 +26,7 @@ where V: TopEncode + TopDecode + 'static, { _phantom_api: PhantomData, + address: A, base_key: StorageKey, keys_set: SetMapper, _phantom_value: PhantomData, @@ -40,6 +41,7 @@ where fn new(base_key: StorageKey) -> Self { MapMapper { _phantom_api: PhantomData, + address: CurrentStorage, base_key: base_key.clone(), keys_set: SetMapper::new(base_key), _phantom_value: PhantomData, @@ -106,6 +108,7 @@ where pub fn new_from_address(address: ManagedAddress, base_key: StorageKey) -> Self { MapMapper { _phantom_api: PhantomData, + address: address.clone(), base_key: base_key.clone(), keys_set: SetMapper::new_from_address(address, base_key), _phantom_value: PhantomData, @@ -149,7 +152,8 @@ where } fn get_mapped_value(&self, key: &K) -> V { - storage_get(self.build_named_key(MAPPED_VALUE_IDENTIFIER, key).as_ref()) + self.address + .address_storage_get(self.build_named_key(MAPPED_VALUE_IDENTIFIER, key).as_ref()) } /// Gets a reference to the value in the entry.