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

Remove Default implementation for AccountId #1255

Merged
merged 14 commits into from
Feb 1, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions crates/env/src/call/call_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,10 @@ where
E: Environment,
{
/// Returns the account ID of the called contract instance.
///
/// Returns `None` if no account ID has been set for the call.
#[inline]
pub(crate) fn callee(&self) -> &E::AccountId {
pub(crate) fn callee(&self) -> &Option<E::AccountId> {
&self.call_type.callee
}

Expand Down Expand Up @@ -261,7 +263,7 @@ where
/// The default call type for cross-contract calls. Performs a cross-contract call to `callee`
/// with gas limit `gas_limit`, transferring `transferred_value` of currency.
pub struct Call<E: Environment> {
callee: E::AccountId,
callee: Option<E::AccountId>,
ascjones marked this conversation as resolved.
Show resolved Hide resolved
gas_limit: Gas,
transferred_value: E::Balance,
}
Expand Down Expand Up @@ -290,7 +292,7 @@ where
/// Sets the `callee` for the current cross-contract call.
pub fn callee(self, callee: E::AccountId) -> Self {
Call {
callee,
callee: Some(callee),
gas_limit: self.gas_limit,
transferred_value: self.transferred_value,
}
Expand Down Expand Up @@ -448,7 +450,7 @@ where
let call_type = self.call_type.value();
CallBuilder {
call_type: Set(Call {
callee,
callee: Some(callee),
gas_limit: call_type.gas_limit,
transferred_value: call_type.transferred_value,
}),
Expand Down
20 changes: 4 additions & 16 deletions crates/env/src/engine/on_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,20 +179,6 @@ impl EnvInstance {
ScopedBuffer::from(&mut self.buffer[..])
}

/// Returns the contract property value into the given result buffer.
///
/// # Note
///
/// This skips the potentially costly decoding step that is often equivalent to a `memcpy`.
fn get_property_inplace<T>(&mut self, ext_fn: fn(output: &mut &mut [u8])) -> T
where
T: Default + AsMut<[u8]>,
{
let mut result = T::default();
ext_fn(&mut result.as_mut());
result
}

/// Returns the contract property value from its little-endian representation.
///
/// # Note
Expand Down Expand Up @@ -332,7 +318,8 @@ impl EnvBackend for EnvInstance {

impl TypedEnvBackend for EnvInstance {
fn caller<E: Environment>(&mut self) -> E::AccountId {
self.get_property_inplace::<E::AccountId>(ext::caller)
self.get_property::<E::AccountId>(ext::caller)
.expect("The executed contract must have a caller with a valid account id.")
}

fn transferred_value<E: Environment>(&mut self) -> E::Balance {
Expand All @@ -348,7 +335,8 @@ impl TypedEnvBackend for EnvInstance {
}

fn account_id<E: Environment>(&mut self) -> E::AccountId {
self.get_property_inplace::<E::AccountId>(ext::address)
self.get_property::<E::AccountId>(ext::address)
.expect("A contract being executed must have a valid account id.")
}

fn balance<E: Environment>(&mut self) -> E::Balance {
Expand Down
18 changes: 3 additions & 15 deletions crates/env/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,15 @@ pub trait Environment {
/// The value must match the maximum number of supported event topics of the used runtime.
const MAX_EVENT_TOPICS: usize;

/// The address type.
/// The account id type.
type AccountId: 'static
+ scale::Codec
+ Clone
+ PartialEq
+ Eq
+ Ord
+ AsRef<[u8]>
+ AsMut<[u8]>
+ Default;
+ AsMut<[u8]>;

/// The type of balances.
type Balance: 'static
Expand Down Expand Up @@ -202,18 +201,7 @@ pub type BlockNumber = u32;
/// This is a mirror of the `AccountId` type used in the default configuration
/// of PALLET contracts.
#[derive(
Debug,
Copy,
Clone,
PartialEq,
Eq,
Ord,
PartialOrd,
Hash,
Encode,
Decode,
From,
Default,
Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Encode, Decode, From,
)]
#[cfg_attr(feature = "std", derive(TypeInfo))]
pub struct AccountId([u8; 32]);
Expand Down
49 changes: 48 additions & 1 deletion crates/storage/src/traits/impls/prims.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl_layout_for_primitive!(
// We do not include `f32` and `f64` since Wasm contracts currently
// do not support them since they are non deterministic. We might add them
// to this list once we add deterministic support for those primitives.
Key, Hash, AccountId, (),
Key, Hash, (),
String,
bool,
u8, u16, u32, u64, u128,
Expand Down Expand Up @@ -288,6 +288,53 @@ where
}
}

impl SpreadLayout for AccountId
where
Self: PackedLayout,
{
const FOOTPRINT: u64 = 1_u64;
const REQUIRES_DEEP_CLEAN_UP: bool = false;

fn pull_spread(ptr: &mut KeyPtr) -> Self {
crate::traits::impls::forward_pull_packed::<Self>(ptr)
}

fn push_spread(&self, ptr: &mut KeyPtr) {
crate::traits::impls::forward_push_packed::<Self>(self, ptr)
}

fn clear_spread(&self, ptr: &mut KeyPtr) {
crate::traits::impls::forward_clear_packed::<Self>(self, ptr)
}
}

// TODO: Not sure if this can actually be implemented, since we need some sort of "sane" default
HCastano marked this conversation as resolved.
Show resolved Hide resolved
// here
impl SpreadAllocate for AccountId
where
Self: PackedLayout,
{
#[inline]
fn allocate_spread(ptr: &mut KeyPtr) -> Self {
ptr.advance_by(<Self as SpreadLayout>::FOOTPRINT);
[0u8; 32].into()
}
}

impl PackedLayout for AccountId {
#[inline]
fn pull_packed(&mut self, _at: &::ink_primitives::Key) {}
#[inline]
fn push_packed(&self, _at: &::ink_primitives::Key) {}
#[inline]
fn clear_packed(&self, _at: &::ink_primitives::Key) {}
}

impl PackedAllocate for AccountId {
#[inline]
fn allocate_packed(&mut self, _at: &::ink_primitives::Key) {}
}

#[cfg(test)]
mod tests {
use crate::push_pull_works_for_primitive;
Expand Down
11 changes: 9 additions & 2 deletions examples/dns/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ mod dns {
/// to facilitate transfers, voting and DApp-related operations instead
/// of resorting to long IP addresses that are hard to remember.
#[ink(storage)]
#[derive(Default, SpreadAllocate)]
#[derive(SpreadAllocate)]
pub struct DomainNameService {
/// A hashmap to store all name to addresses mapping.
name_to_address: Mapping<Hash, AccountId>,
Expand Down Expand Up @@ -88,7 +88,7 @@ mod dns {
// This call is required in order to correctly initialize the
// `Mapping`s of our contract.
ink_lang::utils::initialize_contract(|contract: &mut Self| {
contract.default_address = Default::default();
contract.default_address = zero_address();
})
}

Expand Down Expand Up @@ -176,6 +176,13 @@ mod dns {
}
}

/// Helper for referencing the zero address (0x00). Note that in practice this address should
/// not be treated in any special way (such as a default placeholder) since it has a known
/// private key.
fn zero_address() -> AccountId {
[0u8; 32].into()
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
11 changes: 9 additions & 2 deletions examples/erc1155/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ mod erc1155 {
ensure!(self.is_approved_for_all(from, caller), Error::NotApproved);
}

ensure!(to != AccountId::default(), Error::ZeroAddressTransfer);
ensure!(to != zero_address(), Error::ZeroAddressTransfer);

let balance = self.balance_of(from, token_id);
ensure!(balance >= value, Error::InsufficientBalance);
Expand All @@ -461,7 +461,7 @@ mod erc1155 {
ensure!(self.is_approved_for_all(from, caller), Error::NotApproved);
}

ensure!(to != AccountId::default(), Error::ZeroAddressTransfer);
ensure!(to != zero_address(), Error::ZeroAddressTransfer);
ensure!(!token_ids.is_empty(), Error::BatchTransferMismatch);
ensure!(
token_ids.len() == values.len(),
Expand Down Expand Up @@ -585,6 +585,13 @@ mod erc1155 {
}
}

/// Helper for referencing the zero address (0x00). Note that in practice this address should
/// not be treated in any special way (such as a default placeholder) since it has a known
/// private key.
fn zero_address() -> AccountId {
[0u8; 32].into()
}

#[cfg(test)]
mod tests {
/// Imports all the definitions from the outer scope so we can use them here.
Expand Down