Skip to content

Commit

Permalink
Merge pull request #1683 from multiversx/storage-mapper-from-addr
Browse files Browse the repository at this point in the history
storage mapper from address
  • Loading branch information
andrei-marinica authored Jun 21, 2024
2 parents f27462e + 7f0c946 commit 323919e
Show file tree
Hide file tree
Showing 27 changed files with 168 additions and 104 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use multiversx_sc::storage::StorageKey;

multiversx_sc::imports!();
multiversx_sc::derive_imports!();

Expand All @@ -17,102 +15,99 @@ pub trait StorageMapperGetAtAddress {
#[endpoint]
fn is_empty_at_address(&self) -> bool {
let address = self.contract_address().get();
let mapper: SetMapper<u32, _> =
SetMapper::new_from_address(address, StorageKey::from("set_mapper"));
mapper.is_empty()
self.set_mapper_from_address(address).is_empty()
}

#[endpoint]
fn contains_at_address(&self, item: u32) -> bool {
let address = self.contract_address().get();
let mapper: SetMapper<u32, _> =
SetMapper::new_from_address(address, StorageKey::from("set_mapper"));
mapper.contains(&item)
self.set_mapper_from_address(address).contains(&item)
}

#[endpoint]
fn len_at_address(&self) -> usize {
let address = self.contract_address().get();
let mapper: SetMapper<u32, _> =
SetMapper::new_from_address(address, StorageKey::from("set_mapper"));
mapper.len()
self.set_mapper_from_address(address).len()
}

#[endpoint]
fn next_at_address(&self, item: u32) -> u32 {
let address = self.contract_address().get();
let mapper: SetMapper<u32, _> =
SetMapper::new_from_address(address, StorageKey::from("set_mapper"));
mapper.next(&item).unwrap()
self.set_mapper_from_address(address).next(&item).unwrap()
}

#[endpoint]
fn previous_at_address(&self, item: u32) -> u32 {
let address = self.contract_address().get();
let mapper: SetMapper<u32, _> =
SetMapper::new_from_address(address, StorageKey::from("set_mapper"));
mapper.previous(&item).unwrap()
self.set_mapper_from_address(address)
.previous(&item)
.unwrap()
}

#[endpoint]
fn front_at_address(&self) -> u32 {
let address = self.contract_address().get();
let mapper: SetMapper<u32, _> =
SetMapper::new_from_address(address, StorageKey::from("set_mapper"));
mapper.front().unwrap()
self.set_mapper_from_address(address).front().unwrap()
}

#[endpoint]
fn back_at_address(&self) -> u32 {
let address = self.contract_address().get();
let mapper: SetMapper<u32, _> =
SetMapper::new_from_address(address, StorageKey::from("set_mapper"));
mapper.back().unwrap()
self.set_mapper_from_address(address).back().unwrap()
}

#[endpoint]
fn keys_at_address(&self) -> ManagedVec<u32> {
let address = self.contract_address().get();
let mapper: MapMapper<u32, u32, _> =
MapMapper::new_from_address(address, StorageKey::from("map_mapper"));
mapper.keys().collect()
self.map_mapper_from_address(address).keys().collect()
}

#[endpoint]
fn values_at_address(&self) -> ManagedVec<u32> {
let address = self.contract_address().get();
let mapper: MapMapper<u32, u32, _> =
MapMapper::new_from_address(address, StorageKey::from("map_mapper"));
mapper.values().collect()
self.map_mapper_from_address(address).values().collect()
}

#[endpoint]
fn contains_unordered_at_address(&self, item: u32) -> bool {
let address = self.contract_address().get();
let mapper: UnorderedSetMapper<u32, _> =
UnorderedSetMapper::new_from_address(address, StorageKey::from("unordered_set_mapper"));
mapper.contains(&item)
self.unordered_set_mapper_from_address(address)
.contains(&item)
}

#[endpoint]
fn get_by_index(&self, index: usize) -> u32 {
let address = self.contract_address().get();
let mapper: UnorderedSetMapper<u32, _> =
UnorderedSetMapper::new_from_address(address, StorageKey::from("unordered_set_mapper"));
mapper.get_by_index(index)
self.unordered_set_mapper_from_address(address)
.get_by_index(index)
}

/// 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<u32>;

#[storage_mapper_from_address("set_mapper")]
fn set_mapper_from_address(&self, address: ManagedAddress) -> SetMapper<u32, ManagedAddress>;

#[storage_mapper("map_mapper")]
fn map_mapper(&self) -> MapMapper<u32, u32>;

#[storage_mapper_from_address("map_mapper")]
fn map_mapper_from_address(
&self,
address: ManagedAddress,
) -> MapMapper<u32, u32, ManagedAddress>;

#[storage_mapper("unordered_set_mapper")]
fn unordered_set_mapper(&self) -> UnorderedSetMapper<u32>;

#[storage_mapper_from_address("unordered_set_mapper")]
fn unordered_set_mapper_from_address(
&self,
address: ManagedAddress,
) -> UnorderedSetMapper<u32, ManagedAddress>;

#[endpoint]
fn fill_set_mapper(&self, value: u32) {
for item in 1u32..=value {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use multiversx_sc::storage::StorageKey;

multiversx_sc::imports!();

/// Storage mapper test.
Expand All @@ -9,6 +7,12 @@ pub trait SingleValueMapperFeatures {
#[storage_mapper("my_single_value_mapper")]
fn map_my_single_value_mapper(&self) -> SingleValueMapper<BigInt>;

#[storage_mapper_from_address("my_single_value_mapper")]
fn map_my_single_value_mapper_from_address(
&self,
address: ManagedAddress,
) -> SingleValueMapper<BigUint, ManagedAddress>;

#[endpoint]
fn my_single_value_mapper_increment_1(&self, amount: BigInt) {
let my_single_value_mapper = self.map_my_single_value_mapper();
Expand Down Expand Up @@ -55,12 +59,8 @@ pub trait SingleValueMapperFeatures {

#[endpoint]
fn is_empty_at_address_single_value_mapper(&self, address: ManagedAddress) -> bool {
let mapper: SingleValueMapper<Self::Api, BigInt, _> = SingleValueMapper::new_from_address(
address,
StorageKey::from("my_single_value_mapper"),
);

mapper.is_empty()
self.map_my_single_value_mapper_from_address(address)
.is_empty()
}

#[endpoint]
Expand Down
12 changes: 5 additions & 7 deletions contracts/feature-tests/basic-features/src/storage_mapper_vec.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use multiversx_sc::storage::StorageKey;

multiversx_sc::imports!();

/// Storage mapper test.
Expand All @@ -9,6 +7,9 @@ pub trait VecMapperFeatures {
#[storage_mapper("vec_mapper")]
fn vec_mapper(&self) -> VecMapper<u32>;

#[storage_mapper_from_address("vec_mapper")]
fn vec_mapper_from_address(&self, address: ManagedAddress) -> VecMapper<u32, ManagedAddress>;

#[endpoint]
fn vec_mapper_push(&self, item: u32) {
let mut vec_mapper = self.vec_mapper();
Expand All @@ -22,8 +23,7 @@ pub trait VecMapperFeatures {

#[view]
fn vec_mapper_get_at_address(&self, address: ManagedAddress, index: usize) -> u32 {
let mapper = VecMapper::new_from_address(address, StorageKey::from("vec_mapper"));
mapper.get(index)
self.vec_mapper_from_address(address).get(index)
}

#[view]
Expand All @@ -33,8 +33,6 @@ pub trait VecMapperFeatures {

#[view]
fn vec_mapper_len_at_address(&self, address: ManagedAddress) -> usize {
let mapper: VecMapper<Self::Api, u32, _> =
VecMapper::new_from_address(address, StorageKey::from("vec_mapper"));
mapper.len()
self.vec_mapper_from_address(address).len()
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use multiversx_sc::storage::StorageKey;

multiversx_sc::imports!();

#[multiversx_sc::module]
Expand All @@ -21,9 +19,7 @@ pub trait StorageMapperWhitelistFeatures {

#[endpoint]
fn check_contains_at_address(&self, address: ManagedAddress, item: ManagedBuffer) -> bool {
let mapper =
WhitelistMapper::new_from_address(address, StorageKey::from("whitelistMapper"));
mapper.contains(&item)
self.whitelist_mapper_from_address(address).contains(&item)
}

#[endpoint]
Expand All @@ -33,11 +29,16 @@ pub trait StorageMapperWhitelistFeatures {

#[endpoint]
fn require_contains_at_address(&self, address: ManagedAddress, item: ManagedBuffer) {
let mapper =
WhitelistMapper::new_from_address(address, StorageKey::from("whitelistMapper"));
mapper.require_whitelisted(&item)
self.whitelist_mapper_from_address(address)
.require_whitelisted(&item)
}

#[storage_mapper("whitelistMapper")]
fn whitelist_mapper(&self) -> WhitelistMapper<ManagedBuffer>;

#[storage_mapper_from_address("whitelistMapper")]
fn whitelist_mapper_from_address(
&self,
address: ManagedAddress,
) -> WhitelistMapper<ManagedBuffer, ManagedAddress>;
}
2 changes: 1 addition & 1 deletion framework/base/src/storage/mappers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub use bi_di_mapper::BiDiMapper;
pub use linked_list_mapper::{LinkedListMapper, LinkedListNode};
pub use map_mapper::MapMapper;
pub use map_storage_mapper::MapStorageMapper;
pub use mapper::{StorageClearable, StorageMapper};
pub use mapper::{StorageClearable, StorageMapper, StorageMapperFromAddress};
pub use ordered_binary_tree_mapper::{
NodeId, OrderedBinaryTreeMapper, OrderedBinaryTreeNode, NULL_NODE_ID,
};
Expand Down
6 changes: 3 additions & 3 deletions framework/base/src/storage/mappers/address_to_id_mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::marker::PhantomData;

use super::{
set_mapper::{CurrentStorage, StorageAddress},
StorageMapper,
StorageMapper, StorageMapperFromAddress,
};
use crate::{
api::{ErrorApiImpl, StorageMapperApi},
Expand Down Expand Up @@ -42,11 +42,11 @@ where
}
}

impl<SA> AddressToIdMapper<SA, ManagedAddress<SA>>
impl<SA> StorageMapperFromAddress<SA> for AddressToIdMapper<SA, ManagedAddress<SA>>
where
SA: StorageMapperApi,
{
pub fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
AddressToIdMapper {
_phantom_api: PhantomData,
address,
Expand Down
6 changes: 3 additions & 3 deletions framework/base/src/storage/mappers/bi_di_mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{

use super::{
set_mapper::{CurrentStorage, StorageAddress},
unordered_set_mapper, StorageMapper, UnorderedSetMapper,
unordered_set_mapper, StorageMapper, StorageMapperFromAddress, UnorderedSetMapper,
};
use crate::{
abi::{TypeAbi, TypeDescriptionContainer, TypeName},
Expand Down Expand Up @@ -66,13 +66,13 @@ where
}
}

impl<SA, K, V> BiDiMapper<SA, K, V, ManagedAddress<SA>>
impl<SA, K, V> StorageMapperFromAddress<SA> for BiDiMapper<SA, K, V, ManagedAddress<SA>>
where
SA: StorageMapperApi,
K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
{
pub fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
let mut id_key = base_key.clone();
id_key.append_bytes(ID_SUFIX);

Expand Down
6 changes: 3 additions & 3 deletions framework/base/src/storage/mappers/linked_list_mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::marker::PhantomData;

use super::{
set_mapper::{CurrentStorage, StorageAddress},
StorageClearable, StorageMapper,
StorageClearable, StorageMapper, StorageMapperFromAddress,
};
use crate::{
abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName},
Expand Down Expand Up @@ -118,12 +118,12 @@ where
}
}

impl<SA, T> LinkedListMapper<SA, T, ManagedAddress<SA>>
impl<SA, T> StorageMapperFromAddress<SA> for LinkedListMapper<SA, T, ManagedAddress<SA>>
where
SA: StorageMapperApi,
T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone,
{
pub fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
LinkedListMapper {
_phantom_api: PhantomData,
address,
Expand Down
6 changes: 3 additions & 3 deletions framework/base/src/storage/mappers/map_mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::marker::PhantomData;

use super::{
set_mapper::{self, CurrentStorage, StorageAddress},
SetMapper, StorageClearable, StorageMapper,
SetMapper, StorageClearable, StorageMapper, StorageMapperFromAddress,
};
use crate::{
abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName},
Expand Down Expand Up @@ -99,13 +99,13 @@ where
}
}

impl<SA, K, V> MapMapper<SA, K, V, ManagedAddress<SA>>
impl<SA, K, V> StorageMapperFromAddress<SA> for MapMapper<SA, K, V, ManagedAddress<SA>>
where
SA: StorageMapperApi,
K: TopEncode + TopDecode + NestedEncode + NestedDecode,
V: TopEncode + TopDecode,
{
pub fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
MapMapper {
_phantom_api: PhantomData,
address: address.clone(),
Expand Down
6 changes: 3 additions & 3 deletions framework/base/src/storage/mappers/map_storage_mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::marker::PhantomData;

use super::{
set_mapper::{self, CurrentStorage, StorageAddress},
SetMapper, StorageClearable, StorageMapper,
SetMapper, StorageClearable, StorageMapper, StorageMapperFromAddress,
};
use crate::{
api::StorageMapperApi,
Expand Down Expand Up @@ -87,13 +87,13 @@ where
}
}

impl<SA, K, V> MapStorageMapper<SA, K, V, ManagedAddress<SA>>
impl<SA, K, V> StorageMapperFromAddress<SA> for MapStorageMapper<SA, K, V, ManagedAddress<SA>>
where
SA: StorageMapperApi,
K: TopEncode + TopDecode + NestedEncode + NestedDecode,
V: StorageMapper<SA> + StorageClearable,
{
pub fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
MapStorageMapper {
_phantom_api: PhantomData,
base_key: base_key.clone(),
Expand Down
11 changes: 10 additions & 1 deletion framework/base/src/storage/mappers/mapper.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{api::StorageMapperApi, storage::StorageKey};
use crate::{api::StorageMapperApi, storage::StorageKey, types::ManagedAddress};

pub trait StorageMapper<SA>: 'static
where
Expand All @@ -8,6 +8,15 @@ where
fn new(base_key: StorageKey<SA>) -> Self;
}

pub trait StorageMapperFromAddress<SA>: 'static
where
SA: StorageMapperApi,
{
/// Will be called automatically by the `#[storage_mapper_from_address]`
/// annotation generated code.
fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self;
}

pub trait StorageClearable {
/// Clears all the entries owned by the storage.
fn clear(&mut self);
Expand Down
Loading

0 comments on commit 323919e

Please sign in to comment.