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 all 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]
- Rename `_checked` codegen call methods with `try_` ‒ [#1621](/~https://github.com/paritytech/ink/pull/1621)
- Remove `Default` implementation for AccountId ‒ [#1255](/~https://github.com/paritytech/ink/pull/1255)

### Breaking Changes

1. We've renamed some of the generated message methods on the `ContractRef` struct. They
have been changed from `_checked` to `try_` ([#1621](/~https://github.com/paritytech/ink/pull/1621))
1. We have removed the `Default` implementation for `AccountId`s. This is because of
security concerns around the use of the zero address which has a known private key in
the `sr25519` and `ed25519` curves ([#1255](/~https://github.com/paritytech/ink/pull/1255)).

## Version 4.0.0-beta.1
The coolest feature included in this release is the first first published version of
Expand Down
98 changes: 42 additions & 56 deletions crates/env/src/call/call_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ use crate::{
Error,
};
use core::marker::PhantomData;
use ink_primitives::Clear;
use num_traits::Zero;

/// The final parameters to the cross-contract call.
Expand Down Expand Up @@ -203,11 +202,9 @@ where
/// # type AccountId = <DefaultEnvironment as Environment>::AccountId;
/// # type Balance = <DefaultEnvironment as Environment>::Balance;
/// build_call::<DefaultEnvironment>()
/// .call_type(
/// Call::new()
/// .callee(AccountId::from([0x42; 32]))
/// .gas_limit(5000)
/// .transferred_value(10))
/// .call(AccountId::from([0x42; 32]))
/// .gas_limit(5000)
/// .transferred_value(10)
/// .exec_input(
/// ExecutionInput::new(Selector::new([0xDE, 0xAD, 0xBE, 0xEF]))
/// .push_arg(42u8)
Expand Down Expand Up @@ -239,9 +236,8 @@ where
/// # };
/// # type AccountId = <DefaultEnvironment as Environment>::AccountId;
/// let my_return_value: i32 = build_call::<DefaultEnvironment>()
/// .call_type(Call::new()
/// .callee(AccountId::from([0x42; 32]))
/// .gas_limit(5000))
/// .call_type(Call::new(AccountId::from([0x42; 32])))
/// .gas_limit(5000)
/// .transferred_value(10)
/// .exec_input(
/// ExecutionInput::new(Selector::new([0xDE, 0xAD, 0xBE, 0xEF]))
Expand All @@ -268,8 +264,7 @@ where
/// # use ink_primitives::Clear;
/// # type AccountId = <DefaultEnvironment as Environment>::AccountId;
/// let my_return_value: i32 = build_call::<DefaultEnvironment>()
/// .call_type(DelegateCall::new()
/// .code_hash(<DefaultEnvironment as Environment>::Hash::CLEAR_HASH))
/// .delegate(<DefaultEnvironment as Environment>::Hash::CLEAR_HASH)
/// .exec_input(
/// ExecutionInput::new(Selector::new([0xDE, 0xAD, 0xBE, 0xEF]))
/// .push_arg(42u8)
Expand Down Expand Up @@ -304,12 +299,9 @@ where
/// # type AccountId = <DefaultEnvironment as Environment>::AccountId;
/// # type Balance = <DefaultEnvironment as Environment>::Balance;
/// let call_result = build_call::<DefaultEnvironment>()
/// .call_type(
/// Call::new()
/// .callee(AccountId::from([0x42; 32]))
/// .gas_limit(5000)
/// .transferred_value(10),
/// )
/// .call(AccountId::from([0x42; 32]))
/// .gas_limit(5000)
/// .transferred_value(10)
/// .try_invoke()
/// .expect("Got an error from the Contract's pallet.");
///
Expand Down Expand Up @@ -346,36 +338,21 @@ pub struct Call<E: Environment> {
transferred_value: E::Balance,
}

impl<E: Environment> Default for Call<E> {
fn default() -> Self {
Call {
callee: Default::default(),
impl<E: Environment> Call<E> {
/// Returns a clean builder for [`Call`].
pub fn new(callee: E::AccountId) -> Self {
Self {
callee,
gas_limit: Default::default(),
transferred_value: E::Balance::zero(),
}
}
}

impl<E: Environment> Call<E> {
/// Returns a clean builder for [`Call`].
pub fn new() -> Self {
Default::default()
}
}

impl<E> Call<E>
where
E: Environment,
{
/// Sets the `callee` for the current cross-contract call.
pub fn callee(self, callee: E::AccountId) -> Self {
Call {
callee,
gas_limit: self.gas_limit,
transferred_value: self.transferred_value,
}
}

/// Sets the `gas_limit` for the current cross-contract call.
pub fn gas_limit(self, gas_limit: Gas) -> Self {
Call {
Expand All @@ -402,16 +379,8 @@ pub struct DelegateCall<E: Environment> {

impl<E: Environment> DelegateCall<E> {
/// Returns a clean builder for [`DelegateCall`]
pub const fn new() -> Self {
DelegateCall {
code_hash: E::Hash::CLEAR_HASH,
}
}
}

impl<E: Environment> Default for DelegateCall<E> {
fn default() -> Self {
Self::new()
pub const fn new(code_hash: E::Hash) -> Self {
DelegateCall { code_hash }
}
}

Expand Down Expand Up @@ -519,26 +488,43 @@ where
}
}

impl<E, Args, RetType> CallBuilder<E, Set<Call<E>>, Args, RetType>
impl<E, CallType, Args, RetType> CallBuilder<E, Unset<CallType>, Args, RetType>
where
E: Environment,
{
/// Sets the `callee` for the current cross-contract call.
pub fn callee(self, callee: E::AccountId) -> Self {
let call_type = self.call_type.value();
/// Prepares the `CallBuilder` for a cross-contract [`Call`].
pub fn call(
self,
callee: E::AccountId,
) -> CallBuilder<E, Set<Call<E>>, Args, RetType> {
CallBuilder {
call_type: Set(Call {
callee,
gas_limit: call_type.gas_limit,
transferred_value: call_type.transferred_value,
}),
call_type: Set(Call::new(callee)),
call_flags: self.call_flags,
exec_input: self.exec_input,
return_type: self.return_type,
_phantom: Default::default(),
}
}

/// Prepares the `CallBuilder` for a cross-contract [`DelegateCall`].
pub fn delegate(
self,
code_hash: E::Hash,
) -> CallBuilder<E, Set<DelegateCall<E>>, Args, RetType> {
CallBuilder {
call_type: Set(DelegateCall::new(code_hash)),
call_flags: self.call_flags,
exec_input: self.exec_input,
return_type: self.return_type,
_phantom: Default::default(),
}
}
}

impl<E, Args, RetType> CallBuilder<E, Set<Call<E>>, Args, RetType>
where
E: Environment,
{
/// Sets the `gas_limit` for the current cross-contract call.
pub fn gas_limit(self, gas_limit: Gas) -> Self {
let call_type = self.call_type.value();
Expand Down
21 changes: 4 additions & 17 deletions crates/env/src/engine/on_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,21 +182,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`.
#[inline(always)]
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 @@ -372,7 +357,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 @@ -388,7 +374,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
5 changes: 2 additions & 3 deletions crates/env/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,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
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ impl CallBuilder<'_> {
#( , #input_bindings : #input_types )*
) -> #output_type {
::ink::env::call::build_call::<Environment>()
.call_type(::ink::env::call::Call::new().callee(::ink::ToAccountId::to_account_id(self)))
.call(::ink::ToAccountId::to_account_id(self))
.exec_input(
::ink::env::call::ExecutionInput::new(
::ink::env::call::Selector::new([ #( #selector_bytes ),* ])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ impl CallBuilder<'_> {
#( , #input_bindings : #input_types )*
) -> Self::#output_ident {
::ink::env::call::build_call::<Self::Env>()
.call_type(::ink::env::call::Call::new().callee(::ink::ToAccountId::to_account_id(self)))
.call(::ink::ToAccountId::to_account_id(self))
.exec_input(
::ink::env::call::ExecutionInput::new(
::ink::env::call::Selector::new([ #( #selector_bytes ),* ])
Expand Down
6 changes: 2 additions & 4 deletions crates/ink/src/env_access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -524,8 +524,7 @@ where
/// pub fn invoke_contract(&self) -> i32 {
/// let call_params = build_call::<DefaultEnvironment>()
/// .call_type(
/// Call::new()
/// .callee(AccountId::from([0x42; 32]))
/// Call::new(AccountId::from([0x42; 32]))
/// .gas_limit(5000)
/// .transferred_value(10))
/// .exec_input(
Expand Down Expand Up @@ -588,8 +587,7 @@ where
/// pub fn invoke_contract_delegate(&self) -> i32 {
/// let call_params = build_call::<DefaultEnvironment>()
/// .call_type(
/// DelegateCall::new()
/// .code_hash(<DefaultEnvironment as ink::env::Environment>::Hash::CLEAR_HASH))
/// DelegateCall::new(<DefaultEnvironment as ink::env::Environment>::Hash::CLEAR_HASH))
/// .exec_input(
/// ExecutionInput::new(Selector::new([0xCA, 0xFE, 0xBA, 0xBE]))
/// .push_arg(42u8)
Expand Down
13 changes: 1 addition & 12 deletions crates/primitives/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,7 @@ use scale_info::TypeInfo;
/// 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
23 changes: 22 additions & 1 deletion examples/dns/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ 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)]
pub struct DomainNameService {
/// A hashmap to store all name to addresses mapping.
name_to_address: Mapping<Hash, AccountId>,
Expand All @@ -63,6 +62,21 @@ mod dns {
default_address: AccountId,
}

impl Default for DomainNameService {
fn default() -> Self {
let mut name_to_address = Mapping::new();
name_to_address.insert(Hash::default(), &zero_address());
let mut name_to_owner = Mapping::new();
name_to_owner.insert(Hash::default(), &zero_address());

Self {
name_to_address,
name_to_owner,
default_address: zero_address(),
}
}
}

/// Errors that can occur upon calling this contract.
#[derive(Debug, PartialEq, Eq, scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(::scale_info::TypeInfo))]
Expand Down Expand Up @@ -165,6 +179,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
Loading