Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve on Mapping::contains + Migrate examples to new API #1242

Merged
merged 8 commits into from
May 18, 2022
2 changes: 1 addition & 1 deletion MONTHLY_UPDATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ The [Substrate & Polkadot StackExchange](https://substrate.stackexchange.com/) s
has graduated from its private beta ‒ the site is now in public beta!

This means that the site is now indexed by search engines and can be
browser without any user account.
browsed without any user account.

If you have any questions regarding ink! or smart contracts on Substrate this is
the place to be.
Expand Down
11 changes: 11 additions & 0 deletions crates/engine/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,17 @@ impl Engine {
}
}

/// Returns the size of the value stored in the contract storage at the key if any.
pub fn contains_storage(&mut self, key: &[u8; 32]) -> Option<u32> {
let callee = self.get_callee();
let account_id = AccountId::from_bytes(&callee[..]);

self.debug_info.inc_reads(account_id);
self.database
.get_from_contract_storage(&callee, key)
.map(|val| val.len() as u32)
}

/// Removes the storage entries at the given key.
pub fn clear_storage(&mut self, key: &[u8; 32]) {
let callee = self.get_callee();
Expand Down
6 changes: 2 additions & 4 deletions crates/env/src/engine/off_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,8 @@ impl EnvBackend for EnvInstance {
Ok(Some(decoded))
}

fn contract_storage_contains(&mut self, _key: &Key) -> Option<u32> {
unimplemented!(
"the off-chain env does not implement `seal_contains_storage`, yet"
)
fn contract_storage_contains(&mut self, key: &Key) -> Option<u32> {
self.engine.contains_storage(key.as_ref())
}

fn clear_contract_storage(&mut self, key: &Key) {
Expand Down
13 changes: 12 additions & 1 deletion crates/storage/src/lazy/mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,24 @@ where
///
/// Returns `None` if no `value` exists at the given `key`.
#[inline]
pub fn contains<Q>(&self, key: Q) -> Option<u32>
pub fn size<Q>(&self, key: Q) -> Option<u32>
athei marked this conversation as resolved.
Show resolved Hide resolved
where
Q: scale::EncodeLike<K>,
{
ink_env::contract_storage_contains(&self.storage_key(&key))
}

/// Checks if a value is stored at the given `key` in the contract storage.
///
cmichi marked this conversation as resolved.
Show resolved Hide resolved
/// Returns `None` if no `value` exists at the given `key`.
cmichi marked this conversation as resolved.
Show resolved Hide resolved
#[inline]
pub fn contains<Q>(&self, key: Q) -> bool
where
Q: scale::EncodeLike<K>,
{
ink_env::contract_storage_contains(&self.storage_key(&key)).is_some()
}

/// Clears the value at `key` from storage.
pub fn remove<Q>(&self, key: Q)
where
Expand Down
2 changes: 1 addition & 1 deletion examples/dns/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ mod dns {
#[ink(message)]
pub fn register(&mut self, name: Hash) -> Result<()> {
let caller = self.env().caller();
if self.name_to_owner.get(&name).is_some() {
if self.name_to_owner.contains(&name) {
return Err(Error::NameAlreadyExists)
}

Expand Down
2 changes: 1 addition & 1 deletion examples/erc1155/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ mod erc1155 {

#[ink(message)]
fn is_approved_for_all(&self, owner: AccountId, operator: AccountId) -> bool {
self.approvals.get((&owner, &operator)).is_some()
self.approvals.contains((&owner, &operator))
}
}

Expand Down
10 changes: 5 additions & 5 deletions examples/erc721/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ mod erc721 {
..
} = self;

if token_owner.get(&id).is_none() {
if !token_owner.contains(&id) {
return Err(Error::TokenNotFound)
}

Expand All @@ -305,7 +305,7 @@ mod erc721 {
..
} = self;

if token_owner.get(&id).is_some() {
if token_owner.contains(&id) {
return Err(Error::TokenExists)
}

Expand Down Expand Up @@ -360,7 +360,7 @@ mod erc721 {
return Err(Error::NotAllowed)
};

if self.token_approvals.get(&id).is_some() {
if self.token_approvals.contains(&id) {
return Err(Error::CannotInsert)
} else {
self.token_approvals.insert(&id, to);
Expand All @@ -387,7 +387,7 @@ mod erc721 {

/// Gets an operator on other Account's behalf.
fn approved_for_all(&self, owner: AccountId, operator: AccountId) -> bool {
self.operator_approvals.get((&owner, &operator)).is_some()
self.operator_approvals.contains((&owner, &operator))
}

/// Returns true if the `AccountId` `from` is the owner of token `id`
Expand All @@ -405,7 +405,7 @@ mod erc721 {

/// Returns true if token `id` exists or false if it does not.
fn exists(&self, id: TokenId) -> bool {
self.token_owner.get(&id).is_some()
self.token_owner.contains(&id)
}
}

Expand Down
34 changes: 17 additions & 17 deletions examples/multisig/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ mod multisig {
pub fn revoke_confirmation(&mut self, trans_id: TransactionId) {
self.ensure_caller_is_owner();
let caller = self.env().caller();
if self.confirmations.get(&(trans_id, caller)).is_some() {
if self.confirmations.contains(&(trans_id, caller)) {
self.confirmations.remove(&(trans_id, caller));
let mut confirmation_count = self
.confirmation_count
Expand Down Expand Up @@ -601,7 +601,7 @@ mod multisig {
) -> ConfirmationStatus {
let mut count = self.confirmation_count.get(&transaction).unwrap_or(0);
let key = (transaction, confirmer);
let new_confirmation = self.confirmations.get(&key).is_none();
let new_confirmation = !self.confirmations.contains(&key);
if new_confirmation {
count += 1;
self.confirmations.insert(&key, &());
Expand Down Expand Up @@ -659,7 +659,7 @@ mod multisig {
fn clean_owner_confirmations(&mut self, owner: &AccountId) {
for trans_id in &self.transaction_list.transactions {
let key = (*trans_id, *owner);
if self.confirmations.get(&key).is_some() {
if self.confirmations.contains(&key) {
self.confirmations.remove(&key);
let mut count = self.confirmation_count.get(&trans_id).unwrap_or(0);
count -= 1;
Expand Down Expand Up @@ -696,12 +696,12 @@ mod multisig {

/// Panic if `owner` is not an owner,
fn ensure_owner(&self, owner: &AccountId) {
assert!(self.is_owner.get(owner).is_some());
assert!(self.is_owner.contains(owner));
}

/// Panic if `owner` is an owner.
fn ensure_no_owner(&self, owner: &AccountId) {
assert!(self.is_owner.get(owner).is_none());
assert!(!self.is_owner.contains(owner));
}
}

Expand Down Expand Up @@ -794,12 +794,12 @@ mod multisig {
assert_eq!(contract.owners.len(), 3);
assert_eq!(contract.requirement, 2);
assert!(contract.owners.iter().eq(owners.iter()));
assert!(contract.is_owner.get(&accounts.alice).is_some());
assert!(contract.is_owner.get(&accounts.bob).is_some());
assert!(contract.is_owner.get(&accounts.eve).is_some());
assert!(contract.is_owner.get(&accounts.charlie).is_none());
assert!(contract.is_owner.get(&accounts.django).is_none());
assert!(contract.is_owner.get(&accounts.frank).is_none());
assert!(contract.is_owner.contains(&accounts.alice));
assert!(contract.is_owner.contains(&accounts.bob));
assert!(contract.is_owner.contains(&accounts.eve));
assert!(!contract.is_owner.contains(&accounts.charlie));
assert!(!contract.is_owner.contains(&accounts.django));
assert!(!contract.is_owner.contains(&accounts.frank));
assert_eq!(contract.transaction_list.transactions.len(), 0);
}

Expand Down Expand Up @@ -831,7 +831,7 @@ mod multisig {
let owners = contract.owners.len();
contract.add_owner(accounts.frank);
assert_eq!(contract.owners.len(), owners + 1);
assert!(contract.is_owner.get(&accounts.frank).is_some());
assert!(contract.is_owner.contains(&accounts.frank));
assert_eq!(test::recorded_events().count(), 1);
}

Expand Down Expand Up @@ -861,7 +861,7 @@ mod multisig {
let owners = contract.owners.len();
contract.remove_owner(accounts.alice);
assert_eq!(contract.owners.len(), owners - 1);
assert!(contract.is_owner.get(&accounts.alice).is_none());
assert!(!contract.is_owner.contains(&accounts.alice));
assert_eq!(test::recorded_events().count(), 1);
}

Expand Down Expand Up @@ -891,8 +891,8 @@ mod multisig {
let owners = contract.owners.len();
contract.replace_owner(accounts.alice, accounts.django);
assert_eq!(contract.owners.len(), owners);
assert!(contract.is_owner.get(&accounts.alice).is_none());
assert!(contract.is_owner.get(&accounts.django).is_some());
assert!(!contract.is_owner.contains(&accounts.alice));
assert!(contract.is_owner.contains(&accounts.django));
assert_eq!(test::recorded_events().count(), 2);
}

Expand Down Expand Up @@ -1053,7 +1053,7 @@ mod multisig {
set_caller(accounts.alice);
contract.revoke_confirmation(0);
assert_eq!(test::recorded_events().count(), 3);
assert!(contract.confirmations.get(&(0, accounts.alice)).is_none());
assert!(!contract.confirmations.contains(&(0, accounts.alice)));
assert_eq!(contract.confirmation_count.get(&0).unwrap(), 0);
}

Expand All @@ -1064,7 +1064,7 @@ mod multisig {
set_caller(accounts.bob);
contract.revoke_confirmation(0);
assert_eq!(test::recorded_events().count(), 2);
assert!(contract.confirmations.get(&(0, accounts.alice)).is_some());
assert!(contract.confirmations.contains(&(0, accounts.alice)));
assert_eq!(contract.confirmation_count.get(&0).unwrap(), 1);
}

Expand Down